Bug #91630 stack-use-after-scope in innobase_convert_identifier() detected by ASan
Submitted: 13 Jul 2018 14:47 Modified: 15 Jul 2018 5:59
Reporter: Yura Sorokin (OCA) Email Updates:
Status: Verified Impact on me:
Category:MySQL Server: InnoDB storage engine Severity:S2 (Serious)
Version:5.6.40 OS:Any
Assigned to: CPU Architecture:Any
Tags: Contribution

[13 Jul 2018 14:47] Yura Sorokin
Address Sanitizer from GCC 7.3 and 8.0 detects the following problem in a number of MTR test cases.

==28134==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffcfeda3560 at pc 0x7fc4c8c05733 bp 0x7ffcfeda3380 sp 0x7ffcfeda2b28
READ of size 15 at 0x7ffcfeda3560 thread T0
    #0 0x7fc4c8c05732  (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79732)
    #1 0x55ea1ad06473 in memcpy /usr/include/x86_64-linux-gnu/bits/string_fortified.h:34
    #2 0x55ea1ad06473 in innobase_convert_identifier /mnt/hgfs/repos/percona-server/storage/innobase/handler/ha_innodb.cc:3195
    #3 0x55ea1ad23a2e in innobase_convert_name(char*, unsigned long, char const*, unsigned long, THD*, unsigned long) /mnt/hgfs/repos/percona-server/storage/innobase/handler/ha_innodb.cc:3280
    #4 0x55ea1ad23c3a in innobase_format_name(char*, unsigned long, char const*, unsigned long) /mnt/hgfs/repos/percona-server/storage/innobase/handler/ha_innodb.cc:3302
    #5 0x55ea1b2019d6 in dict_check_tablespaces_and_store_max_id(dict_check_t) /mnt/hgfs/repos/percona-server/storage/innobase/dict/dict0load.cc:1185
    #6 0x55ea1b0175cc in innobase_start_or_create_for_mysql() /mnt/hgfs/repos/percona-server/storage/innobase/srv/srv0start.cc:2553
    #7 0x55ea1ad3e63b in innobase_init /mnt/hgfs/repos/percona-server/storage/innobase/handler/ha_innodb.cc:4027
    #8 0x55ea19f73753 in ha_initialize_handlerton(st_plugin_int*) /mnt/hgfs/repos/percona-server/sql/handler.cc:696
    #9 0x55ea1a456405 in plugin_initialize /mnt/hgfs/repos/percona-server/sql/sql_plugin.cc:1166
    #10 0x55ea1a466f52 in plugin_init(int*, char**, int) /mnt/hgfs/repos/percona-server/sql/sql_plugin.cc:1463
    #11 0x55ea19f4c9aa in init_server_components /mnt/hgfs/repos/percona-server/sql/mysqld.cc:5229
    #12 0x55ea19f4c9aa in mysqld_main(int, char**) /mnt/hgfs/repos/percona-server/sql/mysqld.cc:5875
    #13 0x55ea19f280d2 in main /mnt/hgfs/repos/percona-server/sql/main.cc:25
    #14 0x7fc4c71f6b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
    #15 0x55ea19f27fe9 in _start (/home/yura/addon/percona-build-5.6-asan/sql/mysqld-debug+0x7bafe9)

Address 0x7ffcfeda3560 is located in stack of thread T0 at offset 416 in frame
    #0 0x55ea1ad06207 in innobase_convert_identifier /mnt/hgfs/repos/percona-server/storage/innobase/handler/ha_innodb.cc:3161

  This frame has 2 object(s):
    [32, 353) 'nz'
    [416, 737) 'nz2' <== Memory access at offset 416 is inside this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-scope (/usr/lib/x86_64-linux-gnu/libasan.so.4+0x79732)
Shadow bytes around the buggy address:
  0x10001fdac650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001fdac660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10001fdac670: 00 00 00 00 00 00 00 00 f1 f1 f1 f1 f8 f8 f8 f8
  0x10001fdac680: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x10001fdac690: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
=>0x10001fdac6a0: f8 f8 f8 f8 f8 f2 f2 f2 f2 f2 f2 f2[f8]f8 f8 f8
  0x10001fdac6b0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x10001fdac6c0: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
  0x10001fdac6d0: f8 f8 f8 f8 f8 f2 f2 f2 00 00 00 00 00 00 00 00
  0x10001fdac6e0: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 f2
  0x10001fdac6f0: f2 f2 f2 f2 f2 f2 00 06 f2 f2 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

How to repeat:
Compile MySQL 5.6 branch on Ubuntu Bionic (GCC 7.3) with -DWITH_ASAN=ON

./mysql-test/mtr --debug-server innodb_bug12661768

Suggested fix:
'nz' and 'nz2' buffers inside 'innobase_convert_identifier()' are declared in an internal 'if' block. However, pointers to them are used afterwards.

Fix by moving their declarations to the 'innobase_convert_identifier()' function scope.

See the attache patch.
[13 Jul 2018 14:51] Yura Sorokin
5.6 patch

(*) I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Contribution: bug91630_5_6.diff (application/octet-stream, text), 601 bytes.

[15 Jul 2018 5:59] MySQL Verification Team
Hello Yura Sorokin,

Thank you for the report and contribution.