Bug #108561 AddressSanitizer: heap-buffer-overflow in MySQL ODBC Driver
Submitted: 21 Sep 2022 8:26 Modified: 21 Sep 2022 9:24
Reporter: Zhejun Cai Email Updates:
Status: Analyzing Impact on me:
None 
Category:Connector / ODBC Severity:S3 (Non-critical)
Version:8.0.30 OS:CentOS
Assigned to: MySQL Verification Team CPU Architecture:x86

[21 Sep 2022 8:26] Zhejun Cai
Description:
Build ODBC -DWITH_ASAN=1
Enable AddressSanitizer, and access a special table, ASAN will report as blow:

By isql:

==17521==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x618000000fa1 at pc 0x2b455b7fd970 bp 0x7ffc9c493e20 sp 0x7ffc9c4935d0
READ of size 770 at 0x618000000fa1 thread T0
    #0 0x2b455b7fd96f in __interceptor_strlen ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:301
    #1 0x2b45673de297 in SQLGetData connector/odbc/mysql-connector-odbc-8.0.30-src/driver/results.cc:1572
    #2 0x2b455c734d36 in SQLGetData (/usr/lib64/libodbc.so.2+0x19d36)
    #3 0x4034e0  (/usr/bin/isql+0x4034e0)
    #4 0x404086  (/usr/bin/isql+0x404086)
    #5 0x401d94  (/usr/bin/isql+0x401d94)
    #6 0x2b455d215554 in __libc_start_main (/usr/lib64/libc.so.6+0x22554)
    #7 0x402b97  (/usr/bin/isql+0x402b97)

0x618000000fa1 is located 0 bytes to the right of 801-byte region [0x618000000c80,0x618000000fa1)
allocated by thread T0 here:
    #0 0x2b455b83e750 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x2b45673f1047 in my_malloc(unsigned int, unsigned long, int) connector/odbc/mysql-connector-odbc-8.0.30-src/mysql_sys/my_malloc.cc:198

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:301 in __interceptor_strlen

Application Using otl:
=================================================================
==42215==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6080001a5c80 at pc 0x2aabfcd94970 bp 0x7ffd1c9f6b10 sp 0x7ffd1c9f62c0
READ of size 65 at 0x6080001a5c80 thread T0
    #0 0x2aabfcd9496f in __interceptor_strlen ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:301
    #1 0x2aac3b335357 in fill_fetch_buffers connector/odbc/mysql-connector-odbc-8.0.30-src/driver/results.cc:1885
    #2 0x2aac3b337301 in my_SQLExtendedFetch(void*, unsigned short, long, unsigned long*, unsigned short*, bool) connector/odbc/mysql-connector-odbc-8.0.30-src/driver/results.cc:2454
    #3 0x2aac3b337b0f in SQLFetchScroll connector/odbc/mysql-connector-odbc-8.0.30-src/driver/results.cc:2616
    #4 0x2aabfea66094 in SQLFetchScroll (/usr/lib64/libodbc.so.2+0x17094)
    #5 0x2aac0787a1c3 in odbc::otl_sel::first(odbc::otl_cur&, int&, int&, int&, int&, int) /otl/otl.4.0.455.h:14900
    #6 0x2aac0787a1c3 in otl_tmpl_select_cursor<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur, odbc::otl_var, odbc::otl_sel>::first() otl/otl.4.0.455.h:6954
    #7 0x2aac0787a1c3 in otl_tmpl_select_cursor<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur, odbc::otl_var, odbc::otl_sel>::first() otl/otl.4.0.455.h:6950
    #8 0x2aac0787a1c3 in otl_tmpl_select_stream<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur, odbc::otl_var, odbc::otl_sel, tagTIMESTAMP_STRUCT>::rewind() otl/otl.4.0.455.h:7344
    #9 0x2aac09e46a57 in otl_tmpl_select_stream<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur, odbc::otl_var, odbc::otl_sel, tagTIMESTAMP_STRUCT>::get_in_next() otl/otl.4.0.455.h:8264
    #10 0x2aac09e46a57 in otl_tmpl_select_stream<odbc::otl_exc, odbc::otl_conn, odbc::otl_cur, odbc::otl_var, odbc::otl_sel, tagTIMESTAMP_STRUCT>::operator<<(char const*) otl/otl.4.0.455.h:8331
    #11 0x2aac09e46a57 in odbc::otl_stream::operator<<(char const*) otl/otl.4.0.455.h:18454

