[MDEV-31357] ASAN heap-use-after-free in spider_link_get_key on LOCK TABLES Created: 2023-05-27  Updated: 2023-11-22  Resolved: 2023-11-17

Status: Closed
Project: MariaDB Server
Component/s: Locking, Storage Engine - Spider
Affects Version/s: 10.4, 10.5, 10.6, 10.9, 10.10, 10.11, 11.0, 11.1
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: Major
Reporter: Roel Van de Paar Assignee: Yuchen Pei
Resolution: Fixed Votes: 0
Labels: ASAN, memory_corruption

Issue Links:
Blocks
is blocked by MDEV-29963 SIGSEGV in spider_db_mbase::append_lo... Closed
Duplicate
is duplicated by MDEV-29854 SIGSEGV in spider_string::length on ... Closed
PartOf
is part of MDEV-29963 SIGSEGV in spider_db_mbase::append_lo... Closed

 Description   

INSTALL PLUGIN Spider SONAME 'ha_spider.so';
CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET'',DATABASE'',USER'',PASSWORD'');
CREATE TABLE t1 (c INT) ENGINE=Spider;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT="WRAPPER 'mysql',srv 's',TABLE 't1'";
LOCK TABLES t1 WRITE,t2 WRITE;
TRUNCATE t2;
LOCK TABLES t2 AS o WRITE;

Leads to:

11.0.2 368dd22a816f3b437bccd0b9ff28b9de9b1abf0a (Debug)

==675445==ERROR: AddressSanitizer: heap-use-after-free on address 0x6070000165c8 at pc 0x1482e898ad97 bp 0x1482e9586040 sp 0x1482e9586030
READ of size 8 at 0x6070000165c8 thread T12
    #0 0x1482e898ad96 in spider_link_get_key(st_spider_link_for_hash*, unsigned long*, char) /test/11.0_dbg_san/storage/spider/spd_table.cc:406
    #1 0x56101d0357eb in my_hash_key /test/11.0_dbg_san/mysys/hash.c:197
    #2 0x56101d0357eb in hashcmp /test/11.0_dbg_san/mysys/hash.c:380
    #3 0x56101d03640e in my_hash_first_from_hash_value /test/11.0_dbg_san/mysys/hash.c:291
    #4 0x56101d0365c2 in my_hash_search_using_hash_value /test/11.0_dbg_san/mysys/hash.c:245
    #5 0x1482e8bb1f4d in spider_mbase_handler::append_lock_tables_list(st_spider_conn*, int, int*) /test/11.0_dbg_san/storage/spider/spd_db_mysql.cc:13050
    #6 0x1482e8b2eb9d in ha_spider::append_lock_tables_list() /test/11.0_dbg_san/storage/spider/ha_spider.cc:12024
    #7 0x1482e8b32395 in ha_spider::store_lock(THD*, st_thr_lock_data**, thr_lock_type) /test/11.0_dbg_san/storage/spider/ha_spider.cc:759
    #8 0x56101b829d08 in get_lock_data(THD*, TABLE**, unsigned int, unsigned int) /test/11.0_dbg_san/sql/lock.cc:826
    #9 0x56101b82b36a in mysql_lock_tables(THD*, TABLE**, unsigned int, unsigned int) /test/11.0_dbg_san/sql/lock.cc:301
    #10 0x561018e911de in lock_tables(THD*, TABLE_LIST*, unsigned int, unsigned int) /test/11.0_dbg_san/sql/sql_base.cc:5819
    #11 0x5610192782d2 in lock_tables_open_and_lock_tables /test/11.0_dbg_san/sql/sql_parse.cc:2961
    #12 0x5610192f1e17 in mysql_execute_command(THD*, bool) /test/11.0_dbg_san/sql/sql_parse.cc:5142
    #13 0x5610192f5973 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.0_dbg_san/sql/sql_parse.cc:8014
    #14 0x561019305707 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.0_dbg_san/sql/sql_parse.cc:1894
    #15 0x561019313542 in do_command(THD*, bool) /test/11.0_dbg_san/sql/sql_parse.cc:1407
    #16 0x561019ce88b5 in do_handle_one_connection(CONNECT*, bool) /test/11.0_dbg_san/sql/sql_connect.cc:1416
    #17 0x561019ce9dd0 in handle_one_connection /test/11.0_dbg_san/sql/sql_connect.cc:1318
    #18 0x14830b694b42 in start_thread nptl/pthread_create.c:442
    #19 0x14830b7269ff  (/lib/x86_64-linux-gnu/libc.so.6+0x1269ff)
 
