Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-34076

Spider: heap-use-after-free in my_convert on SELECT

Details

    Description

      INSTALL PLUGIN Spider SONAME 'ha_spider.so';
      CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET '../socket.sock',DATABASE 'test',user 'Spider',PASSWORD'');
      CREATE TABLE t1 (c1 INT KEY,c3 TEXT) ENGINE=InnoDB;
      CREATE TABLE t2 (c1 INT KEY,c3 TEXT) ENGINE=Spider COMMENT='WRAPPER "mysql",SRV "srv",TABLE "t1"';
      INSERT INTO t1 VALUES (0,'a');
      SELECT * FROM t2 WHERE c1=0;
      

      Leads to:

      11.5.0 3f9182126c64bcec359bebe9ebad2a0e559b13e2 (Optimized, UBASAN)

      ==3127594==ERROR: AddressSanitizer: heap-use-after-free on address 0x608000018e62 at pc 0x558b38b1ab5c bp 0x1535b1662b20 sp 0x1535b1662b10
      READ of size 1 at 0x608000018e62 thread T10
          #0 0x558b38b1ab5b in my_convert /test/11.5_opt_san/strings/ctype.c:1267
          #1 0x558b34402233 in copy_and_convert(char*, unsigned long, charset_info_st const*, char const*, unsigned long, charset_info_st const*, unsigned int*) /test/11.5_opt_san/sql/sql_string.h:53
          #2 0x558b34402233 in Protocol::net_store_data_cs(unsigned char const*, unsigned long, charset_info_st const*, charset_info_st const*) /test/11.5_opt_san/sql/protocol.cc:118
          #3 0x558b3602c6bc in Protocol::store(char const*, unsigned long, charset_info_st const*) /test/11.5_opt_san/sql/protocol.h:157
          #4 0x558b3602c6bc in Field_longstr::send(Protocol*) /test/11.5_opt_san/sql/field.cc:7379
          #5 0x558b34408351 in Protocol_text::store(Field*) /test/11.5_opt_san/sql/protocol.cc:1643
          #6 0x558b34413271 in Protocol::send_result_set_row(List<Item>*) /test/11.5_opt_san/sql/protocol.cc:1359
          #7 0x558b3473b15d in select_send::send_data(List<Item>&) /test/11.5_opt_san/sql/sql_class.cc:3189
          #8 0x558b35057848 in select_result_sink::send_data_with_check(List<Item>&, st_select_lex_unit*, unsigned long long) /test/11.5_opt_san/sql/sql_class.h:6090
          #9 0x558b35057848 in select_result_sink::send_data_with_check(List<Item>&, st_select_lex_unit*, unsigned long long) /test/11.5_opt_san/sql/sql_class.h:6080
          #10 0x558b35057848 in Pushdown_query::execute(JOIN*) /test/11.5_opt_san/sql/group_by_handler.cc:100
          #11 0x558b34f3a0d5 in do_select /test/11.5_opt_san/sql/sql_select.cc:23000
          #12 0x558b34f3a0d5 in JOIN::exec_inner() /test/11.5_opt_san/sql/sql_select.cc:4988
          #13 0x558b34f3ff16 in JOIN::exec() /test/11.5_opt_san/sql/sql_select.cc:4774
          #14 0x558b34f2da26 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/11.5_opt_san/sql/sql_select.cc:5304
          #15 0x558b34f316ca in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.5_opt_san/sql/sql_select.cc:630
          #16 0x558b34a968ae in execute_sqlcom_select /test/11.5_opt_san/sql/sql_parse.cc:6093
          #17 0x558b34afb9bc in mysql_execute_command(THD*, bool) /test/11.5_opt_san/sql/sql_parse.cc:3942
          #18 0x558b34b0aaed in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.5_opt_san/sql/sql_parse.cc:7815
          #19 0x558b34b18519 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.5_opt_san/sql/sql_parse.cc:1892
          #20 0x558b34b22ce3 in do_command(THD*, bool) /test/11.5_opt_san/sql/sql_parse.cc:1405
          #21 0x558b354b4887 in do_handle_one_connection(CONNECT*, bool) /test/11.5_opt_san/sql/sql_connect.cc:1445
          #22 0x558b354b727c in handle_one_connection /test/11.5_opt_san/sql/sql_connect.cc:1347
          #23 0x1535d2c8f189 in start_thread nptl/pthread_create.c:444
          #24 0x1535d2d1dbcf in clone3 ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
       
      0x608000018e62 is located 66 bytes inside of 88-byte region [0x608000018e20,0x608000018e78)
      freed by thread T10 here:
          #0 0x558b3420aaa0 in __interceptor_free.part.0 (/test/UBASAN_MD240424-mariadb-11.5.0-linux-x86_64-opt/bin/mariadbd+0x7f71aa0)
          #1 0x1535b0200010 in spider_free_mem(st_spider_transaction*, void*, unsigned long) /test/11.5_opt_san/storage/spider/spd_malloc.cc:183
          #2 0x1535b031fb5f in spider_db_mbase_row::~spider_db_mbase_row() /test/11.5_opt_san/storage/spider/spd_db_mysql.cc:377
          #3 0x1535b031fca4 in spider_db_mbase_row::~spider_db_mbase_row() /test/11.5_opt_san/storage/spider/spd_db_mysql.cc:380
          #4 0x1535b008993a in spider_db_free_one_result(st_spider_result_list*, st_spider_result*) /test/11.5_opt_san/storage/spider/spd_db_conn.cc:2803
          #5 0x1535b008a5e2 in spider_db_free_one_result_for_start_next(ha_spider*) /test/11.5_opt_san/storage/spider/spd_db_conn.cc:2751
          #6 0x1535b040ca6c in spider_prepare_init_scan /test/11.5_opt_san/storage/spider/spd_group_by_handler.cc:1028
          #7 0x1535b040ca6c in spider_group_by_handler::init_scan() /test/11.5_opt_san/storage/spider/spd_group_by_handler.cc:1288
          #8 0x558b3505688f in Pushdown_query::execute(JOIN*) /test/11.5_opt_san/sql/group_by_handler.cc:49
          #9 0x558b34f3a0d5 in do_select /test/11.5_opt_san/sql/sql_select.cc:23000
          #10 0x558b34f3a0d5 in JOIN::exec_inner() /test/11.5_opt_san/sql/sql_select.cc:4988
          #11 0x558b34f3ff16 in JOIN::exec() /test/11.5_opt_san/sql/sql_select.cc:4774
          #12 0x558b34f2da26 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/11.5_opt_san/sql/sql_select.cc:5304
          #13 0x558b34f316ca in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.5_opt_san/sql/sql_select.cc:630
          #14 0x558b34a968ae in execute_sqlcom_select /test/11.5_opt_san/sql/sql_parse.cc:6093
          #15 0x558b34afb9bc in mysql_execute_command(THD*, bool) /test/11.5_opt_san/sql/sql_parse.cc:3942
          #16 0x558b34b0aaed in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.5_opt_san/sql/sql_parse.cc:7815
          #17 0x558b34b18519 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.5_opt_san/sql/sql_parse.cc:1892
          #18 0x558b34b22ce3 in do_command(THD*, bool) /test/11.5_opt_san/sql/sql_parse.cc:1405
          #19 0x558b354b4887 in do_handle_one_connection(CONNECT*, bool) /test/11.5_opt_san/sql/sql_connect.cc:1445
          #20 0x558b354b727c in handle_one_connection /test/11.5_opt_san/sql/sql_connect.cc:1347
          #21 0x1535d2c8f189 in start_thread nptl/pthread_create.c:444
       
      previously allocated by thread T10 here:
          #0 0x558b3420bf4f in malloc (/test/UBASAN_MD240424-mariadb-11.5.0-linux-x86_64-opt/bin/mariadbd+0x7f72f4f)
          #1 0x558b38894315 in my_malloc /test/11.5_opt_san/mysys/my_malloc.c:93
          #2 0x1535b0200434 in spider_bulk_alloc_mem(st_spider_transaction*, unsigned int, char const*, char const*, unsigned long, unsigned long, ...) /test/11.5_opt_san/storage/spider/spd_malloc.cc:231
          #3 0x1535b035db6d in spider_db_mbase_row::clone() /test/11.5_opt_san/storage/spider/spd_db_mysql.cc:547
          #4 0x1535b0091ec9 in spider_db_store_result(ha_spider*, int, TABLE*) /test/11.5_opt_san/storage/spider/spd_db_conn.cc:3398
          #5 0x1535b026f3fd in ha_spider::index_read_map_internal(unsigned char*, unsigned char const*, unsigned long, ha_rkey_function) /test/11.5_opt_san/storage/spider/ha_spider.cc:1515
          #6 0x558b36143c50 in handler::index_read_idx_map(unsigned char*, unsigned int, unsigned char const*, unsigned long, ha_rkey_function) /test/11.5_opt_san/sql/handler.cc:7082
          #7 0x558b3617f657 in handler::ha_index_read_idx_map(unsigned char*, unsigned int, unsigned char const*, unsigned long, ha_rkey_function) /test/11.5_opt_san/sql/handler.cc:3718
          #8 0x558b34e13137 in join_read_const /test/11.5_opt_san/sql/sql_select.cc:24195
          #9 0x558b34e14168 in join_read_const_table /test/11.5_opt_san/sql/sql_select.cc:24065
          #10 0x558b34ef2c06 in make_join_statistics /test/11.5_opt_san/sql/sql_select.cc:5968
          #11 0x558b34f2675c in JOIN::optimize_inner() /test/11.5_opt_san/sql/sql_select.cc:2657
          #12 0x558b34f2ce89 in JOIN::optimize() /test/11.5_opt_san/sql/sql_select.cc:1966
          #13 0x558b34f2d75a 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/11.5_opt_san/sql/sql_select.cc:5290
          #14 0x558b34f316ca in handle_select(THD*, LEX*, select_result*, unsigned long long) /test/11.5_opt_san/sql/sql_select.cc:630
          #15 0x558b34a968ae in execute_sqlcom_select /test/11.5_opt_san/sql/sql_parse.cc:6093
          #16 0x558b34afb9bc in mysql_execute_command(THD*, bool) /test/11.5_opt_san/sql/sql_parse.cc:3942
          #17 0x558b34b0aaed in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/11.5_opt_san/sql/sql_parse.cc:7815
          #18 0x558b34b18519 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/11.5_opt_san/sql/sql_parse.cc:1892
          #19 0x558b34b22ce3 in do_command(THD*, bool) /test/11.5_opt_san/sql/sql_parse.cc:1405
          #20 0x558b354b4887 in do_handle_one_connection(CONNECT*, bool) /test/11.5_opt_san/sql/sql_connect.cc:1445
          #21 0x558b354b727c in handle_one_connection /test/11.5_opt_san/sql/sql_connect.cc:1347
          #22 0x1535d2c8f189 in start_thread nptl/pthread_create.c:444
       
      Thread T10 created by T0 here:
          #0 0x558b341975d5 in __interceptor_pthread_create (/test/UBASAN_MD240424-mariadb-11.5.0-linux-x86_64-opt/bin/mariadbd+0x7efe5d5)
          #1 0x558b3426b59d in create_thread_to_handle_connection(CONNECT*) /test/11.5_opt_san/sql/mysqld.cc:6079
          #2 0x558b3427e8cb in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /test/11.5_opt_san/sql/mysqld.cc:6203
          #3 0x558b3427f96f in handle_connections_sockets() /test/11.5_opt_san/sql/mysqld.cc:6316
          #4 0x558b34282b78 in mysqld_main(int, char**) /test/11.5_opt_san/sql/mysqld.cc:5974
          #5 0x1535d2c23a8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
       
      SUMMARY: AddressSanitizer: heap-use-after-free /test/11.5_opt_san/strings/ctype.c:1267 in my_convert
      Shadow bytes around the buggy address:
        0x0c107fffb170: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c107fffb180: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c107fffb190: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c107fffb1a0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c107fffb1b0: fa fa fa fa 00 00 00 00 00 00 00 00 00 00 00 fa
      =>0x0c107fffb1c0: fa fa fa fa fd fd fd fd fd fd fd fd[fd]fd fd fa
        0x0c107fffb1d0: fa fa fa fa fd fd fd fd fd fd fd fd fd fd fd fa
        0x0c107fffb1e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c107fffb1f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c107fffb200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c107fffb210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      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
      ==3127594==ABORTING
      240504 11:04:54 [ERROR] mysqld got signal 6 ;
      

      All UniqueID's/stacks seen across versions and build types:

      ASAN|heap-use-after-free|strings/ctype.c|my_convert|copy_and_convert|Protocol::net_store_data_cs|Protocol::store
      ASAN|heap-use-after-free|strings/ctype.c|my_convert|copy_and_convert|Protocol::net_store_data_cs|Protocol::store_string_aux
      

      Attachments

        Issue Links

          Activity

            Roel Roel Van de Paar added a comment - - edited

            When converting this to an MTR testcase, it results in the same crash as MDEV-34003, however that bug is a heap-use-after-free in sql/protocol.cc whereas this one is in strings/ctype.c. They are likely related.

            --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 srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$SOCKET",DATABASE 'test',USER 'spider',PASSWORD 'pwd');
            SET spider_same_server_link=1;
            CREATE TABLE t1 (c1 INT KEY,c3 TEXT) ENGINE=InnoDB;
            CREATE TABLE t2 (c1 INT KEY,c3 TEXT) ENGINE=Spider COMMENT='WRAPPER "mysql",SRV "srv",TABLE "t1"';
            INSERT INTO t1 VALUES (0,'a');
            SELECT * FROM t2 WHERE c1=0;
            

            I thus recommend replaying not this MTR testcase but the original testcase at the CLI to generate the different ASAN stack.
            BTW, the shadow byte map also looks significantly different.

            Roel Roel Van de Paar added a comment - - edited When converting this to an MTR testcase, it results in the same crash as MDEV-34003 , however that bug is a heap-use-after-free in sql/protocol.cc whereas this one is in strings/ctype.c. They are likely related. --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 srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$SOCKET" , DATABASE 'test' , USER 'spider' , PASSWORD 'pwd' ); SET spider_same_server_link=1; CREATE TABLE t1 (c1 INT KEY ,c3 TEXT) ENGINE=InnoDB; CREATE TABLE t2 (c1 INT KEY ,c3 TEXT) ENGINE=Spider COMMENT= 'WRAPPER "mysql",SRV "srv",TABLE "t1"' ; INSERT INTO t1 VALUES (0, 'a' ); SELECT * FROM t2 WHERE c1=0; I thus recommend replaying not this MTR testcase but the original testcase at the CLI to generate the different ASAN stack. BTW, the shadow byte map also looks significantly different.
            ycp Yuchen Pei added a comment - - edited

            Like MDEV-34003, the similarly looking mtr testcase is fixed by the patch for MDEV-33742:

            --disable_query_log
            --disable_result_log
            --source ../../t/test_init.inc
            --enable_result_log
            --enable_query_log
            set spider_same_server_link= 1;
            evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
            OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
            CREATE TABLE t1 (c1 INT KEY,c3 TEXT) ENGINE=InnoDB;
            CREATE TABLE t2 (c1 INT KEY,c3 TEXT) ENGINE=Spider COMMENT='WRAPPER "mysql",SRV "srv",TABLE "t1"';
            INSERT INTO t1 VALUES (0,'a');
            SELECT * FROM t2 WHERE c1=0;
            drop table t1, t2;
            drop server srv;
            --disable_query_log
            --disable_result_log
            --source ../../t/test_deinit.inc
            --enable_result_log
            --enable_query_log
            

            I can also confirm that the case when tested in cli is also fixed by MDEV-33742, so I'm closing this ticket as a duplicate.

            Also, given the similarity between the test of this ticket and that of MDEV-34003, there's no need to add the test to the codebase.

            ycp Yuchen Pei added a comment - - edited Like MDEV-34003 , the similarly looking mtr testcase is fixed by the patch for MDEV-33742 : --disable_query_log --disable_result_log --source ../../t/test_init.inc --enable_result_log --enable_query_log set spider_same_server_link= 1; evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql OPTIONS (SOCKET "$MASTER_1_MYSOCK" , DATABASE 'test' , user 'root' ); CREATE TABLE t1 (c1 INT KEY ,c3 TEXT) ENGINE=InnoDB; CREATE TABLE t2 (c1 INT KEY ,c3 TEXT) ENGINE=Spider COMMENT= 'WRAPPER "mysql",SRV "srv",TABLE "t1"' ; INSERT INTO t1 VALUES (0, 'a' ); SELECT * FROM t2 WHERE c1=0; drop table t1, t2; drop server srv; --disable_query_log --disable_result_log --source ../../t/test_deinit.inc --enable_result_log --enable_query_log I can also confirm that the case when tested in cli is also fixed by MDEV-33742 , so I'm closing this ticket as a duplicate. Also, given the similarity between the test of this ticket and that of MDEV-34003 , there's no need to add the test to the codebase.

            Great to hear, thank you

            Roel Roel Van de Paar added a comment - Great to hear, thank you

            People

              ycp Yuchen Pei
              Roel Roel Van de Paar
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Git Integration

                  Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.