How to repeat:
1.Create table
CREATE TABLE `t4` (
  `f1` decimal(10,0) NOT NULL,
  `f2` varchar(600) DEFAULT NULL,
  `f3` varchar(768) DEFAULT NULL,
  `f4` varchar(256) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;

2.Insert
INSERT INTO `t4` VALUES (1401,'111','',NULL),(1001,'222',NULL,NULL);

3.Config ODBC
[my_test]
Driver        = /xxx/lib/libmyodbc8w.so
Description  = Connector/ODBC 5 Driver DSN
SERVER       = 127.0.0.1
PORT         = 10036
USER         = mysql
Password     = mysql
Database     = test
Charset      = UTF8
OPTION       = 3
SOCKET       =
TraceFile  = /tmp/odbc.trace
Trace      = 1

4.isql
LD_PRELOAD=/xxxx/gcc-8.3.0/lib64/libasan.so.5.0.0 isql my_test

SQL> use test
SQLRowCount returns 0
SQL> select * from t4;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| f1         | f2                                                                                                                                                                                                                                                                                                          | f3                                                                                                                                                                                                                                                                                                          | f4                                                                                                                                                                                                                                                              |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
=================================================================
==27132==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x618000000fa1 at pc 0x2b03cdd81970 bp 0x7ffd684c9db0 sp 0x7ffd684c9560
READ of size 770 at 0x618000000fa1 thread T0
    #0 0x2b03cdd8196f in __interceptor_strlen ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:301
    #1 0x2b03d99de297 in SQLGetData /data01/jtxnrkj/aidb_v5_dev/for_mysql/connector/odbc/mysql-connector-odbc-8.0.30-src/driver/results.cc:1572
    #2 0x2b03cecb8d36 in SQLGetData (/usr/lib64/libodbc.so.2+0x19d36)
    #3 0x4034e0  (/usr/bin/isql+0x4034e0)
    #4 0x404086  (/usr/bin/isql+0x404086)
    #5 0x401d94  (/usr/bin/isql+0x401d94)
    #6 0x2b03cf799554 in __libc_start_main (/usr/lib64/libc.so.6+0x22554)
    #7 0x402b97  (/usr/bin/isql+0x402b97)

0x618000000fa1 is located 0 bytes to the right of 801-byte region [0x618000000c80,0x618000000fa1)
allocated by thread T0 here:
    #0 0x2b03cddc2750 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:86
    #1 0x2b03d99f1047 in my_malloc(unsigned int, unsigned long, int) /data01/jtxnrkj/aidb_v5_dev/for_mysql/connector/odbc/mysql-connector-odbc-8.0.30-src/mysql_sys/my_malloc.cc:198

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:301 in __interceptor_strlen
Shadow bytes around the buggy address:
  0x0c307fff81a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff81b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff81c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff81d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c307fff81e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c307fff81f0: 00 00 00 00[01]fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8210: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8220: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8230: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c307fff8240: 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
==27132==ABORTING

=================================================================
But if the table with 3 fields, there is no ASAN report and every thing is fine
CREATE TABLE `t3` (
  `f1` decimal(10,0) NOT NULL,
  `f2` varchar(600) DEFAULT NULL,
  `f3` varchar(768) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
INSERT INTO `t3` VALUES (1401,'111',''),(1001,'222',NULL);

LD_PRELOAD=/xxxx/gcc-8.3.0/lib64/libasan.so.5.0.0 isql my_test

SQL> use test
SQLRowCount returns 0
SQL> select * from t3;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| f1         | f2                                                                                                                                                                                                                                                                                                          | f3                                                                                                                                                                                                                                                                                                          |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| 1401       | 111                                                                                                                                                                                                                                                                                                         |                                                                                                                                                                                                                                                                                                             |
| 1001       | 222                                                                                                                                                                                                                                                                                                         |                                                                                                                                                                                                                                                                                                             |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
SQLRowCount returns 2
2 rows fetched
SQL>