[MDEV-24356] InnoDB: Failing assertion: len < sizeof(tmp_buff) in get_foreign_key_info Created: 2020-12-07  Updated: 2023-04-27

Status: Confirmed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9
Fix Version/s: 10.4, 10.5, 10.6

Type: Bug Priority: Major
Reporter: Roel Van de Paar Assignee: Vladislav Lesin
Resolution: Unresolved Votes: 0
Labels: upstream-5.5, upstream-5.6, upstream-5.7, upstream-not-8.0

Issue Links:
Relates
relates to MDEV-27369 Renaming Spider table fails due to ER... Stalled

 Description   

CREATE DATABASE `db_new..............................................end`;
SET SESSION foreign_key_checks=0;
USE `db_new..............................................end`;
CREATE TABLE mytable_ref (id int,constraint FOREIGN KEY (id) REFERENCES FOO(id) ON DELETE CASCADE) ;
SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, column_name FROM information_schema.key_column_usage WHERE (constraint_catalog IS NOT NULL OR table_catalog IS NOT NULL) AND table_name != 'abcdefghijklmnopqrstuvwxyz' ORDER BY constraint_name, table_name, column_name;

Leads to:

10.6.0 5d4599f9750140f92cfdbbe4d292ae1b8dd456f8 (Optimized)

InnoDB: Failing assertion: len < sizeof(tmp_buff)

10.6.0 5d4599f9750140f92cfdbbe4d292ae1b8dd456f8 (Optimized)

