summaryrefslogtreecommitdiff
path: root/storage/maria
diff options
context:
space:
mode:
authorVlad Lesin <vlad_lesin@mail.ru>2019-05-24 13:09:13 +0300
committerVlad Lesin <vlad_lesin@mail.ru>2019-05-31 10:03:17 +0300
commitc9b49a4be723c18a8fad2bf4fd549079d45a33a5 (patch)
treed15770dc77c976ff77e2cd6209b8aee84872b9e7 /storage/maria
parent9d142a895c4ac9e34f839222df70b967dfb840e3 (diff)
downloadmariadb-git-c9b49a4be723c18a8fad2bf4fd549079d45a33a5.tar.gz
MDEV-18207: ASAN heap-use-after-free in _ma_get_status upon concurrent operations with sequence
The issue is that two MARIA_HA instances shares the same MARIA_STATUS_INFO object during UNION execution, so the second MARIA_HA instance state pointer MARIA_HA::state points to the MARIA_HA::state_save of the first MARIA instance. This happens in thr_multi_lock(...) { ... for (first_lock=data, pos= data+1 ; pos < end ; pos++) { ... if (pos[0]->lock == pos[-1]->lock && pos[0]->lock->copy_status) (pos[0]->lock->copy_status)((*pos)->status_param, (*first_lock)->status_param); ... } ... } Usually the state is restored from ha_maria::external_lock(...): \#0 _ma_update_status (param=0x6290000e6270) at ./storage/maria/ma_state.c:309 \#1 0x00005555577ccb15 in _ma_update_status_with_lock (info=0x6290000e6270) at ./storage/maria/ma_state.c:361 \#2 0x00005555577c7dcc in maria_lock_database (info=0x6290000e6270, lock_type=2) at ./storage/maria/ma_locking.c:66 \#3 0x0000555557802ccd in ha_maria::external_lock (this=0x61d0001b1308, thd=0x62a000048270, lock_type=2) at ./storage/maria/ha_maria.cc:2727 But _ma_update_status() does not take into account the case when MARIA_HA::status points to the MARIA_HA::state_save of the other MARIA_HA instance. The fix is to restore MARIA_HA::state in ha_maria::external_lock() after maria_lock_database() call for transactional tables.
Diffstat (limited to 'storage/maria')
-rw-r--r--storage/maria/ha_maria.cc7
1 files changed, 5 insertions, 2 deletions
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 5a371a07fc3..f64ea4b1edb 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2798,9 +2798,12 @@ int ha_maria::external_lock(THD *thd, int lock_type)
}
}
} /* if transactional table */
- DBUG_RETURN(maria_lock_database(file, !table->s->tmp_table ?
+ int result = maria_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ?
- F_UNLCK : F_EXTRA_LCK)));
+ F_UNLCK : F_EXTRA_LCK));
+ if (!file->s->base.born_transactional)
+ file->state= &file->s->state.state; // Restore state if clone
+ DBUG_RETURN(result);
}
int ha_maria::start_stmt(THD *thd, thr_lock_type lock_type)