diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2020-12-17 02:41:17 +1000 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2020-12-18 20:17:45 +1000 |
commit | 83d2e0841ee30727c609f23957cc592399a3aca4 (patch) | |
tree | bbeedf758d1299ada982d9f6a51e77428e39dc39 | |
parent | 25d6f634b89c4b1ad8ae721921b5ccf595073270 (diff) | |
download | mariadb-git-83d2e0841ee30727c609f23957cc592399a3aca4.tar.gz |
MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB
row_upd_clust_step() calls row_upd_del_mark_clust_rec() which would
allocate some memory in row_ins_foreign_fill_virtual(). Then,
row_upd_store_row() would access the allocated memory, but only after
potentially freeing that memory by invoking mem_heap_empty(),
leading to ASAN heap-use-after-free diagnostics.
row_ins_foreign_fill_virtual(): Use a more appropriate memory heap with a
longer lifetime.
-rw-r--r-- | mysql-test/suite/gcol/r/innodb_virtual_fk.result | 28 | ||||
-rw-r--r-- | mysql-test/suite/gcol/t/innodb_virtual_fk.test | 37 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 2 |
3 files changed, 66 insertions, 1 deletions
diff --git a/mysql-test/suite/gcol/r/innodb_virtual_fk.result b/mysql-test/suite/gcol/r/innodb_virtual_fk.result index 50685e04a69..68601823e31 100644 --- a/mysql-test/suite/gcol/r/innodb_virtual_fk.result +++ b/mysql-test/suite/gcol/r/innodb_virtual_fk.result @@ -790,3 +790,31 @@ t1 CREATE TABLE `t1` ( ALTER TABLE t1 DROP INDEX f1; ALTER TABLE t1 DROP f3; DROP TABLE t1; +# +# MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB +# +CREATE TABLE emails ( +id int, +PRIMARY KEY (id) +) ENGINE=InnoDB; +CREATE TABLE email_stats ( +id int, +email_id int, +date_sent char(4), +generated_email_id int as (email_id), +PRIMARY KEY (id), +KEY mautic_generated_sent_date_email_id (generated_email_id), +FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL +) ENGINE=InnoDB; +CREATE TABLE emails_metadata ( +email_id int, +PRIMARY KEY (email_id), +CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE +) ENGINE=InnoDB; +INSERT INTO emails VALUES (1); +INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); +INSERT INTO emails_metadata VALUES (1); +DELETE FROM emails; +DROP TABLE email_stats; +DROP TABLE emails_metadata; +DROP TABLE emails; diff --git a/mysql-test/suite/gcol/t/innodb_virtual_fk.test b/mysql-test/suite/gcol/t/innodb_virtual_fk.test index 23d3ee97290..da20612f0a1 100644 --- a/mysql-test/suite/gcol/t/innodb_virtual_fk.test +++ b/mysql-test/suite/gcol/t/innodb_virtual_fk.test @@ -649,3 +649,40 @@ SHOW CREATE TABLE t1; ALTER TABLE t1 DROP INDEX f1; ALTER TABLE t1 DROP f3; DROP TABLE t1; + +--echo # +--echo # MDEV-24041 Generated column DELETE with FOREIGN KEY crash InnoDB +--echo # + +CREATE TABLE emails ( + id int, + PRIMARY KEY (id) +) ENGINE=InnoDB; + +CREATE TABLE email_stats ( + id int, + email_id int, + date_sent char(4), + generated_email_id int as (email_id), + PRIMARY KEY (id), + KEY mautic_generated_sent_date_email_id (generated_email_id), + FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL +) ENGINE=InnoDB; + + +CREATE TABLE emails_metadata ( + email_id int, + PRIMARY KEY (email_id), + CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE +) ENGINE=InnoDB; + + +INSERT INTO emails VALUES (1); +INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); +INSERT INTO emails_metadata VALUES (1); + +DELETE FROM emails; + +DROP TABLE email_stats; +DROP TABLE emails_metadata; +DROP TABLE emails; diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index ca04be71953..635e7f659eb 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -931,7 +931,7 @@ row_ins_foreign_fill_virtual( update->old_vrow = row_build( ROW_COPY_DATA, index, rec, offsets, index->table, NULL, NULL, - &ext, cascade->heap); + &ext, update->heap); n_diff = update->n_fields; if (index->table->vc_templ == NULL) { |