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

Buffer overflow on instant ADD/DROP of generated column

Details

    Description

      PoC:

      CREATE TABLE v0 ( v1 TIME NOT NULL PRIMARY KEY ) ;
       ALTER TABLE v0 ADD COLUMN v0 INT GENERATED ALWAYS AS ( lpad ( 'x' , NULL = 32 , 'x' ) ) STORED ;
       SHOW LOCAL STATUS WHERE COALESCE ( 27 , 51 - 39 ) = 'x' ;
       DELETE FROM v0 WHERE 44707452.000000 ;
       ALTER TABLE v0 ADD COLUMN v0 INT GENERATED ALWAYS AS ( v1 + v1 ) , DROP COLUMN v0 ;
       SELECT COUNT ( * ) FROM v0 WHERE v1 = -128 AND v1 = 'x' ;
      

      Log and Asan report:

      2021-08-16 14:41:38 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
      2021-08-16 14:41:38 0 [Note] InnoDB: Number of pools: 1
      2021-08-16 14:41:38 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
      2021-08-16 14:41:38 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
      2021-08-16 14:41:38 0 [Note] InnoDB: Using liburing
      2021-08-16 14:41:38 0 [Note] InnoDB: Initializing buffer pool, total size = 134217728, chunk size = 134217728
      2021-08-16 14:41:38 0 [Note] InnoDB: Completed initialization of buffer pool
      2021-08-16 14:41:38 0 [Note] InnoDB: 128 rollback segments are active.
      2021-08-16 14:41:38 0 [Note] InnoDB: Creating shared tablespace for temporary tables
      2021-08-16 14:41:38 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
      2021-08-16 14:41:38 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
      2021-08-16 14:41:38 0 [Note] InnoDB: 10.7.0 started; log sequence number 42161; transaction id 14
      2021-08-16 14:41:38 0 [Note] InnoDB: Loading buffer pool(s) from /home/fuboat/mariadb-tmp/mysql-default-data/ib_buffer_pool
      2021-08-16 14:41:38 0 [Note] Plugin 'FEEDBACK' is disabled.
      2021-08-16 14:41:38 0 [Note] InnoDB: Buffer pool(s) load completed at 210816 14:41:38
      2021-08-16 14:41:38 0 [Note] Server socket created on IP: '0.0.0.0'.
      2021-08-16 14:41:38 0 [Note] Server socket created on IP: '::'.
      2021-08-16 14:41:38 0 [Note] /usr/local/mysql/bin//mysqld: ready for connections.
      Version: '10.7.0-MariaDB'  socket: '/tmp/0.socket'  port: 3306  Source distribution
      2021-08-16 14:41:39 0 [Note] /usr/local/mysql/bin//mysqld (initiated by: root[root] @ localhost []): Normal shutdown
      2021-08-16 14:41:39 0 [Note] InnoDB: FTS optimize thread exiting.
      2021-08-16 14:41:39 0 [Note] InnoDB: Starting shutdown...
      2021-08-16 14:41:39 0 [Note] InnoDB: Dumping buffer pool(s) to /home/fuboat/mariadb-tmp/mysql-default-data/ib_buffer_pool
      2021-08-16 14:41:39 0 [Note] InnoDB: Buffer pool(s) dump completed at 210816 14:41:39
      2021-08-16 14:41:39 0 [Note] InnoDB: Removed temporary tablespace data file: "./ibtmp1"
      2021-08-16 14:41:39 0 [Note] InnoDB: Shutdown completed; log sequence number 42173; transaction id 15
      2021-08-16 14:41:39 0 [Note] /usr/local/mysql/bin//mysqld: Shutdown complete
       
      2021-08-16 14:49:19 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
      2021-08-16 14:49:19 0 [Note] InnoDB: Number of pools: 1
      2021-08-16 14:49:19 0 [Note] InnoDB: Using crc32 + pclmulqdq instructions
      2021-08-16 14:49:19 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
      2021-08-16 14:49:19 0 [Note] InnoDB: Using liburing
      2021-08-16 14:49:19 0 [Note] InnoDB: Initializing buffer pool, total size = 134217728, chunk size = 134217728
      2021-08-16 14:49:19 0 [Note] InnoDB: Completed initialization of buffer pool
      2021-08-16 14:49:26 0 [Note] InnoDB: 128 rollback segments are active.
      2021-08-16 14:49:26 0 [Note] InnoDB: Creating shared tablespace for temporary tables
      2021-08-16 14:49:26 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
      2021-08-16 14:49:26 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
      2021-08-16 14:49:26 0 [Note] InnoDB: 10.7.0 started; log sequence number 42173; transaction id 14
      2021-08-16 14:49:26 0 [Note] InnoDB: Loading buffer pool(s) from /home/fuboat/mariadb-tmp/19/ib_buffer_pool
      2021-08-16 14:49:26 0 [Note] Plugin 'FEEDBACK' is disabled.
      2021-08-16 14:49:27 0 [Note] Server socket created on IP: '0.0.0.0'.
      2021-08-16 14:49:27 0 [Note] Server socket created on IP: '::'.
      2021-08-16 14:49:28 0 [Note] InnoDB: Buffer pool(s) load completed at 210816 14:49:28
      2021-08-16 14:49:28 0 [Note] /usr/local/mysql/bin//mysqld: ready for connections.
      Version: '10.7.0-MariaDB'  socket: '/tmp/19.socket'  port: 10019  Source distribution
      =================================================================
      ==2119277==ERROR: AddressSanitizer: use-after-poison on address 0x6190000d6d60 at pc 0x55a3184baacf bp 0x7f47ed829920 sp 0x7f47ed829910
      WRITE of size 64 at 0x6190000d6d60 thread T14
          #0 0x55a3184baace in prepare_inplace_add_virtual /experiment/mariadb-server/sql/field.h:1395
          #1 0x55a3184cc1db in prepare_inplace_alter_table_dict /experiment/mariadb-server/storage/innobase/handler/handler0alter.cc:6206
          #2 0x55a3184d9f06 in ha_innobase::prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /experiment/mariadb-server/storage/innobase/handler/handler0alter.cc:8270
          #3 0x55a3176a67d2 in mysql_inplace_alter_table /experiment/mariadb-server/sql/sql_table.cc:7326
          #4 0x55a3176a67d2 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool, bool) /experiment/mariadb-server/sql/sql_table.cc:10205
          #5 0x55a3177fcf99 in Sql_cmd_alter_table::execute(THD*) /experiment/mariadb-server/sql/sql_alter.cc:550
          #6 0x55a31741717f in mysql_execute_command(THD*, bool) /experiment/mariadb-server/sql/sql_parse.cc:5997
          #7 0x55a3174245a0 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /experiment/mariadb-server/sql/sql_parse.cc:8030
          #8 0x55a31742a60b in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /experiment/mariadb-server/sql/sql_parse.cc:1896
          #9 0x55a31742f73c in do_command(THD*, bool) /experiment/mariadb-server/sql/sql_parse.cc:1404
          #10 0x55a3177eae56 in do_handle_one_connection(CONNECT*, bool) /experiment/mariadb-server/sql/sql_connect.cc:1418
          #11 0x55a3177eb33c in handle_one_connection /experiment/mariadb-server/sql/sql_connect.cc:1312
          #12 0x55a31827bc2b in pfs_spawn_thread /experiment/mariadb-server/storage/perfschema/pfs.cc:2201
          #13 0x7f4812443258 in start_thread (/usr/lib/libpthread.so.0+0x9258)
          #14 0x7f4811fee5e2 in __GI___clone (/usr/lib/libc.so.6+0xfe5e2)
       
      0x6190000d6d60 is located 480 bytes inside of 1152-byte region [0x6190000d6b80,0x6190000d7000)
      allocated by thread T14 here:
          #0 0x7f4812ad5279 in __interceptor_malloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
          #1 0x55a3185c76c0 in ut_allocator<unsigned char, true>::allocate(unsigned long, unsigned char const*, unsigned int, bool, bool) /experiment/mariadb-server/storage/innobase/include/ut0new.h:375
          #2 0x55a3185c76c0 in mem_heap_create_block_func(mem_block_info_t*, unsigned long, unsigned long) /experiment/mariadb-server/storage/innobase/mem/mem0mem.cc:277
          #3 0x55a3184da801 in mem_heap_create_func /experiment/mariadb-server/storage/innobase/include/mem0mem.ic:377
          #4 0x55a3184da801 in ha_innobase::prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /experiment/mariadb-server/storage/innobase/handler/handler0alter.cc:7816
          #5 0x55a3176a67d2 in mysql_inplace_alter_table /experiment/mariadb-server/sql/sql_table.cc:7326
          #6 0x55a3176a67d2 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool, bool) /experiment/mariadb-server/sql/sql_table.cc:10205
          #7 0x55a3177fcf99 in Sql_cmd_alter_table::execute(THD*) /experiment/mariadb-server/sql/sql_alter.cc:550
          #8 0x55a31741717f in mysql_execute_command(THD*, bool) /experiment/mariadb-server/sql/sql_parse.cc:5997
          #9 0x55a3174245a0 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /experiment/mariadb-server/sql/sql_parse.cc:8030
          #10 0x55a31742a60b in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /experiment/mariadb-server/sql/sql_parse.cc:1896
          #11 0x55a31742f73c in do_command(THD*, bool) /experiment/mariadb-server/sql/sql_parse.cc:1404
          #12 0x55a3177eae56 in do_handle_one_connection(CONNECT*, bool) /experiment/mariadb-server/sql/sql_connect.cc:1418
          #13 0x55a3177eb33c in handle_one_connection /experiment/mariadb-server/sql/sql_connect.cc:1312
          #14 0x55a31827bc2b in pfs_spawn_thread /experiment/mariadb-server/storage/perfschema/pfs.cc:2201
          #15 0x7f4812443258 in start_thread (/usr/lib/libpthread.so.0+0x9258)
       
      Thread T14 created by T0 here:
          #0 0x7f4812a76fa7 in __interceptor_pthread_create /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:216
          #1 0x55a31827bea9 in my_thread_create /experiment/mariadb-server/storage/perfschema/my_thread.h:48
          #2 0x55a31827bea9 in pfs_spawn_thread_v1 /experiment/mariadb-server/storage/perfschema/pfs.cc:2252
          #3 0x55a3170ecb3c in inline_mysql_thread_create /experiment/mariadb-server/include/mysql/psi/mysql_thread.h:1139
          #4 0x55a3170ecb3c in create_thread_to_handle_connection(CONNECT*) /experiment/mariadb-server/sql/mysqld.cc:5934
          #5 0x55a3170f87b6 in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /experiment/mariadb-server/sql/mysqld.cc:6055
          #6 0x55a3170f936f in handle_connections_sockets() /experiment/mariadb-server/sql/mysqld.cc:6179
          #7 0x55a3170fca52 in mysqld_main(int, char**) /experiment/mariadb-server/sql/mysqld.cc:5829
          #8 0x7f4811f17b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
       
      SUMMARY: AddressSanitizer: use-after-poison /experiment/mariadb-server/sql/field.h:1395 in prepare_inplace_add_virtual
      Shadow bytes around the buggy address:
        0x0c3280012d50: f7 f7 fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c3280012d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c3280012d70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c3280012d80: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
        0x0c3280012d90: 00 00 00 00 00 00 f7 00 00 00 00 00 00 00 00 00
      =>0x0c3280012da0: 00 00 00 00 00 00 00 00 00 00 00 f7[f7]f7 f7 f7
        0x0c3280012db0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
        0x0c3280012dc0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
        0x0c3280012dd0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
        0x0c3280012de0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
        0x0c3280012df0: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
      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
      ==2119277==ABORTING
      GNU gdb (GDB) 10.2
      Copyright (C) 2021 Free Software Foundation, Inc.
      License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
      Type "show copying" and "show warranty" for details.
      This GDB was configured as "x86_64-pc-linux-gnu".
      Type "show configuration" for configuration details.
      For bug reporting instructions, please see:
      <https://www.gnu.org/software/gdb/bugs/>.
      Find the GDB manual and other documentation resources online at:
          <http://www.gnu.org/software/gdb/documentation/>.
       
      For help, type "help".
      Type "apropos word" to search for commands related to "word"...
      Reading symbols from /usr/local/mysql/bin//mysqld...
      (gdb) (gdb) (gdb) quit
      

      Attachments

        Issue Links

          Activity

            alice Alice Sherepa added a comment -

            Thank you! Reproducible on 10.4-10.6:

            --source include/have_innodb.inc
             
            CREATE TABLE t1 (i int AS ('x') stored, j int) engine=innodb;
            ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS ('a'), DROP COLUMN i ;
            

            10.4 dc6bc85cd29586631d

            Version: '10.4.22-MariaDB-debug-log'  
            =================================================================
            ==620710==ERROR: AddressSanitizer: use-after-poison on address 0x6190000f3998 at pc 0x5623146114a1 bp 0x7fc65afb1b80 sp 0x7fc65afb1b70
            WRITE of size 56 at 0x6190000f3998 thread T27
                #0 0x5623146114a0 in prepare_inplace_add_virtual /10.4/src/storage/innobase/handler/handler0alter.cc:5059
                #1 0x5623146199c0 in prepare_inplace_alter_table_dict /10.4/src/storage/innobase/handler/handler0alter.cc:6284
                #2 0x56231462eafc in ha_innobase::prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/storage/innobase/handler/handler0alter.cc:8356
                #3 0x562313fc4575 in handler::ha_prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/sql/handler.cc:4622
                #4 0x562313a01860 in mysql_inplace_alter_table /10.4/src/sql/sql_table.cc:7785
                #5 0x562313a136d2 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool) /10.4/src/sql/sql_table.cc:10251
                #6 0x562313b97587 in Sql_cmd_alter_table::execute(THD*) /10.4/src/sql/sql_alter.cc:520
                #7 0x5623137a6789 in mysql_execute_command(THD*) /10.4/src/sql/sql_parse.cc:6192
                #8 0x5623137b22d6 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.4/src/sql/sql_parse.cc:7995
                #9 0x562313788a52 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.4/src/sql/sql_parse.cc:1857
                #10 0x5623137854cf in do_command(THD*) /10.4/src/sql/sql_parse.cc:1373
                #11 0x562313b7eb38 in do_handle_one_connection(CONNECT*) /10.4/src/sql/sql_connect.cc:1420
                #12 0x562313b7e291 in handle_one_connection /10.4/src/sql/sql_connect.cc:1316
                #13 0x56231525074c in pfs_spawn_thread /10.4/src/storage/perfschema/pfs.cc:1869
                #14 0x7fc671cb4608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
                #15 0x7fc671889292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)
             
            0x6190000f3998 is located 536 bytes inside of 1152-byte region [0x6190000f3780,0x6190000f3c00)
            allocated by thread T27 here:
                #0 0x7fc6722c8bc8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
                #1 0x562314774ce9 in mem_heap_create_block_func(mem_block_info_t*, unsigned long, char const*, unsigned int, unsigned long) /10.4/src/storage/innobase/mem/mem0mem.cc:277
                #2 0x5623145ef526 in mem_heap_create_func /10.4/src/storage/innobase/include/mem0mem.ic:375
                #3 0x562314629f56 in ha_innobase::prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/storage/innobase/handler/handler0alter.cc:7913
                #4 0x562313fc4575 in handler::ha_prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/sql/handler.cc:4622
                #5 0x562313a01860 in mysql_inplace_alter_table /10.4/src/sql/sql_table.cc:7785
                #6 0x562313a136d2 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool) /10.4/src/sql/sql_table.cc:10251
                #7 0x562313b97587 in Sql_cmd_alter_table::execute(THD*) /10.4/src/sql/sql_alter.cc:520
                #8 0x5623137a6789 in mysql_execute_command(THD*) /10.4/src/sql/sql_parse.cc:6192
                #9 0x5623137b22d6 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.4/src/sql/sql_parse.cc:7995
                #10 0x562313788a52 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.4/src/sql/sql_parse.cc:1857
                #11 0x5623137854cf in do_command(THD*) /10.4/src/sql/sql_parse.cc:1373
                #12 0x562313b7eb38 in do_handle_one_connection(CONNECT*) /10.4/src/sql/sql_connect.cc:1420
                #13 0x562313b7e291 in handle_one_connection /10.4/src/sql/sql_connect.cc:1316
                #14 0x56231525074c in pfs_spawn_thread /10.4/src/storage/perfschema/pfs.cc:1869
                #15 0x7fc671cb4608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
             
            Thread T27 created by T0 here:
                #0 0x7fc6721f5805 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
                #1 0x562315250b3d in spawn_thread_v1 /10.4/src/storage/perfschema/pfs.cc:1919
                #2 0x56231348cb8f in inline_mysql_thread_create /10.4/src/include/mysql/psi/mysql_thread.h:1275
                #3 0x5623134a4a94 in create_thread_to_handle_connection(CONNECT*) /10.4/src/sql/mysqld.cc:6241
                #4 0x5623134a522f in create_new_thread(CONNECT*) /10.4/src/sql/mysqld.cc:6311
                #5 0x5623134a5715 in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /10.4/src/sql/mysqld.cc:6409
                #6 0x5623134a65e2 in handle_connections_sockets() /10.4/src/sql/mysqld.cc:6567
                #7 0x5623134a4188 in mysqld_main(int, char**) /10.4/src/sql/mysqld.cc:5899
                #8 0x56231348addc in main /10.4/src/sql/main.cc:25
                #9 0x7fc67178e0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
             
            SUMMARY: AddressSanitizer: use-after-poison /10.4/src/storage/innobase/handler/handler0alter.cc:5059 in prepare_inplace_add_virtual
            Shadow bytes around the buggy address:
              0x0c32800166e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
              0x0c32800166f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c3280016700: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
              0x0c3280016710: 00 00 00 00 00 00 00 00 00 f7 00 00 00 00 00 00
              0x0c3280016720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
            =>0x0c3280016730: 00 00 f7[f7]f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
              0x0c3280016740: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
              0x0c3280016750: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
              0x0c3280016760: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
              0x0c3280016770: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7
              0x0c3280016780: 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
              Shadow gap:              cc
            ==620710==ABORTING
            ----------SERVER LOG END-------------
            
            

            alice Alice Sherepa added a comment - Thank you! Reproducible on 10.4-10.6: --source include/have_innodb.inc   CREATE TABLE t1 (i int AS ( 'x' ) stored, j int ) engine=innodb; ALTER TABLE t1 ADD COLUMN i INT GENERATED ALWAYS AS ( 'a' ), DROP COLUMN i ; 10.4 dc6bc85cd29586631d Version: '10.4.22-MariaDB-debug-log' ================================================================= ==620710==ERROR: AddressSanitizer: use-after-poison on address 0x6190000f3998 at pc 0x5623146114a1 bp 0x7fc65afb1b80 sp 0x7fc65afb1b70 WRITE of size 56 at 0x6190000f3998 thread T27 #0 0x5623146114a0 in prepare_inplace_add_virtual /10.4/src/storage/innobase/handler/handler0alter.cc:5059 #1 0x5623146199c0 in prepare_inplace_alter_table_dict /10.4/src/storage/innobase/handler/handler0alter.cc:6284 #2 0x56231462eafc in ha_innobase::prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/storage/innobase/handler/handler0alter.cc:8356 #3 0x562313fc4575 in handler::ha_prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/sql/handler.cc:4622 #4 0x562313a01860 in mysql_inplace_alter_table /10.4/src/sql/sql_table.cc:7785 #5 0x562313a136d2 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool) /10.4/src/sql/sql_table.cc:10251 #6 0x562313b97587 in Sql_cmd_alter_table::execute(THD*) /10.4/src/sql/sql_alter.cc:520 #7 0x5623137a6789 in mysql_execute_command(THD*) /10.4/src/sql/sql_parse.cc:6192 #8 0x5623137b22d6 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.4/src/sql/sql_parse.cc:7995 #9 0x562313788a52 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.4/src/sql/sql_parse.cc:1857 #10 0x5623137854cf in do_command(THD*) /10.4/src/sql/sql_parse.cc:1373 #11 0x562313b7eb38 in do_handle_one_connection(CONNECT*) /10.4/src/sql/sql_connect.cc:1420 #12 0x562313b7e291 in handle_one_connection /10.4/src/sql/sql_connect.cc:1316 #13 0x56231525074c in pfs_spawn_thread /10.4/src/storage/perfschema/pfs.cc:1869 #14 0x7fc671cb4608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477 #15 0x7fc671889292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)   0x6190000f3998 is located 536 bytes inside of 1152-byte region [0x6190000f3780,0x6190000f3c00) allocated by thread T27 here: #0 0x7fc6722c8bc8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8) #1 0x562314774ce9 in mem_heap_create_block_func(mem_block_info_t*, unsigned long, char const*, unsigned int, unsigned long) /10.4/src/storage/innobase/mem/mem0mem.cc:277 #2 0x5623145ef526 in mem_heap_create_func /10.4/src/storage/innobase/include/mem0mem.ic:375 #3 0x562314629f56 in ha_innobase::prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/storage/innobase/handler/handler0alter.cc:7913 #4 0x562313fc4575 in handler::ha_prepare_inplace_alter_table(TABLE*, Alter_inplace_info*) /10.4/src/sql/handler.cc:4622 #5 0x562313a01860 in mysql_inplace_alter_table /10.4/src/sql/sql_table.cc:7785 #6 0x562313a136d2 in mysql_alter_table(THD*, st_mysql_const_lex_string const*, st_mysql_const_lex_string const*, HA_CREATE_INFO*, TABLE_LIST*, Alter_info*, unsigned int, st_order*, bool) /10.4/src/sql/sql_table.cc:10251 #7 0x562313b97587 in Sql_cmd_alter_table::execute(THD*) /10.4/src/sql/sql_alter.cc:520 #8 0x5623137a6789 in mysql_execute_command(THD*) /10.4/src/sql/sql_parse.cc:6192 #9 0x5623137b22d6 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.4/src/sql/sql_parse.cc:7995 #10 0x562313788a52 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.4/src/sql/sql_parse.cc:1857 #11 0x5623137854cf in do_command(THD*) /10.4/src/sql/sql_parse.cc:1373 #12 0x562313b7eb38 in do_handle_one_connection(CONNECT*) /10.4/src/sql/sql_connect.cc:1420 #13 0x562313b7e291 in handle_one_connection /10.4/src/sql/sql_connect.cc:1316 #14 0x56231525074c in pfs_spawn_thread /10.4/src/storage/perfschema/pfs.cc:1869 #15 0x7fc671cb4608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477   Thread T27 created by T0 here: #0 0x7fc6721f5805 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3a805) #1 0x562315250b3d in spawn_thread_v1 /10.4/src/storage/perfschema/pfs.cc:1919 #2 0x56231348cb8f in inline_mysql_thread_create /10.4/src/include/mysql/psi/mysql_thread.h:1275 #3 0x5623134a4a94 in create_thread_to_handle_connection(CONNECT*) /10.4/src/sql/mysqld.cc:6241 #4 0x5623134a522f in create_new_thread(CONNECT*) /10.4/src/sql/mysqld.cc:6311 #5 0x5623134a5715 in handle_accepted_socket(st_mysql_socket, st_mysql_socket) /10.4/src/sql/mysqld.cc:6409 #6 0x5623134a65e2 in handle_connections_sockets() /10.4/src/sql/mysqld.cc:6567 #7 0x5623134a4188 in mysqld_main(int, char**) /10.4/src/sql/mysqld.cc:5899 #8 0x56231348addc in main /10.4/src/sql/main.cc:25 #9 0x7fc67178e0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)   SUMMARY: AddressSanitizer: use-after-poison /10.4/src/storage/innobase/handler/handler0alter.cc:5059 in prepare_inplace_add_virtual Shadow bytes around the buggy address: 0x0c32800166e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c32800166f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c3280016700: f7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c3280016710: 00 00 00 00 00 00 00 00 00 f7 00 00 00 00 00 00 0x0c3280016720: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c3280016730: 00 00 f7[f7]f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 0x0c3280016740: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 0x0c3280016750: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 0x0c3280016760: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 0x0c3280016770: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 0x0c3280016780: 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 Shadow gap: cc ==620710==ABORTING ----------SERVER LOG END-------------

            For alice’s test case, the memory had been poisoned here:

            10.4 8911823f65a6557ce66ea5f8aecd55b115a85606

            #3  0x0000562765feda32 in mem_heap_create_func (size=<optimized out>, 
                size@entry=1024, 
                file_name=file_name@entry=0x562766ef84c0 "/mariadb/10.4/storage/innobase/handler/handler0alter.cc", line=line@entry=7964, type=type@entry=0)
                at /mariadb/10.4/storage/innobase/include/mem0mem.inl:375
            #4  0x000056276600a835 in ha_innobase::prepare_inplace_alter_table (
                this=0x61d000247ca8, altered_table=<optimized out>, 
                ha_alter_info=<optimized out>)
                at /mariadb/10.4/storage/innobase/handler/handler0alter.cc:7964
            #5  0x000056276589c741 in handler::ha_prepare_inplace_alter_table (
                this=0x61d000247ca8, altered_table=altered_table@entry=0x7f6ba9085510, 
                ha_alter_info=ha_alter_info@entry=0x7f6ba90837a0)
                at /mariadb/10.4/sql/handler.cc:4637
            

            So, it looks like an out-of-bounds access.

            marko Marko Mäkelä added a comment - For alice ’s test case, the memory had been poisoned here: 10.4 8911823f65a6557ce66ea5f8aecd55b115a85606 #3 0x0000562765feda32 in mem_heap_create_func (size=<optimized out>, size@entry=1024, file_name=file_name@entry=0x562766ef84c0 "/mariadb/10.4/storage/innobase/handler/handler0alter.cc", line=line@entry=7964, type=type@entry=0) at /mariadb/10.4/storage/innobase/include/mem0mem.inl:375 #4 0x000056276600a835 in ha_innobase::prepare_inplace_alter_table ( this=0x61d000247ca8, altered_table=<optimized out>, ha_alter_info=<optimized out>) at /mariadb/10.4/storage/innobase/handler/handler0alter.cc:7964 #5 0x000056276589c741 in handler::ha_prepare_inplace_alter_table ( this=0x61d000247ca8, altered_table=altered_table@entry=0x7f6ba9085510, ha_alter_info=ha_alter_info@entry=0x7f6ba90837a0) at /mariadb/10.4/sql/handler.cc:4637 So, it looks like an out-of-bounds access.

            The out-of-bounds access occurs here:

            		new (&ctx->add_vcol[j]) dict_v_col_t();
            

            The j=0 is out-of-bounds because ctx->num_to_add_vcol=0 (instead of the correct value 1). The math goes wrong in prepare_inplace_add_virtual():

            static
            bool
            prepare_inplace_add_virtual(
            	Alter_inplace_info*	ha_alter_info,
            	const TABLE*		altered_table,
            	const TABLE*		table)
            {
            	ha_innobase_inplace_ctx*	ctx;
            	ulint				i = 0;
            	ulint				j = 0;
             
            	ctx = static_cast<ha_innobase_inplace_ctx*>
            		(ha_alter_info->handler_ctx);
             
            	ctx->num_to_add_vcol = altered_table->s->virtual_fields
            		+ ctx->num_to_drop_vcol - table->s->virtual_fields;
            

            Here, we have both altered_table->s->virtual_fields and table->s->virtual_fields equal to 1. InnoDB really cares about generated columns that are not stored in the clustered index, so it looks like we must iterate through all columns to see for which ones Field::stored_in_db() holds.

            The bug does not affect 10.3. For newer servers a work-around (to disable MDEV-15562) is innodb_instant_alter_column_allowed=add_last.

            marko Marko Mäkelä added a comment - The out-of-bounds access occurs here: new (&ctx->add_vcol[j]) dict_v_col_t(); The j=0 is out-of-bounds because ctx->num_to_add_vcol=0 (instead of the correct value 1). The math goes wrong in prepare_inplace_add_virtual() : static bool prepare_inplace_add_virtual( Alter_inplace_info* ha_alter_info, const TABLE* altered_table, const TABLE* table) { ha_innobase_inplace_ctx* ctx; ulint i = 0; ulint j = 0;   ctx = static_cast <ha_innobase_inplace_ctx*> (ha_alter_info->handler_ctx);   ctx->num_to_add_vcol = altered_table->s->virtual_fields + ctx->num_to_drop_vcol - table->s->virtual_fields; Here, we have both altered_table->s->virtual_fields and table->s->virtual_fields equal to 1. InnoDB really cares about generated columns that are not stored in the clustered index, so it looks like we must iterate through all columns to see for which ones Field::stored_in_db() holds. The bug does not affect 10.3. For newer servers a work-around (to disable MDEV-15562 ) is innodb_instant_alter_column_allowed=add_last .

            The simple fix is to over-estimate the size of the buffer as altered_table->s->virtual_fields + ctx->num_to_drop_vcol (not subtract any pre-existing generated columns), and to assign j at the end of the function to ctx->num_to_add_vcol.

            marko Marko Mäkelä added a comment - The simple fix is to over-estimate the size of the buffer as altered_table->s->virtual_fields + ctx->num_to_drop_vcol (not subtract any pre-existing generated columns), and to assign j at the end of the function to ctx->num_to_add_vcol .

            People

              marko Marko Mäkelä
              Zhiyong Zhiyong Wu
              Votes:
              0 Vote for this issue
              Watchers:
              4 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.