0x6070000165c8 is located 56 bytes inside of 80-byte region [0x607000016590,0x6070000165e0)
freed by thread T12 here:
    #0 0x561018979fe7 in __interceptor_free (/test/UBASAN_MD120523-mariadb-11.0.2-linux-x86_64-dbg/bin/mariadbd+0x7963fe7)
    #1 0x56101d091a61 in my_free /test/11.0_dbg_san/mysys/my_malloc.c:213
    #2 0x1482e8a52150 in spider_free_mem(st_spider_transaction*, void*, unsigned long) /test/11.0_dbg_san/storage/spider/spd_malloc.cc:183
    #3 0x1482e8bc4299 in spider_mbase_handler::~spider_mbase_handler() /test/11.0_dbg_san/storage/spider/spd_db_mysql.cc:8529
    #4 0x1482e8bc4dce in spider_mysql_handler::~spider_mysql_handler() /test/11.0_dbg_san/storage/spider/spd_db_mysql.cc:8540
    #5 0x1482e8bc4e46 in spider_mysql_handler::~spider_mysql_handler() /test/11.0_dbg_san/storage/spider/spd_db_mysql.cc:8540
    #6 0x1482e8a9ac5b in ha_spider::close() /test/11.0_dbg_san/storage/spider/ha_spider.cc:516
    #7 0x56101a9e585b in handler::ha_close() /test/11.0_dbg_san/sql/handler.cc:3571
    #8 0x561019aef686 in closefrm(TABLE*) /test/11.0_dbg_san/sql/table.cc:4644
    #9 0x56101a40834c in intern_close_table /test/11.0_dbg_san/sql/table_cache.cc:225
    #10 0x56101a40d1b6 in TDC_element::flush_unused(bool) /test/11.0_dbg_san/sql/table_cache.cc:1298
    #11 0x56101a40d48a in tdc_remove_referenced_share(THD*, TABLE_SHARE*) /test/11.0_dbg_san/sql/table_cache.cc:1009
    #12 0x561019e1ae2b in Sql_cmd_truncate_table::lock_table(THD*, TABLE_LIST*, bool*) /test/11.0_dbg_san/sql/sql_truncate.cc:372
    #13 0x561019e1b6aa in Sql_cmd_truncate_table::truncate_table(THD*, TABLE_LIST*) /test/11.0_dbg_san/sql/sql_truncate.cc:482
    #14 0x561019e1cf3e in Sql_cmd_truncate_table::execute(THD*) /test/11.0_dbg_san/sql/sql_truncate.cc:573
    #15 0x5610192ec054 in mysql_execute_command(THD*, bool) /test/11.0_dbg_san/sql/sql_parse.cc:6015
    #16 0x5610192f5973 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.0_dbg_san/sql/sql_parse.cc:8014
    #17 0x561019305707 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.0_dbg_san/sql/sql_parse.cc:1894
    #18 0x561019313542 in do_command(THD*, bool) /test/11.0_dbg_san/sql/sql_parse.cc:1407
    #19 0x561019ce88b5 in do_handle_one_connection(CONNECT*, bool) /test/11.0_dbg_san/sql/sql_connect.cc:1416
    #20 0x561019ce9dd0 in handle_one_connection /test/11.0_dbg_san/sql/sql_connect.cc:1318
    #21 0x14830b694b42 in start_thread nptl/pthread_create.c:442
 
previously allocated by thread T12 here:
    #0 0x56101897a337 in __interceptor_malloc (/test/UBASAN_MD120523-mariadb-11.0.2-linux-x86_64-dbg/bin/mariadbd+0x7964337)
    #1 0x56101d091703 in my_malloc /test/11.0_dbg_san/mysys/my_malloc.c:91
    #2 0x1482e8a52583 in spider_bulk_alloc_mem(st_spider_transaction*, unsigned int, char const*, char const*, unsigned long, unsigned long, ...) /test/11.0_dbg_san/storage/spider/spd_malloc.cc:231
    #3 0x1482e8b785f6 in spider_mbase_handler::init() /test/11.0_dbg_san/storage/spider/spd_db_mysql.cc:8586
    #4 0x1482e8996d3a in spider_share_init_spider_dbton_handlers(ha_spider*, st_spider_share*) /test/11.0_dbg_san/storage/spider/spd_table.cc:4835
    #5 0x1482e8a04fec in spider_init_share(char const*, TABLE*, THD*, ha_spider*, int*, st_spider_share*, TABLE_SHARE*, bool) /test/11.0_dbg_san/storage/spider/spd_table.cc:5131
    #6 0x1482e8a06475 in spider_get_share(char const*, TABLE*, THD*, ha_spider*, int*) /test/11.0_dbg_san/storage/spider/spd_table.cc:5252
    #7 0x1482e8b05021 in ha_spider::open(char const*, int, unsigned int) /test/11.0_dbg_san/storage/spider/ha_spider.cc:312
    #8 0x56101a9e6235 in handler::ha_open(TABLE*, char const*, int, unsigned int, st_mem_root*, List<String>*) /test/11.0_dbg_san/sql/handler.cc:3487
    #9 0x561019b2f885 in open_table_from_share(THD*, TABLE_SHARE*, st_mysql_const_lex_string const*, unsigned int, unsigned int, unsigned int, TABLE*, bool, List<String>*) /test/11.0_dbg_san/sql/table.cc:4540
    #10 0x561018e7e3e3 in open_table(THD*, TABLE_LIST*, Open_table_context*) /test/11.0_dbg_san/sql/sql_base.cc:2178
    #11 0x561018e95f14 in open_and_process_table /test/11.0_dbg_san/sql/sql_base.cc:4108
    #12 0x561018e95f14 in open_tables(THD*, DDL_options_st const&, TABLE_LIST**, unsigned int*, unsigned int, Prelocking_strategy*) /test/11.0_dbg_san/sql/sql_base.cc:4595
    #13 0x56101927804c in open_tables /test/11.0_dbg_san/sql/sql_base.h:266
    #14 0x56101927804c in lock_tables_open_and_lock_tables /test/11.0_dbg_san/sql/sql_parse.cc:2865
    #15 0x5610192f1e17 in mysql_execute_command(THD*, bool) /test/11.0_dbg_san/sql/sql_parse.cc:5142
    #16 0x5610192f5973 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.0_dbg_san/sql/sql_parse.cc:8014
    #17 0x561019305707 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.0_dbg_san/sql/sql_parse.cc:1894
    #18 0x561019313542 in do_command(THD*, bool) /test/11.0_dbg_san/sql/sql_parse.cc:1407
    #19 0x561019ce88b5 in do_handle_one_connection(CONNECT*, bool) /test/11.0_dbg_san/sql/sql_connect.cc:1416
    #20 0x561019ce9dd0 in handle_one_connection /test/11.0_dbg_san/sql/sql_connect.cc:1318
    #21 0x14830b694b42 in start_thread nptl/pthread_create.c:442
 
Thread T12 created by T0 here:
    #0 0x56101891e175 in pthread_create (/test/UBASAN_MD120523-mariadb-11.0.2-linux-x86_64-dbg/bin/mariadbd+0x7908175)
    #1 0x5610189d498b in create_thread_to_handle_connection(CONNECT*) /test/11.0_dbg_san/sql/mysqld.cc:6129
    #2 0x5610189e1e67 in create_new_thread(CONNECT*) /test/11.0_dbg_san/sql/mysqld.cc:6191
    #3 0x5610189e26e7 in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /test/11.0_dbg_san/sql/mysqld.cc:6253
    #4 0x5610189e3738 in handle_connections_sockets() /test/11.0_dbg_san/sql/mysqld.cc:6377
    #5 0x5610189eaee7 in mysqld_main(int, char**) /test/11.0_dbg_san/sql/mysqld.cc:6024
    #6 0x5610189bfeca in main /test/11.0_dbg_san/sql/main.cc:34
    #7 0x14830b629d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
 
