From a14544260c33dcdb057d2f62c4aab33cb09ebcb1 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Fri, 15 Nov 2019 21:49:04 +0700 Subject: [PATCH] MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col row_log_table_get_pk_col(): read instant field value from instant alter table when it's required. --- .../suite/innodb/r/instant_alter_debug.result | 18 +++++++++++++ .../suite/innodb/t/instant_alter_debug.test | 26 +++++++++++++++++++ storage/innobase/row/row0log.cc | 4 +++ 3 files changed, 48 insertions(+) diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result index 62df17e066f..49365b6e9be 100644 --- a/mysql-test/suite/innodb/r/instant_alter_debug.result +++ b/mysql-test/suite/innodb/r/instant_alter_debug.result @@ -264,3 +264,21 @@ a b vb 5 NULL NULL DROP TABLE t1; SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; +# +# MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col +# +CREATE TABLE t1 (a TEXT) ENGINE = InnoDB ROW_FORMAT=REDUNDANT; +INSERT INTO t1 (a) VALUES ('foo'); +ALTER TABLE t1 ADD COLUMN b INT DEFAULT 0,algorithm=instant; +connect con2,localhost,root,,test; +SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL onlinealter WAIT_FOR update'; +ALTER TABLE t1 ADD PRIMARY KEY (b); +connection default; +SET DEBUG_SYNC='now WAIT_FOR onlinealter'; +UPDATE t1 SET b = 1; +SET DEBUG_SYNC='now SIGNAL update'; +connection con2; +connection default; +SET DEBUG_SYNC='RESET'; +disconnect con2; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test index 5b8624a3186..cec7a05725b 100644 --- a/mysql-test/suite/innodb/t/instant_alter_debug.test +++ b/mysql-test/suite/innodb/t/instant_alter_debug.test @@ -293,3 +293,29 @@ SELECT * FROM t1; DROP TABLE t1; SET GLOBAL innodb_purge_rseg_truncate_frequency = @save_frequency; + +--echo # +--echo # MDEV-21045 AddressSanitizer: use-after-poison in mem_heap_dup / row_log_table_get_pk_col +--echo # +CREATE TABLE t1 (a TEXT) ENGINE = InnoDB ROW_FORMAT=REDUNDANT; +INSERT INTO t1 (a) VALUES ('foo'); + +ALTER TABLE t1 ADD COLUMN b INT DEFAULT 0,algorithm=instant; + +--connect (con2,localhost,root,,test) +SET DEBUG_SYNC='innodb_inplace_alter_table_enter SIGNAL onlinealter WAIT_FOR update'; +--send +ALTER TABLE t1 ADD PRIMARY KEY (b); + +--connection default +SET DEBUG_SYNC='now WAIT_FOR onlinealter'; +UPDATE t1 SET b = 1; +SET DEBUG_SYNC='now SIGNAL update'; + +--connection con2 +--reap + +--connection default +SET DEBUG_SYNC='RESET'; +--disconnect con2 +DROP TABLE t1; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 9b09b61e119..e2f6450e38d 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1164,6 +1164,10 @@ row_log_table_get_pk_col( field = rec_get_nth_field(rec, offsets, i, &len); + if (len == UNIV_SQL_DEFAULT) { + field = log->instant_field_value(i, &len); + } + if (len == UNIV_SQL_NULL) { if (!log->allow_not_null) { return(DB_INVALID_NULL);