[MDEV-31523] Using two temporary tables in OPTIMIZE TABLE lead to crash Created: 2023-06-22  Updated: 2024-01-12  Resolved: 2024-01-12

Status: Closed
Project: MariaDB Server
Component/s: OTHER
Affects Version/s: 11.2
Fix Version/s: 10.4.33, 10.5.24, 10.6.17, 10.11.7, 11.0.5, 11.1.4, 11.2.3

Type: Bug Priority: Critical
Reporter: Ramesh Sivaraman Assignee: Oleksandr Byelkin
Resolution: Fixed Votes: 0
Labels: None


 Description   

CREATE TEMPORARY TABLE t1 (c INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE t2 (c INT) ENGINE=MyISAM;
PREPARE s FROM 'optimize TABLE t1,t2';
EXECUTE s;
SHOW TABLES;

Leads to

11.2.0 acb02f646ebbd8b100c30621b92dcc0e2e4db7b3 (Optimized, UBASAN)

/test/mtest/MDEV-5816/11.1_opt_san/sql/sql_show.cc:5315:44: runtime error: member access within null pointer of type 'struct TABLE'
    #0 0x5564335b3acb in get_all_tables(THD*, TABLE_LIST*, Item*) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_show.cc:5315
    #1 0x5564335bc9bc in get_schema_tables_result(JOIN*, enum_schema_table_state) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_show.cc:9129
    #2 0x5564334b801c in JOIN::exec_inner() /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_select.cc:4890
    #3 0x5564334be849 in JOIN::exec() /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_select.cc:4710
    #4 0x5564334abc6c in mysql_select(THD*, TABLE_LIST*, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_select.cc:5239
    #5 0x5564334af873 in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_select.cc:627
    #6 0x55643308bb3f in execute_sqlcom_select /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_parse.cc:6030
    #7 0x5564330da217 in mysql_execute_command(THD*, bool) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_parse.cc:3944
    #8 0x55643305b2f0 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_parse.cc:7769
    #9 0x5564330b09a8 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_parse.cc:1892
    #10 0x5564330bc14d in do_command(THD*, bool) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_parse.cc:1405
    #11 0x5564339ec6bd in do_handle_one_connection(CONNECT*, bool) /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_connect.cc:1416
    #12 0x5564339eed2c in handle_one_connection /test/mtest/MDEV-5816/11.1_opt_san/sql/sql_connect.cc:1318
    #13 0x150b40c80608 in start_thread /build/glibc-SzIz7B/glibc-2.31/nptl/pthread_create.c:477
    #14 0x150b3fef5132 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x11f132)
 
230622  7:06:53 [ERROR] mysqld got signal 11 ;

Setup

Compiled with GCC 9.4.0

-DWITH_UBSAN=ON -DCMAKE_CXX_FLAGS=-static-libasan



 Comments   
Comment by Ramesh Sivaraman [ 2023-06-28 ]

Another test case

CREATE TEMPORARY TABLE t (c INT);
--error ER_KEY_COLUMN_DOES_NOT_EXITS
ALTER TABLE t CHANGE COLUMN c b INT,ADD INDEX (c);
--error ER_NO_SUCH_TABLE
RENAME TABLE t TO t;
SHOW TABLES;

Leads to

11.2.0 acb02f646ebbd8b100c30621b92dcc0e2e4db7b3 (Optimized)

Core was generated by `/test/mtest/MDEV-5816/MD190623-mariadb-11.2.0-linux-x86_64-opt/bin/mariadbd --n'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  get_all_tables (thd=0x14fdc0000c58, tables=0x14fdc0010ec8, 
    cond=<optimized out>)
    at /test/mtest/MDEV-5816/11.1_opt/sql/sql_show.cc:5316
5316	        restore_record(table, s->default_values);
[Current thread is 1 (Thread 0x14fe2893b700 (LWP 3768249))]
(gdb) bt
#0  get_all_tables (thd=0x14fdc0000c58, tables=0x14fdc0010ec8, cond=<optimized out>) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_show.cc:5316
#1  0x00005637793e812e in get_schema_tables_result (join=join@entry=0x14fdc0011950, executed_place=executed_place@entry=PROCESSED_BY_JOIN_EXEC) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_show.cc:9129
#2  0x00005637793cad87 in JOIN::exec_inner (this=0x14fdc0011950) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_select.cc:4889
#3  0x00005637793cb61e in JOIN::exec (this=this@entry=0x14fdc0011950) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_select.cc:4710
#4  0x00005637793c975c in mysql_select (thd=0x14fdc0000c58, tables=0x14fdc0010ec8, fields=<optimized out>, conds=0x0, og_num=0, order=0x0, group=0x0, having=0x0, proc_param=0x0, select_options=<optimized out>, result=0x14fdc0011928, unit=0x14fdc0004cf0, select_lex=0x14fdc0005528) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_select.cc:5239
#5  0x00005637793c9ea7 in handle_select (thd=thd@entry=0x14fdc0000c58, lex=lex@entry=0x14fdc0004c10, result=result@entry=0x14fdc0011928, setup_tables_done_option=setup_tables_done_option@entry=0) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_select.cc:627
#6  0x00005637793472fe in execute_sqlcom_select (thd=0x14fdc0000c58, all_tables=0x14fdc0010ec8) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_parse.cc:6030
#7  0x0000563779354c82 in mysql_execute_command (thd=0x14fdc0000c58, is_called_from_prepared_stmt=<optimized out>) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_parse.cc:3944
#8  0x0000563779342195 in mysql_parse (rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>, thd=0x14fdc0000c58) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_parse.cc:7769
#9  mysql_parse (thd=0x14fdc0000c58, rawbuf=<optimized out>, length=<optimized out>, parser_state=<optimized out>) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_parse.cc:7691
#10 0x000056377934e212 in dispatch_command (command=COM_QUERY, thd=0x14fdc0000c58, packet=<optimized out>, packet_length=<optimized out>, blocking=<optimized out>) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_class.h:1371
#11 0x000056377935010e in do_command (thd=0x14fdc0000c58, blocking=blocking@entry=true) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_parse.cc:1405
#12 0x000056377947023f in do_handle_one_connection (connect=<optimized out>, connect@entry=0x56377bae2b38, put_in_cache=put_in_cache@entry=true) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_connect.cc:1416
#13 0x000056377947052d in handle_one_connection (arg=0x56377bae2b38) at /test/mtest/MDEV-5816/11.1_opt/sql/sql_connect.cc:1318
#14 0x000014fe42da3609 in start_thread (arg=<optimized out>) at pthread_create.c:477
#15 0x000014fe4298f133 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95

Comment by Oleksandr Byelkin [ 2023-10-12 ]

The second case is somehow destroyed temporary table list by thd->close_unused_temporary_table_instances(tables); in mysql_admin of previous statement so there id NULL pointer instead of t1 in the list of temporary tables

Comment by Julien Fritsch [ 2023-12-05 ]

Automated message:
----------------------------
Since this issue has not been updated since 6 weeks, it's time to move it back to Stalled.

Comment by JiraAutomate [ 2023-12-05 ]

Automated message:
----------------------------
Since this issue has not been updated since 6 weeks, it's time to move it back to Stalled.

Comment by Oleksandr Byelkin [ 2024-01-08 ]

It is nothing to do with memory stiniser

Comment by Oleksandr Byelkin [ 2024-01-10 ]

It is not repeatable before 11.2 because SHOW TABLES do not show temporary table before 11.2

Comment by Oleksandr Byelkin [ 2024-01-10 ]

It is clash of anel patch of 0b7d1748ad3be55b50e843ee96ec6237d3d5e0cd and monty patch of c8b5fa4afc6c233101b8163ef19c1abc1be0373d . First add showing temporary tables in SHOW TABLES the second I do not understand in part of moving THD::close_unused_temporary_table_instances call.

Comment by Oleksandr Byelkin [ 2024-01-10 ]

ramesh it has nothing to do not only with UBSAN but also with prepared statements:

CREATE TEMPORARY TABLE t1 (c INT) ENGINE=MyISAM;
CREATE TEMPORARY TABLE t2 (c INT) ENGINE=MyISAM;
optimize TABLE t1,t2;
SHOW TABLES;

Comment by Oleksandr Byelkin [ 2024-01-10 ]

It looks like only OPTIMIZE TABLE affected.

There is no way to see temporary tables created by user before 11.2, so versions before 11.2 is not affected.

SELECT opens its tables in any case so it is not afected.

Comment by Oleksandr Byelkin [ 2024-01-11 ]

commit f807a9f874a8079d95bc71c9f27216e4d952f157 (HEAD -> bb-10.4-MDEV-31523, origin/bb-10.4-MDEV-31523)
Author: Oleksandr Byelkin <sanja@mariadb.com>
Date:   Thu Jan 11 11:21:32 2024 +0100
 
    MDEV-31523 Using two temporary tables in OPTIMIZE TABLE lead to crash
    
    Fixed typo in mysql_admin_table which cused call of
    close_unused_temporary_table_instances alwas for the first table
    instead of the current table.
    
    Added ASSERT that close_unused_temporary_table_instances should not
    remove all instances of user created temporary table.

Comment by Sergei Golubchik [ 2024-01-11 ]

f807a9f874a is ok to push

Generated at Thu Feb 08 10:24:31 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.