Commit 173e562d authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-26228 ASAN heap-use-after-free with ON UPDATE CASCADE

In commit 83d2e084 (MDEV-24041)
we failed to notice that in addition to the bug with
DELETE and ON DELETE CASCADE, there is another bug with
UPDATE and ON UPDATE CASCADE.

row_ins_foreign_fill_virtual(): Use the correct memory heap
for everything that will be reachable from the cascade->update
that we return to the caller.

Note: It is correct to use the shorter-lived cascade->heap for
rec_get_offsets(), because that memory will be abandoned when
row_ins_foreign_fill_virtual() returns.
parent 4c4237e6
...@@ -809,15 +809,18 @@ generated_email_id int as (email_id), ...@@ -809,15 +809,18 @@ generated_email_id int as (email_id),
PRIMARY KEY (id), PRIMARY KEY (id),
KEY mautic_generated_sent_date_email_id (generated_email_id), KEY mautic_generated_sent_date_email_id (generated_email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB; ) ENGINE=InnoDB;
CREATE TABLE emails_metadata ( CREATE TABLE emails_metadata (
email_id int, email_id int,
PRIMARY KEY (email_id), PRIMARY KEY (email_id),
CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB; ) ENGINE=InnoDB;
INSERT INTO emails VALUES (1); INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan');
INSERT INTO emails_metadata VALUES (1); INSERT INTO emails_metadata VALUES (1);
UPDATE emails SET id=2;
DELETE FROM emails; DELETE FROM emails;
DROP TABLE email_stats; DROP TABLE email_stats;
DROP TABLE emails_metadata; DROP TABLE emails_metadata;
......
...@@ -670,6 +670,7 @@ CREATE TABLE email_stats ( ...@@ -670,6 +670,7 @@ CREATE TABLE email_stats (
PRIMARY KEY (id), PRIMARY KEY (id),
KEY mautic_generated_sent_date_email_id (generated_email_id), KEY mautic_generated_sent_date_email_id (generated_email_id),
FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB; ) ENGINE=InnoDB;
...@@ -677,6 +678,7 @@ CREATE TABLE emails_metadata ( ...@@ -677,6 +678,7 @@ CREATE TABLE emails_metadata (
email_id int, email_id int,
PRIMARY KEY (email_id), PRIMARY KEY (email_id),
CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE CONSTRAINT FK FOREIGN KEY (email_id) REFERENCES emails (id) ON DELETE CASCADE
ON UPDATE CASCADE
) ENGINE=InnoDB; ) ENGINE=InnoDB;
...@@ -684,6 +686,7 @@ INSERT INTO emails VALUES (1); ...@@ -684,6 +686,7 @@ INSERT INTO emails VALUES (1);
INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan'); INSERT INTO email_stats (id, email_id, date_sent) VALUES (1,1,'Jan');
INSERT INTO emails_metadata VALUES (1); INSERT INTO emails_metadata VALUES (1);
UPDATE emails SET id=2;
DELETE FROM emails; DELETE FROM emails;
DROP TABLE email_stats; DROP TABLE email_stats;
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2020, MariaDB Corporation. Copyright (c) 2016, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -969,8 +969,8 @@ row_ins_foreign_fill_virtual( ...@@ -969,8 +969,8 @@ row_ins_foreign_fill_virtual(
upd_field = update->fields + n_diff; upd_field = update->fields + n_diff;
upd_field->old_v_val = static_cast<dfield_t*>( upd_field->old_v_val = static_cast<dfield_t*>(
mem_heap_alloc(cascade->heap, mem_heap_alloc(update->heap,
sizeof *upd_field->old_v_val)); sizeof *upd_field->old_v_val));
dfield_copy(upd_field->old_v_val, vfield); dfield_copy(upd_field->old_v_val, vfield);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment