summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-07-31 11:38:23 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-07-31 11:54:35 +0300
commitf35d1721039f8f115fc55e8f4b4d2bb4012161d1 (patch)
treefb8932f642c981958ae7e6140ae0dae2b95c9ec4 /storage
parentfd0abc890f99e2b5ca1b8ae4cb0dc3968eef1208 (diff)
downloadmariadb-git-f35d1721039f8f115fc55e8f4b4d2bb4012161d1.tar.gz
MDEV-23198 Crash in REPLACE
row_vers_impl_x_locked_low(): clust_offsets may point to memory that is allocated by mem_heap_alloc() and may have been freed. For initializing clust_offsets, try to use the stack-allocated buffer instead of a pointer that may point to freed memory. This fixes a regression that was introduced in commit f0aa073f2bf3d8d85b3d028df89cdb4cdfc4002d (MDEV-20950).
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/row/row0vers.cc8
1 files changed, 4 insertions, 4 deletions
diff --git a/storage/innobase/row/row0vers.cc b/storage/innobase/row/row0vers.cc
index 09509444ea4..77bbb1b3459 100644
--- a/storage/innobase/row/row0vers.cc
+++ b/storage/innobase/row/row0vers.cc
@@ -91,7 +91,7 @@ row_vers_impl_x_locked_low(
{
rec_t* prev_version = NULL;
rec_offs clust_offsets_[REC_OFFS_NORMAL_SIZE];
- rec_offs* clust_offsets = clust_offsets_;
+ rec_offs* clust_offsets;
mem_heap_t* heap;
dtuple_t* ientry = NULL;
mem_heap_t* v_heap = NULL;
@@ -105,7 +105,7 @@ row_vers_impl_x_locked_low(
heap = mem_heap_create(1024);
- clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets,
+ clust_offsets = rec_get_offsets(clust_rec, clust_index, clust_offsets_,
true, ULINT_UNDEFINED, &heap);
const trx_id_t trx_id = row_get_rec_trx_id(
@@ -187,7 +187,7 @@ row_vers_impl_x_locked_low(
ut_ad(committed || prev_version
|| !rec_get_deleted_flag(version, comp));
- /* Free version. */
+ /* Free version and clust_offsets. */
mem_heap_free(old_heap);
if (committed) {
@@ -222,7 +222,7 @@ not_locked:
}
clust_offsets = rec_get_offsets(
- prev_version, clust_index, clust_offsets, true,
+ prev_version, clust_index, clust_offsets_, true,
ULINT_UNDEFINED, &heap);
vers_del = rec_get_deleted_flag(prev_version, comp);