Skip to content

Commit

Permalink
MDEV-18546 ASAN heap-use-after-free in innobase_get_computed_value / …
Browse files Browse the repository at this point in the history
…row_purge

the bug was already fixed in MDEV-17005, so now only test is added
  • Loading branch information
FooBarrior committed Oct 11, 2019
1 parent b393e2c commit 350e46a
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 0 deletions.
45 changes: 45 additions & 0 deletions mysql-test/suite/gcol/r/innodb_virtual_debug_purge.result
Expand Up @@ -233,3 +233,48 @@ set global debug_dbug= @saved_dbug;
drop table t1;
set debug_sync=reset;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;
#
# MDEV-18546 ASAN heap-use-after-free
# in innobase_get_computed_value / row_purge
#
CREATE TABLE t1 (
pk INT AUTO_INCREMENT,
b BIT(15),
v BIT(15) AS (b) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(v)
) ENGINE=InnoDB;
INSERT IGNORE INTO t1 (b) VALUES
(NULL),(b'011'),(b'000110100'),
(b'01101101010'),(b'01111001001011'),(NULL);
SET GLOBAL innodb_debug_sync = "ib_clust_v_col_before_row_allocated "
"SIGNAL before_row_allocated "
"WAIT_FOR flush_unlock";
SET GLOBAL innodb_debug_sync = "ib_open_after_dict_open "
"SIGNAL purge_open "
"WAIT_FOR select_open";
set @saved_dbug= @@global.debug_dbug;
set global debug_dbug= "+d,ib_purge_virtual_index_callback";
connect purge_waiter,localhost,root;
SET debug_sync= "now WAIT_FOR before_row_allocated";
connection default;
REPLACE INTO t1 (pk, b) SELECT pk, b FROM t1;
connection purge_waiter;
connection default;
disconnect purge_waiter;
FLUSH TABLES;
SET GLOBAL innodb_debug_sync = reset;
SET debug_sync= "now SIGNAL flush_unlock WAIT_FOR purge_open";
SET GLOBAL innodb_debug_sync = reset;
SET debug_sync= "ib_open_after_dict_open SIGNAL select_open";
SELECT * FROM t1;
pk b v
1 NULL NULL
2  
3 4 4
4 j j
5 K K
6 NULL NULL
DROP TABLE t1;
SET debug_sync= reset;
set global debug_dbug= @saved_dbug;
64 changes: 64 additions & 0 deletions mysql-test/suite/gcol/t/innodb_virtual_debug_purge.test
Expand Up @@ -323,3 +323,67 @@ drop table t1;
--source include/wait_until_count_sessions.inc
set debug_sync=reset;
SET GLOBAL innodb_purge_rseg_truncate_frequency = @saved_frequency;

--echo #
--echo # MDEV-18546 ASAN heap-use-after-free
--echo # in innobase_get_computed_value / row_purge
--echo #

CREATE TABLE t1 (
pk INT AUTO_INCREMENT,
b BIT(15),
v BIT(15) AS (b) VIRTUAL,
PRIMARY KEY(pk),
UNIQUE(v)
) ENGINE=InnoDB;
INSERT IGNORE INTO t1 (b) VALUES
(NULL),(b'011'),(b'000110100'),
(b'01101101010'),(b'01111001001011'),(NULL);

SET GLOBAL innodb_debug_sync = "ib_clust_v_col_before_row_allocated "
"SIGNAL before_row_allocated "
"WAIT_FOR flush_unlock";
SET GLOBAL innodb_debug_sync = "ib_open_after_dict_open "
"SIGNAL purge_open "
"WAIT_FOR select_open";

# In 10.2 trx_undo_roll_ptr_is_insert(t_roll_ptr) condition never pass in purge,
# so this condition is forced to pass in row_vers_old_has_index_entry
set @saved_dbug= @@global.debug_dbug;
set global debug_dbug= "+d,ib_purge_virtual_index_callback";

# The purge starts from REPLACE command. To avoid possible race, separate
# connection is used.
--connect(purge_waiter,localhost,root)
--send
SET debug_sync= "now WAIT_FOR before_row_allocated";

--connection default
REPLACE INTO t1 (pk, b) SELECT pk, b FROM t1;

--connection purge_waiter
# Now we will definitely catch ib_clust_v_col_before_row_allocated
--reap
--connection default
--disconnect purge_waiter

# purge hangs on the sync point. table is purged, ref_count is set to 0
FLUSH TABLES;

# Avoid hang on repeating purge.
# Reset Will be applied after first record is purged
SET GLOBAL innodb_debug_sync = reset;

SET debug_sync= "now SIGNAL flush_unlock WAIT_FOR purge_open";

# Avoid hang on repeating purge
SET GLOBAL innodb_debug_sync = reset;

# select unblocks purge thread
SET debug_sync= "ib_open_after_dict_open SIGNAL select_open";
SELECT * FROM t1;

# Cleanup
DROP TABLE t1;
SET debug_sync= reset;
set global debug_dbug= @saved_dbug;
1 change: 1 addition & 0 deletions storage/innobase/row/row0vers.cc
Expand Up @@ -467,6 +467,7 @@ row_vers_build_clust_v_col(
vcol_info->set_used();
maria_table = vcol_info->table();
}
DEBUG_SYNC(current_thd, "ib_clust_v_col_before_row_allocated");

innobase_allocate_row_for_vcol(thd, index,
&local_heap,
Expand Down

0 comments on commit 350e46a

Please sign in to comment.