Core was generated by `/test/MD201020-mariadb-10.6.0-linux-x86_64-opt/bin/mysqld --no-defaults --core-'.
Program terminated with signal SIGABRT, Aborted.
#0  __pthread_kill (threadid=<optimized out>, signo=signo@entry=6)
    at ../sysdeps/unix/sysv/linux/pthread_kill.c:56
[Current thread is 1 (Thread 0x1488c0129700 (LWP 356177))]
(gdb) bt
#0  __pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:56
#1  0x0000559d2579fa4f in my_write_core (sig=sig@entry=6) at /test/10.6_opt/mysys/stacktrace.c:424
#2  0x0000559d251c3130 in handle_fatal_signal (sig=6) at /test/10.6_opt/sql/signal_handler.cc:330
#3  <signal handler called>
#4  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#5  0x00001488d4faa859 in __GI_abort () at abort.c:79
#6  0x0000559d24e87f98 in ut_dbg_assertion_failed (expr=expr@entry=0x559d25a934a7 "len < sizeof(tmp_buff)", file=file@entry=0x559d25a8c510 "/test/10.6_opt/storage/innobase/handler/ha_innodb.cc", line=line@entry=14821) at /test/10.6_opt/storage/innobase/ut/ut0dbg.cc:60
#7  0x0000559d24e5ce98 in get_foreign_key_info (thd=0x148880000c58, foreign=0x14888001d320) at /test/10.6_opt/storage/innobase/handler/ha_innodb.cc:14821
#8  0x0000559d254e1fbd in ha_innobase::get_foreign_key_list (this=<optimized out>, thd=0x148880000c58, f_key_list=<optimized out>) at /test/10.6_opt/storage/innobase/handler/ha_innodb.cc:14953
#9  0x0000559d25034363 in get_schema_key_column_usage_record (res=false, table_name=0x14888002aec8, db_name=0x148880029380, table=0x148880021120, tables=<optimized out>, thd=0x148880000c58) at /test/10.6_opt/sql/sql_class.h:4052
#10 get_schema_key_column_usage_record (thd=0x148880000c58, tables=<optimized out>, table=0x148880021120, res=<optimized out>, db_name=0x148880029380, table_name=0x14888002aec8) at /test/10.6_opt/sql/sql_show.cc:7126
#11 0x0000559d25025628 in fill_schema_table_by_open (thd=0x148880000c58, mem_root=<optimized out>, is_show_fields_or_keys=<optimized out>, table=0x148880021120, schema_table=0x559d2604e0c0 <schema_tables+1024>, orig_db_name=0x148880029380, orig_table_name=0x14888002aec8, open_tables_state_backup=0x1488c01261d0, can_deadlock=false) at /test/10.6_opt/sql/sql_show.cc:4641
#12 0x0000559d25039aae in get_all_tables (thd=0x148880000c58, tables=0x148880011550, cond=<optimized out>) at /test/10.6_opt/sql/sql_show.cc:5245
#13 0x0000559d2503b1d1 in get_schema_tables_result (join=join@entry=0x148880013bd0, executed_place=executed_place@entry=PROCESSED_BY_JOIN_EXEC) at /test/10.6_opt/sql/sql_show.cc:8696
#14 0x0000559d25020c87 in JOIN::exec_inner (this=0x148880013bd0) at /test/10.6_opt/sql/sql_select.cc:4421
#15 0x0000559d250212b9 in JOIN::exec (this=this@entry=0x148880013bd0) at /test/10.6_opt/sql/sql_select.cc:4246
#16 0x0000559d2501f367 in mysql_select (thd=0x148880000c58, tables=0x148880011550, fields=<optimized out>, conds=0x148880012600, og_num=3, order=0x1488800130b8, group=0x0, having=0x0, proc_param=0x0, select_options=2751728384, result=0x148880013ba8, unit=0x148880004c20, select_lex=0x1488800106c0) at /test/10.6_opt/sql/sql_select.cc:4673
#17 0x0000559d2501fd67 in handle_select (thd=thd@entry=0x148880000c58, lex=lex@entry=0x148880004b58, result=result@entry=0x148880013ba8, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.6_opt/sql/sql_select.cc:417
#18 0x0000559d24faf951 in execute_sqlcom_select (thd=0x148880000c58, all_tables=0x148880011550) at /test/10.6_opt/sql/sql_parse.cc:6062
#19 0x0000559d24fbd380 in mysql_execute_command (thd=0x148880000c58) at /test/10.6_opt/sql/sql_parse.cc:3784
#20 0x0000559d24faa03f in mysql_parse (thd=0x148880000c58, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>) at /test/10.6_opt/sql/sql_parse.cc:7833
#21 0x0000559d24fb5967 in dispatch_command (command=COM_QUERY, thd=0x148880000c58, packet=0x148880008009 "SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, column_name FROM information_schema.key_column_usage WHERE (constraint_catalog IS NOT NULL OR ta"..., packet_length=<optimized out>) at /test/10.6_opt/sql/sql_class.h:1253
#22 0x0000559d24fb7d42 in do_command (thd=0x148880000c58) at /test/10.6_opt/sql/sql_parse.cc:1343
#23 0x0000559d250bb6e1 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x559d2727e5e8, put_in_cache=put_in_cache@entry=true) at /test/10.6_opt/sql/sql_connect.cc:1410
#24 0x0000559d250bbb5d in handle_one_connection (arg=arg@entry=0x559d2727e5e8) at /test/10.6_opt/sql/sql_connect.cc:1312
#25 0x0000559d25441266 in pfs_spawn_thread (arg=0x559d271f9888) at /test/10.6_opt/storage/perfschema/pfs.cc:2201
#26 0x00001488d54b8609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#27 0x00001488d50a7293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

10.6.0 5d4599f9750140f92cfdbbe4d292ae1b8dd456f8 (Debug)

InnoDB: Failing assertion: len < sizeof(tmp_buff)

10.6.0 5d4599f9750140f92cfdbbe4d292ae1b8dd456f8 (Debug)

Core was generated by `/test/MD211020-mariadb-10.6.0-linux-x86_64-dbg/bin/mysqld --no-defaults --core-'.
Program terminated with signal SIGABRT, Aborted.
#0  __pthread_kill (threadid=<optimized out>, signo=signo@entry=6)
    at ../sysdeps/unix/sysv/linux/pthread_kill.c:56