SUMMARY: AddressSanitizer: heap-use-after-free /test/11.0_dbg_san/storage/spider/spd_table.cc:406 in spider_link_get_key(st_spider_link_for_hash*, unsigned long*, char)
Shadow bytes around the buggy address:
  0x0c0e7fffac60: 00 00 00 00 00 00 00 00 fa fa fa fa 00 00 00 00
  0x0c0e7fffac70: 00 00 00 00 00 00 fa fa fa fa 00 00 00 00 00 00
  0x0c0e7fffac80: 00 00 00 00 fa fa fa fa 00 00 00 00 00 00 00 00
  0x0c0e7fffac90: 00 00 fa fa fa fa fd fd fd fd fd fd fd fd fd fd
  0x0c0e7fffaca0: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fa fa
=>0x0c0e7fffacb0: fa fa fd fd fd fd fd fd fd[fd]fd fd fa fa fa fa
  0x0c0e7fffacc0: fd fd fd fd fd fd fd fd fd fd fa fa fa fa fd fd
  0x0c0e7fffacd0: fd fd fd fd fd fd fd fd fa fa fa fa fd fd fd fd
  0x0c0e7ffface0: fd fd fd fd fd fa fa fa fa fa fd fd fd fd fd fd
  0x0c0e7fffacf0: fd fd fd fd fa fa fa fa fd fd fd fd fd fd fd fd
  0x0c0e7fffad00: fd fd fa fa fa fa fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==675445==ABORTING
230527 16:51:01 [ERROR] mysqld got signal 6 ;

Setup:

Compiled with GCC >=7.5.0 (I use GCC 11.3.0) and:
    -DWITH_ASAN=ON -DWITH_ASAN_SCOPE=ON -DWITH_UBSAN=ON -DWITH_RAPID=OFF -DWSREP_LIB_WITH_ASAN=ON
Set before execution:
    export ASAN_OPTIONS=quarantine_size_mb=512:atexit=0:detect_invalid_pointer_pairs=3:dump_instruction_bytes=1:abort_on_error=1:allocator_may_return_null=1

Bug confirmed present in:
MariaDB: 10.4.30 (dbg), 10.4.30 (opt), 10.5.21 (dbg), 10.5.21 (opt), 10.6.14 (dbg), 10.6.14 (opt), 10.9.7 (dbg), 10.9.7 (opt), 10.10.5 (dbg), 10.10.5 (opt), 10.11.4 (dbg), 10.11.4 (opt), 11.0.2 (dbg), 11.0.2 (opt), 11.1.0 (dbg), 11.1.0 (opt)



 Comments   
Comment by Roel Van de Paar [ 2023-05-27 ]

MTR testcase:

IF (`SELECT NOT(COUNT(*)) FROM information_schema.system_variables WHERE variable_name='have_sanitizer' AND global_value like "%UBSAN%"`)
{
--skip test needs to be run with UBSAN
}
--source include/have_innodb.inc
--let $SOCKET= `SELECT @@global.socket`
INSTALL PLUGIN Spider SONAME 'ha_spider.so';
CREATE USER spider@localhost IDENTIFIED BY 'pwd';
GRANT ALL ON test.* TO spider@localhost;
eval CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$SOCKET",DATABASE 'test',USER 'spider',PASSWORD 'pwd');
CREATE TABLE t1 (c INT) ENGINE=Spider;
CREATE TABLE t2 (c INT) ENGINE=Spider COMMENT="WRAPPER 'mysql',srv 's',TABLE 't1'";
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
LOCK TABLES t1 WRITE,t2 WRITE;
--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE
TRUNCATE t2;
LOCK TABLES t2 AS o WRITE;

Comment by Roel Van de Paar [ 2023-05-27 ]

Accross versions and builds, a single UniqueID/stack is observed:

ASAN|heap-use-after-free|storage/spider/spd_table.cc|spider_link_get_key|my_hash_key|hashcmp|my_hash_first_from_hash_value

Comment by Yuchen Pei [ 2023-11-17 ]

fixed by MDEV-29963

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