diff options
author | Sergey Vojtovich <svoj@mariadb.org> | 2018-10-18 22:48:28 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2018-10-19 19:09:48 +0400 |
commit | 4ac85d6fd7c43fd0c45c98c0b55810591bd7594b (patch) | |
tree | 1bd4b56f47426df7f63e9882cd9cf2de87d96c2c /sql/ha_partition.cc | |
parent | 8e716138cef2d9be603cdf71701d82bcb72dfd69 (diff) | |
download | mariadb-git-4ac85d6fd7c43fd0c45c98c0b55810591bd7594b.tar.gz |
MDEV-14815 - Server crash or AddressSanitizer errors or valgrind warnings
in thr_lock / has_old_lock upon FLUSH TABLES
Explicit partition access of partitioned MEMORY table under LOCK TABLES
may cause subsequent statements to crash the server, deadlock, trigger
valgrind warnings or ASAN errors. Freed memory was being used due to
incorrect cleanup.
At least MyISAM and InnoDB don't seem to be affected, since their
THR_LOCK structures don't survive FLUSH TABLES. MEMORY keeps table shared
data (including THR_LOCK) even if there're no open instances.
There's partition_info::lock_partitions bitmap, which holds bits of
partitions allowed to be accessed after pruning. This bitmap is
updated for each individual statement.
This bitmap was abused in ha_partition::store_lock() such that when we
need to unlock a table, locked by LOCK TABLES, only locks for partitions
that were accessed by previous statement were released.
Eventually FLUSH TABLES frees THR_LOCK_DATA objects, which are still
linked into THR_LOCK lists. When such THR_LOCK gets reused we end up with
freed memory access.
Fixed by using ha_partition::m_locked_partitions bitmap similarly to
ha_partition::external_lock().
Diffstat (limited to 'sql/ha_partition.cc')
-rw-r--r-- | sql/ha_partition.cc | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 0488ebfb60f..02de92aa17f 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -3907,9 +3907,14 @@ THR_LOCK_DATA **ha_partition::store_lock(THD *thd, } else { - for (i= bitmap_get_first_set(&(m_part_info->lock_partitions)); + MY_BITMAP *used_partitions= lock_type == TL_UNLOCK || + lock_type == TL_IGNORE ? + &m_locked_partitions : + &m_part_info->lock_partitions; + + for (i= bitmap_get_first_set(used_partitions); i < m_tot_parts; - i= bitmap_get_next_set(&m_part_info->lock_partitions, i)) + i= bitmap_get_next_set(used_partitions, i)) { DBUG_PRINT("info", ("store lock %d iteration", i)); to= m_file[i]->store_lock(thd, to, lock_type); |