[Current thread is 1 (Thread 0x151ab0991700 (LWP 366632))]
(gdb) bt
#0  __pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ../sysdeps/unix/sysv/linux/pthread_kill.c:56
#1  0x0000560964e8e021 in my_write_core (sig=sig@entry=6) at /test/10.6_dbg/mysys/stacktrace.c:424
#2  0x00005609645d5321 in handle_fatal_signal (sig=6) at /test/10.6_dbg/sql/signal_handler.cc:330
#3  <signal handler called>
#4  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#5  0x0000151ab3553859 in __GI_abort () at abort.c:79
#6  0x0000560964c4b9d5 in ut_dbg_assertion_failed (expr=expr@entry=0x56096522d07e "len < sizeof(tmp_buff)", file=file@entry=0x56096522ef98 "/test/10.6_dbg/storage/innobase/handler/ha_innodb.cc", line=line@entry=14821) at /test/10.6_dbg/storage/innobase/ut/ut0dbg.cc:60
#7  0x00005609649e359d in get_foreign_key_info (thd=thd@entry=0x151a58000db8, foreign=0x151a58022ac8) at /test/10.6_dbg/storage/innobase/handler/ha_innodb.cc:14821
#8  0x00005609649e7b3e in ha_innobase::get_foreign_key_list (this=0x151a5847d020, thd=0x151a58000db8, f_key_list=0x151ab098c3e0) at /test/10.6_dbg/storage/innobase/handler/ha_innodb.cc:14953
#9  0x00005609643b6515 in get_schema_key_column_usage_record (thd=0x151a58000db8, tables=<optimized out>, table=0x151a5801f2a0, res=<optimized out>, db_name=0x151a5802e270, table_name=0x151a58030198) at /test/10.6_dbg/sql/sql_show.cc:7174
#10 0x000056096439b4d5 in fill_schema_table_by_open (thd=thd@entry=0x151a58000db8, mem_root=mem_root@entry=0x151ab098e240, is_show_fields_or_keys=is_show_fields_or_keys@entry=false, table=table@entry=0x151a5801f2a0, schema_table=schema_table@entry=0x5609658833c0 <schema_tables+1024>, orig_db_name=orig_db_name@entry=0x151a5802e270, orig_table_name=0x151a58030198, open_tables_state_backup=0x151ab098e280, can_deadlock=false) at /test/10.6_dbg/sql/sql_show.cc:4641
#11 0x00005609643be311 in get_all_tables (thd=0x151a58000db8, tables=0x151a58013820, cond=<optimized out>) at /test/10.6_dbg/sql/sql_show.cc:5245
#12 0x00005609643bf5ad in get_schema_tables_result (join=join@entry=0x151a58015ea0, executed_place=executed_place@entry=PROCESSED_BY_JOIN_EXEC) at /test/10.6_dbg/sql/sql_show.cc:8696
#13 0x0000560964393c3f in JOIN::exec_inner (this=this@entry=0x151a58015ea0) at /test/10.6_dbg/sql/sql_select.cc:4442
#14 0x0000560964394733 in JOIN::exec (this=this@entry=0x151a58015ea0) at /test/10.6_dbg/sql/sql_select.cc:4246
#15 0x0000560964392944 in mysql_select (thd=thd@entry=0x151a58000db8, tables=0x151a58013820, fields=@0x151a58012ae0: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x151a58012f58, last = 0x151a580137a0, elements = 7}, <No data fields>}, conds=0x151a580148d0, og_num=3, order=0x151a58015388, group=0x0, having=0x0, proc_param=0x0, select_options=2751728384, result=0x151a58015e78, unit=0x151a58004f40, select_lex=0x151a58012990) at /test/10.6_dbg/sql/sql_select.cc:4673
#16 0x0000560964392c72 in handle_select (thd=thd@entry=0x151a58000db8, lex=lex@entry=0x151a58004e78, result=result@entry=0x151a58015e78, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.6_dbg/sql/sql_select.cc:417
#17 0x000056096430638e in execute_sqlcom_select (thd=thd@entry=0x151a58000db8, all_tables=0x151a58013820) at /test/10.6_dbg/sql/sql_parse.cc:6062
#18 0x0000560964312aea in mysql_execute_command (thd=thd@entry=0x151a58000db8) at /test/10.6_dbg/sql/sql_parse.cc:3784
#19 0x00005609642fefd2 in mysql_parse (thd=thd@entry=0x151a58000db8, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x151ab09903d0) at /test/10.6_dbg/sql/sql_parse.cc:7833
#20 0x000056096430d0c7 in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x151a58000db8, packet=packet@entry=0x151a58008ce9 "SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, column_name FROM information_schema.key_column_usage WHERE (constraint_catalog IS NOT NULL OR ta"..., packet_length=packet_length@entry=321) at /test/10.6_dbg/sql/sql_class.h:1253
#21 0x00005609643103d2 in do_command (thd=0x151a58000db8) at /test/10.6_dbg/sql/sql_parse.cc:1343
#22 0x000056096446a994 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x560968bf9778, put_in_cache=put_in_cache@entry=true) at /test/10.6_dbg/sql/sql_connect.cc:1410
#23 0x000056096446b09b in handle_one_connection (arg=arg@entry=0x560968bf9778) at /test/10.6_dbg/sql/sql_connect.cc:1312
#24 0x000056096491eabb in pfs_spawn_thread (arg=0x560968b00418) at /test/10.6_dbg/storage/perfschema/pfs.cc:2201
#25 0x0000151ab3a61609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#26 0x0000151ab3650293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Bug confirmed present in:
MariaDB: 10.2.42 (dbg), 10.2.42 (opt), 10.3.33 (dbg), 10.3.33 (opt), 10.4.23 (dbg), 10.4.23 (opt), 10.5.14 (dbg), 10.5.14 (opt), 10.6.6 (dbg), 10.6.6 (opt), 10.7.2 (dbg), 10.7.2 (opt), 10.8.0 (dbg), 10.8.0 (opt)
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.36 (dbg), 5.7.36 (opt)

