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

Unexpected results or ASAN use-after-poison in Field::cmp_binary or in row_sel_store_mysql_field_func upon updating virtual column

    XMLWordPrintable

    Details

      Description

      With MyISAM

      CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b VARBINARY(8), c TINYINT AS (a)) ENGINE=MyISAM;
      INSERT INTO t1 (id,a) VALUES (1,242);
      --error ER_WARN_DATA_OUT_OF_RANGE
      REPLACE INTO t1 (id) VALUES (1);
      UPDATE t1 SET a = 1;
       
      # Cleanup
      DROP TABLE t1;
      

      10.2 29d9897f ASAN

      ==1592797==ERROR: AddressSanitizer: use-after-poison on address 0x619000088555 at pc 0x7fb9d2f05dfd bp 0x7fb9c7c7fec0 sp 0x7fb9c7c7f668
      READ of size 4 at 0x619000088555 thread T5
          #0 0x7fb9d2f05dfc  (/lib/x86_64-linux-gnu/libasan.so.5+0xdadfc)
          #1 0x558e7fcf9037 in Field::cmp_binary(unsigned char const*, unsigned char const*, unsigned int) /data/src/10.2/sql/field.h:1066
          #2 0x558e7fcf9195 in Field::cmp_binary_offset(unsigned int) /data/src/10.2/sql/field.h:1070
          #3 0x558e7fe130a5 in compare_record(TABLE const*) /data/src/10.2/sql/sql_update.cc:116
          #4 0x558e7fe1837c in mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, enum_duplicates, bool, unsigned long long*, unsigned long long*) /data/src/10.2/sql/sql_update.cc:768
          #5 0x558e7fb95d69 in mysql_execute_command(THD*) /data/src/10.2/sql/sql_parse.cc:4033
          #6 0x558e7fbaf7eb in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.2/sql/sql_parse.cc:7763
          #7 0x558e7fb88830 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.2/sql/sql_parse.cc:1827
          #8 0x558e7fb855ef in do_command(THD*) /data/src/10.2/sql/sql_parse.cc:1381
          #9 0x558e7ff0db1e in do_handle_one_connection(CONNECT*) /data/src/10.2/sql/sql_connect.cc:1336
          #10 0x558e7ff0d3e1 in handle_one_connection /data/src/10.2/sql/sql_connect.cc:1241
          #11 0x558e812a95d9 in pfs_spawn_thread /data/src/10.2/storage/perfschema/pfs.cc:1869
          #12 0x7fb9d29d1608 in start_thread /build/glibc-ZN95T4/glibc-2.31/nptl/pthread_create.c:477
          #13 0x7fb9d25ab292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)
       
      0x619000088555 is located 213 bytes inside of 1100-byte region [0x619000088480,0x6190000888cc)
      allocated by thread T5 here:
          #0 0x7fb9d2f38bc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
          #1 0x558e813c612c in sf_malloc /data/src/10.2/mysys/safemalloc.c:118
          #2 0x558e81392091 in my_malloc /data/src/10.2/mysys/my_malloc.c:101
          #3 0x558e8136f703 in alloc_root /data/src/10.2/mysys/my_alloc.c:243
          #4 0x558e8137109c in strmake_root /data/src/10.2/mysys/my_alloc.c:451
          #5 0x558e7fe53ff3 in open_table_from_share(THD*, TABLE_SHARE*, char const*, unsigned int, unsigned int, unsigned int, TABLE*, bool) /data/src/10.2/sql/table.cc:3097
          #6 0x558e7fa6a3b9 in open_table(THD*, TABLE_LIST*, Open_table_context*) /data/src/10.2/sql/sql_base.cc:1934
          #7 0x558e7fa72344 in open_and_process_table /data/src/10.2/sql/sql_base.cc:3614
          #8 0x558e7fa7471e in open_tables(THD*, DDL_options_st const&, TABLE_LIST**, unsigned int*, unsigned int, Prelocking_strategy*) /data/src/10.2/sql/sql_base.cc:4081
          #9 0x558e7fa782a4 in open_and_lock_tables(THD*, DDL_options_st const&, TABLE_LIST*, bool, unsigned int, Prelocking_strategy*) /data/src/10.2/sql/sql_base.cc:4880
          #10 0x558e7f9ef46d in open_and_lock_tables(THD*, TABLE_LIST*, bool, unsigned int) /data/src/10.2/sql/sql_base.h:507
          #11 0x558e7fb2e15d in mysql_insert(THD*, TABLE_LIST*, List<Item>&, List<List<Item> >&, List<Item>&, List<Item>&, enum_duplicates, bool) /data/src/10.2/sql/sql_insert.cc:758
          #12 0x558e7fb96b91 in mysql_execute_command(THD*) /data/src/10.2/sql/sql_parse.cc:4194
          #13 0x558e7fbaf7eb in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.2/sql/sql_parse.cc:7763
          #14 0x558e7fb88830 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.2/sql/sql_parse.cc:1827
          #15 0x558e7fb855ef in do_command(THD*) /data/src/10.2/sql/sql_parse.cc:1381
          #16 0x558e7ff0db1e in do_handle_one_connection(CONNECT*) /data/src/10.2/sql/sql_connect.cc:1336
          #17 0x558e7ff0d3e1 in handle_one_connection /data/src/10.2/sql/sql_connect.cc:1241
          #18 0x558e812a95d9 in pfs_spawn_thread /data/src/10.2/storage/perfschema/pfs.cc:1869
          #19 0x7fb9d29d1608 in start_thread /build/glibc-ZN95T4/glibc-2.31/nptl/pthread_create.c:477
       
      Thread T5 created by T0 here:
          #0 0x7fb9d2e65805 in pthread_create (/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
          #1 0x558e812a99ca in spawn_thread_v1 /data/src/10.2/storage/perfschema/pfs.cc:1919
          #2 0x558e7f92a083 in inline_mysql_thread_create /data/src/10.2/include/mysql/psi/mysql_thread.h:1246
          #3 0x558e7f941c2b in create_thread_to_handle_connection(CONNECT*) /data/src/10.2/sql/mysqld.cc:6567
          #4 0x558e7f9423c6 in create_new_thread /data/src/10.2/sql/mysqld.cc:6637
          #5 0x558e7f943558 in handle_connections_sockets() /data/src/10.2/sql/mysqld.cc:6895
          #6 0x558e7f940f7c in mysqld_main(int, char**) /data/src/10.2/sql/mysqld.cc:6186
          #7 0x558e7f92893c in main /data/src/10.2/sql/main.cc:25
          #8 0x7fb9d24b00b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
       
      SUMMARY: AddressSanitizer: use-after-poison (/lib/x86_64-linux-gnu/libasan.so.5+0xdadfc) 
      Shadow bytes around the buggy address:
        0x0c3280009050: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
        0x0c3280009060: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
        0x0c3280009070: f7 f7 f7 f7 f7 f7 f7 f7 f7 04 fa fa fa fa fa fa
        0x0c3280009080: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c3280009090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      =>0x0c32800090a0: 00 f7 03 f7 00 00 03 00 00 03[f7]00 00 00 00 00
        0x0c32800090b0: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c32800090c0: 00 00 00 00 00 00 00 00 00 00 f7 00 00 00 00 00
        0x0c32800090d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c32800090e0: 00 00 00 00 f7 00 00 00 00 00 00 00 00 00 00 00
        0x0c32800090f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      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
      ==1592797==ABORTING
      

      With InnoDB

      --source include/have_innodb.inc
       
      CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b VARBINARY(8), c TINYINT AS (a)) ENGINE=InnoDB;
      INSERT INTO t1 (id,a) VALUES (1,242);
      --error ER_WARN_DATA_OUT_OF_RANGE
      REPLACE INTO t1 (id) VALUES (1);
      UPDATE t1 SET a = 1;
       
      # Cleanup
      DROP TABLE t1;
      

      10.2 29d9897f ASAN

      ==1593047==ERROR: AddressSanitizer: use-after-poison on address 0x6190000db349 at pc 0x7f0a0dfc1480 bp 0x7f09f6f29330 sp 0x7f09f6f28ad8
      READ of size 9 at 0x6190000db349 thread T27
          #0 0x7f0a0dfc147f  (/lib/x86_64-linux-gnu/libasan.so.5+0x9b47f)
          #1 0x559e13daa4d1 in row_sel_store_mysql_field_func /data/src/10.2/storage/innobase/row/row0sel.cc:3077
          #2 0x559e13dab76e in row_sel_store_mysql_rec /data/src/10.2/storage/innobase/row/row0sel.cc:3245
          #3 0x559e13db85f6 in row_search_mvcc(unsigned char*, page_cur_mode_t, row_prebuilt_t*, unsigned long, unsigned long) /data/src/10.2/storage/innobase/row/row0sel.cc:5623
          #4 0x559e13a818fc in ha_innobase::index_read(unsigned char*, unsigned char const*, unsigned int, ha_rkey_function) /data/src/10.2/storage/innobase/handler/ha_innodb.cc:9394
          #5 0x559e13a84ca2 in ha_innobase::index_first(unsigned char*) /data/src/10.2/storage/innobase/handler/ha_innodb.cc:9771
          #6 0x559e13a85379 in ha_innobase::rnd_next(unsigned char*) /data/src/10.2/storage/innobase/handler/ha_innodb.cc:9864
          #7 0x559e13552216 in handler::ha_rnd_next(unsigned char*) /data/src/10.2/sql/handler.cc:2669
          #8 0x559e138ff8e1 in rr_sequential(READ_RECORD*) /data/src/10.2/sql/records.cc:492
          #9 0x559e1318c0ee in mysql_update(THD*, TABLE_LIST*, List<Item>&, List<Item>&, Item*, unsigned int, st_order*, unsigned long long, enum_duplicates, bool, unsigned long long*, unsigned long long*) /data/src/10.2/sql/sql_update.cc:751
          #10 0x559e12f09d69 in mysql_execute_command(THD*) /data/src/10.2/sql/sql_parse.cc:4033
          #11 0x559e12f237eb in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.2/sql/sql_parse.cc:7763
          #12 0x559e12efc830 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.2/sql/sql_parse.cc:1827
          #13 0x559e12ef95ef in do_command(THD*) /data/src/10.2/sql/sql_parse.cc:1381
          #14 0x559e13281b1e in do_handle_one_connection(CONNECT*) /data/src/10.2/sql/sql_connect.cc:1336
          #15 0x559e132813e1 in handle_one_connection /data/src/10.2/sql/sql_connect.cc:1241
          #16 0x559e1461d5d9 in pfs_spawn_thread /data/src/10.2/storage/perfschema/pfs.cc:1869
          #17 0x7f0a0dacc608 in start_thread /build/glibc-ZN95T4/glibc-2.31/nptl/pthread_create.c:477
          #18 0x7f0a0d6a6292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)
       
      0x6190000db349 is located 457 bytes inside of 1100-byte region [0x6190000db180,0x6190000db5cc)
      allocated by thread T27 here:
          #0 0x7f0a0e033bc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
          #1 0x559e1473a12c in sf_malloc /data/src/10.2/mysys/safemalloc.c:118
          #2 0x559e14706091 in my_malloc /data/src/10.2/mysys/my_malloc.c:101
          #3 0x559e146e3703 in alloc_root /data/src/10.2/mysys/my_alloc.c:243
          #4 0x559e146e5139 in memdup_root /data/src/10.2/mysys/my_alloc.c:464
          #5 0x559e131b8777 in TABLE_SHARE::init_from_binary_frm_image(THD*, bool, unsigned char const*, unsigned long) /data/src/10.2/sql/table.cc:1288
          #6 0x559e131b4143 in open_table_def(THD*, TABLE_SHARE*, unsigned int) /data/src/10.2/sql/table.cc:684
          #7 0x559e13406065 in tdc_acquire_share(THD*, TABLE_LIST*, unsigned int, TABLE**) /data/src/10.2/sql/table_cache.cc:826
          #8 0x559e12ddd7f0 in open_table(THD*, TABLE_LIST*, Open_table_context*) /data/src/10.2/sql/sql_base.cc:1797
          #9 0x559e12de6344 in open_and_process_table /data/src/10.2/sql/sql_base.cc:3614
          #10 0x559e12de871e in open_tables(THD*, DDL_options_st const&, TABLE_LIST**, unsigned int*, unsigned int, Prelocking_strategy*) /data/src/10.2/sql/sql_base.cc:4081
          #11 0x559e12dec2a4 in open_and_lock_tables(THD*, DDL_options_st const&, TABLE_LIST*, bool, unsigned int, Prelocking_strategy*) /data/src/10.2/sql/sql_base.cc:4880
          #12 0x559e12d6346d in open_and_lock_tables(THD*, TABLE_LIST*, bool, unsigned int) /data/src/10.2/sql/sql_base.h:507
          #13 0x559e12ea215d in mysql_insert(THD*, TABLE_LIST*, List<Item>&, List<List<Item> >&, List<Item>&, List<Item>&, enum_duplicates, bool) /data/src/10.2/sql/sql_insert.cc:758
          #14 0x559e12f0ab91 in mysql_execute_command(THD*) /data/src/10.2/sql/sql_parse.cc:4194
          #15 0x559e12f237eb in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /data/src/10.2/sql/sql_parse.cc:7763
          #16 0x559e12efc830 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /data/src/10.2/sql/sql_parse.cc:1827
          #17 0x559e12ef95ef in do_command(THD*) /data/src/10.2/sql/sql_parse.cc:1381
          #18 0x559e13281b1e in do_handle_one_connection(CONNECT*) /data/src/10.2/sql/sql_connect.cc:1336
          #19 0x559e132813e1 in handle_one_connection /data/src/10.2/sql/sql_connect.cc:1241
          #20 0x559e1461d5d9 in pfs_spawn_thread /data/src/10.2/storage/perfschema/pfs.cc:1869
          #21 0x7f0a0dacc608 in start_thread /build/glibc-ZN95T4/glibc-2.31/nptl/pthread_create.c:477
       
      Thread T27 created by T0 here:
          #0 0x7f0a0df60805 in pthread_create (/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
          #1 0x559e1461d9ca in spawn_thread_v1 /data/src/10.2/storage/perfschema/pfs.cc:1919
          #2 0x559e12c9e083 in inline_mysql_thread_create /data/src/10.2/include/mysql/psi/mysql_thread.h:1246
          #3 0x559e12cb5c2b in create_thread_to_handle_connection(CONNECT*) /data/src/10.2/sql/mysqld.cc:6567
          #4 0x559e12cb63c6 in create_new_thread /data/src/10.2/sql/mysqld.cc:6637
          #5 0x559e12cb7558 in handle_connections_sockets() /data/src/10.2/sql/mysqld.cc:6895
          #6 0x559e12cb4f7c in mysqld_main(int, char**) /data/src/10.2/sql/mysqld.cc:6186
          #7 0x559e12c9c93c in main /data/src/10.2/sql/main.cc:25
          #8 0x7f0a0d5ab0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
       
      SUMMARY: AddressSanitizer: use-after-poison (/lib/x86_64-linux-gnu/libasan.so.5+0x9b47f) 
      Shadow bytes around the buggy address:
        0x0c3280013610: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa
        0x0c3280013620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c3280013630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c3280013640: 00 f7 00 00 f7 01 f7 00 00 00 00 00 00 00 00 00
        0x0c3280013650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      =>0x0c3280013660: 00 02 f7 00 f7 00 00 03 f7[01]f7 00 00 00 00 00
        0x0c3280013670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c3280013680: 00 00 00 00 00 f7 00 00 00 00 00 00 00 00 00 00
        0x0c3280013690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f7
        0x0c32800136a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c32800136b0: 00 00 00 00 00 00 00 00 00 04 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
        Shadow gap:              cc
      ==1593047==ABORTING
      

      Non-ASAN builds don't crash, but the results are rather odd. I have no clear opinion on how it should behave, but the way it does not seems inconsistent:

      CREATE TABLE t1 (id INT PRIMARY KEY, a INT, b VARBINARY(8), c TINYINT AS (a)) ENGINE=MyISAM;
      INSERT INTO t1 (id,a) VALUES (1,242);
      SELECT * FROM t1;
      --error ER_WARN_DATA_OUT_OF_RANGE
      REPLACE INTO t1 (id) VALUES (1);
      SELECT * FROM t1;
      UPDATE t1 SET a = 1;
      SELECT * FROM t1;
       
      # Cleanup
      DROP TABLE t1;
      

      So, the first INSERT works without an error or a warning, and the value is truncated:

      INSERT INTO t1 (id,a) VALUES (1,242);
      SELECT * FROM t1;
      id	a	b	c
      1	242	NULL	127
      

      The following REPLACE fails, but it does change something anyway:

      REPLACE INTO t1 (id) VALUES (1);
      ERROR 22003: Out of range value for column 'c' at row 1
      SELECT * FROM t1;
      id	a	b	c
      1	242	NULL	NULL
      

      and finall the UPDATE works, again without a warning or an error, but the value of the virtual column remains NULL:

      UPDATE t1 SET a = 1;
      SELECT * FROM t1;
      id	a	b	c
      1	242	NULL	NULL
      

        Attachments

          Activity

            People

            Assignee:
            nikitamalyavin Nikita Malyavin
            Reporter:
            elenst Elena Stepanova
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated: