-
-
Notifications
You must be signed in to change notification settings - Fork 2k
MDEV-19194 ASAN use-after-poison in fk_prepare_copy_alter_table upon dropping FK #4642
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 10.6
Are you sure you want to change the base?
Conversation
|
|
dr-m
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can confirm that 1758b25 with the changed test (without the code change) would fail as follows:
2026-02-12 11:24:34 3 [Warning] InnoDB: Load table `test`.`t3` failed, the table has missing foreign key indexes. Turn off 'foreign_key_checks' and try again.
2026-02-12 11:24:34 3 [Note] InnoDB: Foreign Key referenced table test/t3 not found for foreign table test/t2
=================================================================
==220650==ERROR: AddressSanitizer: use-after-poison on address 0x557284a019e8 at pc 0x557281d82b95 bp 0x7bd4f2a656e0 sp 0x7bd4f2a656d8
READ of size 8 at 0x557284a019e8 thread T10
#0 0x557281d82b94 in base_list_iterator::next_fast() /mariadb/10.6/sql/sql_list.h:442
#1 0x557281d82b94 in List_iterator_fast<Alter_drop>::operator++(int) /mariadb/10.6/sql/sql_list.h:618
#2 0x557281d82b94 in fk_prepare_copy_alter_table /mariadb/10.6/sql/sql_table.cc:9441
#3 0x557281dc9fc9 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Recreate_info*, Alter_info*, unsigned int, st_order*, bool, bool) /mariadb/10.6/sql/sql_table.cc:10876
#4 0x557281f1f635 in Sql_cmd_alter_table::execute(THD*) /mariadb/10.6/sql/sql_alter.cc:675
#5 0x557281b88a38 in mysql_execute_command(THD*, bool) /mariadb/10.6/sql/sql_parse.cc:6168
#6 0x557281b975a2 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /mariadb/10.6/sql/sql_parse.cc:8201
#7 0x557281b9b7d1 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /mariadb/10.6/sql/sql_parse.cc:1911
#8 0x557281b9eb1f in do_command(THD*, bool) /mariadb/10.6/sql/sql_parse.cc:1421
#9 0x557281f0a429 in do_handle_one_connection(CONNECT*, bool) /mariadb/10.6/sql/sql_connect.cc:1386
#10 0x557281f0a8e9 in handle_one_connection /mariadb/10.6/sql/sql_connect.cc:1298
#11 0x55728288f5dd in pfs_spawn_thread /mariadb/10.6/storage/perfschema/pfs.cc:2201
#12 0x7fd50865c0f5 in asan_thread_start ../../../../src/libsanitizer/asan/asan_interceptors.cpp:239
#13 0x7fd50789f468 in start_thread nptl/pthread_create.c:448
#14 0x7fd50791dcf7 in __clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:78
0x557284a019e8 is located 8 bytes inside of global variable 'end_of_list' defined in '/mariadb/10.6/sql/sql_list.cc:24:11' (0x557284a019e0) of size 16
SUMMARY: AddressSanitizer: use-after-poison /mariadb/10.6/sql/sql_list.h:442 in base_list_iterator::next_fast()
The test with the code change present passed in https://buildbot.mariadb.org/#/builders/588/builds/18268 as well as in my local environment.
However, I believe that it would be better to catch user errors. Someone could intend to type ALTER TABLE t1 DROP FOREIGN KEY f1, DROP FOREIGN KEY f2 but accidentally type f1 twice, and then be surprised that f2 was not dropped.
…dropping FK Problem: ======== The issue occurs when ALTER TABLE contains duplicate DROP FOREIGN KEY operations (e.g., "DROP FOREIGN KEY f1, DROP FOREIGN KEY f1"). In fk_prepare_copy_alter_table(), Removes from the list all foreign keys which are to be dropped. But iterator continues to accessing the removed entry when it encounters duplicate foreign key. Solution: ========= mysql_prepare_alter_table(): Add duplicate detection logic to handle cases where the same foreign key is specified multiple times in a single ALTER TABLE statement's DROP clause fk_prepare_copy_alter_table(): Handles both parent foreign keys, child foreign keys. This prevents iterator invalidation while maintaining the same functional behavior for foreign key constraint removal during ALTER TABLE operations. This patch does the following: - Iterate through foreign key lists and collect FOREIGN_KEY_INFO pointers to be removed in a separate keys_to_remove list - For each collected key, rewind the original iterator, find the matching key by pointer comparison, and remove it safely.
991baa8 to
e120d8f
Compare
Problem:
The issue occurs when ALTER TABLE contains duplicate DROP FOREIGN KEY operations (e.g., "DROP FOREIGN KEY f1, DROP FOREIGN KEY f1"). In fk_prepare_copy_alter_table(), Removes from the list all foreign keys which are to be dropped. But iterator continues to accessing the removed entry when it encounters duplicate foreign key.
Solution:
fk_prepare_copy_alter_table(): Handles both parent foreign keys, child foreign keys. This prevents iterator invalidation while maintaining the same functional behavior for foreign key constraint removal during ALTER TABLE operations. This patch does the following:
Iterate through foreign key lists and collect FOREIGN_KEY_INFO pointers to be removed in a separate keys_to_remove list
For each collected key, rewind the original iterator, find the matching key by pointer comparison, and remove it safely.