Bug (or feature/syntax) confirmed not present in:
MySQL: 8.0.27 (dbg), 8.0.27 (opt)



 Comments   
Comment by Marko Mäkelä [ 2020-12-07 ]

The problem appears to be that the

	char		tmp_buff[NAME_LEN+1];

is simply too small, allocating only NAME_CHAR_LEN times 3 bytes. The maximum filename-safe encoded database name length is 5×64 characters, or 321 characters. And yes, there exist some ASCII characters for which the filename-safe encoding is 5 characters per character.

Side note: At only 512 bytes, FN_REFLEN shorter less than the maximum data file name length. The maximum is something like 4*5*64 ASCII characters, plus some delimiters. To overcome a file system limitation, innodb_file_per_table=0 may be used. But, FOREIGN KEY constraints are not supported for partitioned tables (MDEV-12483), so for this function the maximum should be less. (Also, the SQL layer would probably refuse to create an .frm file if the file name length exceeded FN_REFLEN.)

In this case, do we even need the tmp_buff? We could use something similar to std::string_view or LEX_CSTRING.

Comment by Roel Van de Paar [ 2020-12-07 ]

Unique ID's (inc MS)

len < sizeof(tmp_buff)|SIGABRT|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_key_column_usage_record|fill_schema_table_by_open
len < sizeof(tmp_buff)|SIGABRT|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_key_column_usage_record|get_schema_key_column_usage_record
len < sizeof(tmp_buff)|SIGABRT|ut_dbg_assertion_failed|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_key_column_usage_record
len < sizeof(tmp_buff)|SIGABRT|ut_dbg_assertion_failed|get_foreign_key_info|ha_innobase::get_parent_foreign_key_list|prepare_fk_prelocking_list
len < sizeof(tmp_buff)|SIGABRT|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_constraints_record|fill_schema_table_by_open
len < sizeof(tmp_buff)|SIGABRT|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_constraints_record|get_schema_constraints_record
len < sizeof(tmp_buff)|SIGABRT|ut_dbg_assertion_failed|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_constraints_record

