From 160d97a4aaacbefb7f91a7e30a79b4d7937468a8 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 5 Aug 2021 23:48:02 +0300 Subject: MDEV-18734 ASAN heap-use-after-free upon sorting by blob column from partitioned table ha_partition stores records in array of m_ordered_rec_buffer and uses it for prio queue in ordered index scan. When the records are restored from the array the blob buffers may be already freed or rewritten. The solution is to take temporary ownership of cached blob buffers via String::swap(). When the record is restored from m_ordered_rec_buffer the ownership is returned to table fields. Cleanups: init_record_priority_queue(): removed needless !m_ordered_rec_buffer check as there is same assertion few lines before. dbug_print_row() for arbitrary row pointer --- mysql-test/suite/vcol/t/partition.test | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'mysql-test/suite/vcol/t') diff --git a/mysql-test/suite/vcol/t/partition.test b/mysql-test/suite/vcol/t/partition.test index 889724fb1c5..408990b20a6 100644 --- a/mysql-test/suite/vcol/t/partition.test +++ b/mysql-test/suite/vcol/t/partition.test @@ -30,3 +30,51 @@ subpartition by hash(v) subpartitions 3 ( insert t1 set i= 0; set statement sql_mode= '' for update t1 set i= 1, v= 2; drop table t1; + +--echo # +--echo # MDEV-18734 ASAN heap-use-after-free in my_strnxfrm_simple_internal upon update on versioned partitioned table +--echo # +--echo # Cover queue_fix() in ha_partition::handle_ordered_index_scan() +create or replace table t1 ( + x int auto_increment primary key, + b text, v mediumtext as (b) virtual, + index (v(10)) +) partition by range columns (x) ( + partition p1 values less than (3), + partition p2 values less than (6), + partition p3 values less than (9), + partition p4 values less than (12), + partition p5 values less than (15), + partition p6 values less than (17), + partition p7 values less than (19), + partition p8 values less than (21), + partition p9 values less than (23), + partition p10 values less than (25), + partition p11 values less than (27), + partition p12 values less than (29), + partition p13 values less than (31), + partition p14 values less than (33), + partition p15 values less than (35), + partition pn values less than (maxvalue)); +insert into t1 (b) values +(repeat('q', 8192)), (repeat('z', 8192)), (repeat('a', 8192)), (repeat('b', 8192)), +(repeat('x', 8192)), (repeat('y', 8192)); + +insert t1 (b) select b from t1; +insert t1 (b) select b from t1; +insert t1 (b) select b from t1; +insert t1 (b) select b from t1; + +select x, left(b, 10), left(v, 10) from t1 where x > 30 and x < 60 order by v; +update t1 set b= 'bar' where v > 'a' limit 20; + +drop table t1; + +--echo # Cover return_top_record() in ha_partition::handle_ordered_index_scan() +create table t1 (x int primary key, b tinytext, v text as (b) virtual) +partition by range columns (x) ( + partition p1 values less than (4), + partition pn values less than (maxvalue)); +insert into t1 (x, b) values (1, ''), (2, ''), (3, 'a'), (4, 'b'); +update t1 set b= 'bar' where x > 0 order by v limit 2; +drop table t1; -- cgit v1.2.1