Comment by Roel Van de Paar [ 2022-02-15 ]

This new testcase only crashes MariaDB with a new stack.

CREATE DATABASE `..................................................`;
USE `..................................................`;
CREATE TABLE t(a INT KEY,b INT,FOREIGN KEY (b)REFERENCES t (a)) ROW_FORMAT=REDUNDANT;
INSERT INTO t VALUES(6,6,6);

Leads to:

10.5.14 059a8fd87eb900a5a12185b1963e5623df874c21 (Optimized)

InnoDB: Failing assertion: len < sizeof(tmp_buff)

10.5.14 059a8fd87eb900a5a12185b1963e5623df874c21 (Optimized)

Core was generated by `/test/MD290122-mariadb-10.5.14-linux-x86_64-opt/bin/mysqld --no-defaults --core'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[Current thread is 1 (Thread 0x148d78ca2700 (LWP 1377143))]
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x0000148d840ee859 in __GI_abort () at abort.c:79
#2  0x00005623022d1db8 in ut_dbg_assertion_failed (expr=expr@entry=0x562302f4f959 "len < sizeof(tmp_buff)", file=file@entry=0x562302f48348 "/test/10.5_opt/storage/innobase/handler/ha_innodb.cc", line=line@entry=15049) at /test/10.5_opt/storage/innobase/ut/ut0dbg.cc:60
#3  0x00005623022a5b04 in get_foreign_key_info (thd=0x148cf8000c58, foreign=0x148cf801b9f0) at /test/10.5_opt/storage/innobase/handler/ha_innodb.cc:15049
#4  0x000056230294b5dd in ha_innobase::get_parent_foreign_key_list (this=<optimized out>, thd=<optimized out>, f_key_list=<optimized out>) at /test/10.5_opt/storage/innobase/handler/ha_innodb.cc:15219
#5  0x000056230239a078 in prepare_fk_prelocking_list (op=1 '\001', need_prelocking=0x148d78ca094f, table_list=0x148cf8010508, prelocking_ctx=0x148cf8004b80, thd=0x148cf8000c58) at /test/10.5_opt/sql/sql_class.h:1159
#6  DML_prelocking_strategy::handle_table (this=<optimized out>, thd=0x148cf8000c58, prelocking_ctx=0x148cf8004b80, table_list=0x148cf8010508, need_prelocking=0x148d78ca094f) at /test/10.5_opt/sql/sql_base.cc:4712
#7  0x0000562302398f3b in extend_table_list (thd=thd@entry=0x148cf8000c58, tables=tables@entry=0x148cf8010508, prelocking_strategy=prelocking_strategy@entry=0x148d78ca0bd0, has_prelocking_list=has_prelocking_list@entry=false) at /test/10.5_opt/sql/sql_base.cc:3550
#8  0x000056230239b2d3 in open_and_process_table (ot_ctx=0x148d78ca0a10, has_prelocking_list=false, prelocking_strategy=0x148d78ca0bd0, flags=0, counter=0x148d78ca0aac, tables=0x148cf8010508, thd=0x148cf8000c58) at /test/10.5_opt/sql/sql_base.cc:3842
#9  open_tables (thd=thd@entry=0x148cf8000c58, options=@0x148cf8006128: {m_options = DDL_options_st::OPT_NONE}, start=start@entry=0x148d78ca0a98, counter=counter@entry=0x148d78ca0aac, flags=flags@entry=0, prelocking_strategy=0x148d78ca0bd0) at /test/10.5_opt/sql/sql_base.cc:4271
#10 0x000056230239c52a in open_and_lock_tables (thd=thd@entry=0x148cf8000c58, options=<optimized out>, tables=<optimized out>, tables@entry=0x148cf8010508, derived=derived@entry=true, flags=flags@entry=0, prelocking_strategy=<optimized out>) at /test/10.5_opt/sql/sql_base.cc:5217
#11 0x00005623023cda7a in open_and_lock_tables (flags=<optimized out>, derived=<optimized out>, tables=<optimized out>, thd=<optimized out>) at /test/10.5_opt/sql/sql_base.h:507
#12 open_and_lock_for_insert_delayed (table_list=<optimized out>, thd=<optimized out>) at /test/10.5_opt/sql/sql_insert.cc:626
#13 mysql_insert (thd=thd@entry=0x148cf8000c58, table_list=0x148cf8010508, fields=@0x148cf8005b18: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5623035ae150 <end_of_list>, last = 0x148cf8005b18, elements = 0}, <No data fields>}, values_list=@0x148cf8005b60: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x148cf80112c8, last = 0x148cf80112c8, elements = 1}, <No data fields>}, update_fields=@0x148cf8005b48: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5623035ae150 <end_of_list>, last = 0x148cf8005b48, elements = 0}, <No data fields>}, update_values=@0x148cf8005b30: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x5623035ae150 <end_of_list>, last = 0x148cf8005b30, elements = 0}, <No data fields>}, duplic=<optimized out>, ignore=<optimized out>, result=<optimized out>) at /test/10.5_opt/sql/sql_insert.cc:752
#14 0x00005623024097be in mysql_execute_command (thd=0x148cf8000c58) at /test/10.5_opt/sql/sql_parse.cc:4624
#15 0x00005623023f7bf3 in mysql_parse (thd=0x148cf8000c58, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>, is_com_multi=<optimized out>, is_next_command=<optimized out>) at /test/10.5_opt/sql/sql_parse.cc:8100
#16 0x0000562302404a0d in dispatch_command (command=COM_QUERY, thd=0x148cf8000c58, packet=<optimized out>, packet_length=<optimized out>, is_com_multi=<optimized out>, is_next_command=<optimized out>) at /test/10.5_opt/sql/sql_class.h:1290
#17 0x00005623024071e2 in do_command (thd=0x148cf8000c58) at /test/10.5_opt/sql/sql_parse.cc:1370
#18 0x000056230250ed41 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x562304bf5188, put_in_cache=put_in_cache@entry=true) at /test/10.5_opt/sql/sql_connect.cc:1418
#19 0x000056230250f1bd in handle_one_connection (arg=arg@entry=0x562304bf5188) at /test/10.5_opt/sql/sql_connect.cc:1312
#20 0x00005623028a3ec2 in pfs_spawn_thread (arg=0x562304b63548) at /test/10.5_opt/storage/perfschema/pfs.cc:2201
#21 0x0000148d845fd609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#22 0x0000148d841eb293 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Bug confirmed present in:
MariaDB: 10.2.42 (dbg), 10.2.42 (opt), 10.3.33 (dbg), 10.3.33 (opt), 10.4.23 (dbg), 10.4.23 (opt), 10.5.14 (dbg), 10.5.14 (opt), 10.6.6 (dbg), 10.6.6 (opt), 10.7.2 (dbg), 10.7.2 (opt), 10.8.1 (dbg), 10.8.1 (opt), 10.9.0 (dbg), 10.9.0 (opt)

Bug (or feature/syntax) confirmed not present in:
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.36 (dbg), 5.7.36 (opt), 8.0.27 (dbg), 8.0.27 (opt)

Comment by Marko Mäkelä [ 2022-02-15 ]

In the function get_foreign_key_info(), the stack-allocated buffer tmp_buff is too small, only NAME_LEN+1 bytes. 3*NAME_CHAR_LEN+1 would be sufficient for a database or table name that is encoded in system_charset_info (at most 64 utf8mb3 characters). We expect the database name of foreign->referenced_table_name to fit in that space. But, in the filename-safe encoding, some ASCII characters such as . are encoded in 5 bytes (ASCII characters), like @002e. So, the maximum length of a database name in this encoding is 320 bytes, or 321 with the terminating NUL byte.

I think that it would be better if we can avoid the copying here:

	len = dict_get_db_name_len(foreign->referenced_table_name);
	ut_a(len < sizeof(tmp_buff));
	memcpy(tmp_buff, foreign->referenced_table_name, len);
	tmp_buff[len] = 0;
 
	len = filename_to_tablename(tmp_buff, name_buff, sizeof(name_buff));

That is, filename_to_tablename() should not expect a NUL-terminated input buffer, but instead operate on foreign->referenced_table_name and len.

Comment by Roel Van de Paar [ 2022-03-11 ]

New stacks

len < sizeof(tmp_buff)|SIGABRT|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_constraints_record|fill_schema_table_by_open
len < sizeof(tmp_buff)|SIGABRT|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_constraints_record|get_schema_constraints_record
len < sizeof(tmp_buff)|SIGABRT|ut_dbg_assertion_failed|get_foreign_key_info|ha_innobase::get_foreign_key_list|get_schema_constraints_record

With this testcase:

create database `db_new..............................................end`;
set foreign_key_checks=0;
USE `db_new..............................................end`;
CREATE TABLE t0(a INT,b CHAR,FOREIGN KEY (a)REFERENCES t_0(a) ON DELETE CASCADE);
SELECT * FROM information_schema.table_constraints;

Leads to:

10.9.0 4a2a9c02cd6611ef36bbb735c2b483dbc83580d4 (Debug)

InnoDB: Failing assertion: len < sizeof(tmp_buff)

10.9.0 4a2a9c02cd6611ef36bbb735c2b483dbc83580d4 (Debug)

Core was generated by `/test/MD260222-mariadb-10.9.0-linux-x86_64-dbg/bin/mysqld --no-defaults --core-'.
Program terminated with signal SIGABRT, Aborted.
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
[Current thread is 1 (Thread 0x154e9c1b0700 (LWP 798163))]
(gdb) bt
#0  __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x0000154eb3445859 in __GI_abort () at abort.c:79
#2  0x0000556de4fcb594 in ut_dbg_assertion_failed (expr=expr@entry=0x556de55f71b9 "len < sizeof(tmp_buff)", file=file@entry=0x556de55f9418 "/test/10.9_dbg/storage/innobase/handler/ha_innodb.cc", line=line@entry=15404) at /test/10.9_dbg/storage/innobase/ut/ut0dbg.cc:60
#3  0x0000556de4d81c74 in get_foreign_key_info (thd=thd@entry=0x154e44000db8, foreign=0x154e44022c08) at /test/10.9_dbg/storage/innobase/handler/ha_innodb.cc:15404
#4  0x0000556de4d84d6f in ha_innobase::get_foreign_key_list (this=0x154e44475a40, thd=0x154e44000db8, f_key_list=0x154e9c1ab040) at /test/10.9_dbg/storage/innobase/handler/ha_innodb.cc:15532
#5  0x0000556de477dce1 in get_schema_constraints_record (thd=0x154e44000db8, tables=<optimized out>, table=0x154e440275f0, res=<optimized out>, db_name=0x154e4402dbe8, table_name=0x154e44030d60) at /test/10.9_dbg/sql/sql_show.cc:7089
#6  0x0000556de476598d in fill_schema_table_by_open (thd=thd@entry=0x154e44000db8, mem_root=mem_root@entry=0x154e9c1acf60, is_show_fields_or_keys=is_show_fields_or_keys@entry=false, table=table@entry=0x154e440275f0, schema_table=schema_table@entry=0x556de5c5a220 <schema_tables+2304>, orig_db_name=orig_db_name@entry=0x154e4402dbe8, orig_table_name=0x154e44030d60, open_tables_state_backup=0x154e9c1acfa0, can_deadlock=false) at /test/10.9_dbg/sql/sql_show.cc:4716
#7  0x0000556de478996f in get_all_tables (thd=0x154e44000db8, tables=0x154e440144e8, cond=<optimized out>) at /test/10.9_dbg/sql/sql_show.cc:5326
#8  0x0000556de478aff9 in get_schema_tables_result (join=join@entry=0x154e44015830, executed_place=executed_place@entry=PROCESSED_BY_JOIN_EXEC) at /test/10.9_dbg/sql/sql_show.cc:8841
#9  0x0000556de475dc50 in JOIN::exec_inner (this=this@entry=0x154e44015830) at /test/10.9_dbg/sql/sql_string.h:687
#10 0x0000556de475e932 in JOIN::exec (this=this@entry=0x154e44015830) at /test/10.9_dbg/sql/sql_select.cc:4527
#11 0x0000556de475c941 in mysql_select (thd=thd@entry=0x154e44000db8, tables=0x154e440144e8, fields=@0x154e44014178: {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x154e44014468, last = 0x154e44016658, elements = 6}, <No data fields>}, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=2751728384, result=0x154e44015808, unit=0x154e440051c8, select_lex=0x154e44013ed8) at /test/10.9_dbg/sql/sql_select.cc:5007
#12 0x0000556de475cbf6 in handle_select (thd=thd@entry=0x154e44000db8, lex=lex@entry=0x154e440050f0, result=result@entry=0x154e44015808, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/10.9_dbg/sql/sql_select.cc:543
#13 0x0000556de46bc152 in execute_sqlcom_select (thd=thd@entry=0x154e44000db8, all_tables=0x154e440144e8) at /test/10.9_dbg/sql/sql_parse.cc:6252
#14 0x0000556de46c90b9 in mysql_execute_command (thd=thd@entry=0x154e44000db8, is_called_from_prepared_stmt=is_called_from_prepared_stmt@entry=false) at /test/10.9_dbg/sql/sql_parse.cc:3943
#15 0x0000556de46b5343 in mysql_parse (thd=thd@entry=0x154e44000db8, rawbuf=<optimized out>, length=<optimized out>, parser_state=parser_state@entry=0x154e9c1af400) at /test/10.9_dbg/sql/sql_parse.cc:8027
#16 0x0000556de46c3fdf in dispatch_command (command=command@entry=COM_QUERY, thd=thd@entry=0x154e44000db8, packet=packet@entry=0x154e4400b889 "SELECT * FROM information_schema.table_constraints", packet_length=packet_length@entry=50, blocking=blocking@entry=true) at /test/10.9_dbg/sql/sql_class.h:1362
#17 0x0000556de46c7426 in do_command (thd=0x154e44000db8, blocking=blocking@entry=true) at /test/10.9_dbg/sql/sql_parse.cc:1402
#18 0x0000556de4842036 in do_handle_one_connection (connect=<optimized out>, connect@entry=0x556de73a4648, put_in_cache=put_in_cache@entry=true) at /test/10.9_dbg/sql/sql_connect.cc:1418
#19 0x0000556de484263b in handle_one_connection (arg=arg@entry=0x556de73a4648) at /test/10.9_dbg/sql/sql_connect.cc:1312
#20 0x0000556de4cc8d23 in pfs_spawn_thread (arg=0x556de72b7868) at /test/10.9_dbg/storage/perfschema/pfs.cc:2201
#21 0x0000154eb3956609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#22 0x0000154eb3542163 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Bug confirmed present in:
MariaDB: 10.2.44 (dbg), 10.2.44 (opt), 10.3.35 (dbg), 10.3.35 (opt), 10.4.25 (dbg), 10.4.25 (opt), 10.5.16 (dbg), 10.5.16 (opt), 10.6.8 (dbg), 10.6.8 (opt), 10.7.4 (dbg), 10.7.4 (opt), 10.8.3 (dbg), 10.8.3 (opt), 10.9.0 (dbg), 10.9.0 (opt)
MySQL: 5.5.62 (dbg), 5.5.62 (opt), 5.6.51 (dbg), 5.6.51 (opt), 5.7.37 (dbg), 5.7.37 (opt)

Bug (or feature/syntax) confirmed not present in:
MySQL: 8.0.28 (dbg), 8.0.28 (opt)

Generated at Thu Feb 08 09:29:22 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.