[MDEV-31060] UBSAN: runtime error: member access within null pointer of type 'struct st_my_thread_var' Created: 2023-04-16  Updated: 2023-11-28

Status: Confirmed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB, XA
Affects Version/s: 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 11.0, 11.1
Fix Version/s: 10.6, 10.11, 11.0

Type: Bug Priority: Major
Reporter: Roel Van de Paar Assignee: Sergei Petrunia
Resolution: Unresolved Votes: 0
Labels: UBSAN, regression-10.6

Issue Links:
Issue split
split from MDEV-23073 LSAN: Memory leak after XA transactio... Confirmed
Relates
relates to MDEV-31061 ASAN: global-buffer-overflow in __int... Open

 Description   

Null pointer access split from MDEV-23073: please note the UBSAN error (member access within null pointer) towards the end of the stack trace. marko mentions that this looks like it is related to accessing my_errno in my_read():

#define my_errno my_thread_var->thr_errno

InnoDB should not use my_read() for anything. Assigning to thiru as he is assigned to MDEV-23073, but please feel free to reassign as needed. Note that MTR is required to reproduce the issue.

--source include/have_innodb.inc
CREATE TABLE t (c TEXT) ENGINE=InnoDB;
XA BEGIN '0';
INSERT INTO t VALUES (b'');
SAVEPOINT sp0;
XA END '0';
XA PREPARE '0';
SHUTDOWN;

Leads to:

11.0.2 a79abb6517f2fa68b48e61aa3354a0631e3a63f7 (Debug)

==1492049==ERROR: LeakSanitizer: detected memory leaks
 
Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x5614b49d2337 in __interceptor_malloc (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x7986337)
    #1 0x5614b8949ebf in trx_savepoint_for_mysql(trx_t*, char const*, long) /test/10.11_dbg_san/storage/innobase/trx/trx0roll.cc:523
    #2 0x5614b812d690 in innobase_savepoint /test/10.11_dbg_san/storage/innobase/handler/ha_innodb.cc:4910
    #3 0x5614b69e7bd4 in ha_savepoint(THD*, st_savepoint*) /test/10.11_dbg_san/sql/handler.cc:2952
    #4 0x5614b5d9e3d6 in trans_savepoint(THD*, st_mysql_const_lex_string) /test/10.11_dbg_san/sql/transaction.cc:617
    #5 0x5614b5336acd in mysql_execute_command(THD*, bool) /test/10.11_dbg_san/sql/sql_parse.cc:5711
    #6 0x5614b5344c73 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.11_dbg_san/sql/sql_parse.cc:8002
    #7 0x5614b53549cf in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.11_dbg_san/sql/sql_parse.cc:1894
    #8 0x5614b5362799 in do_command(THD*, bool) /test/10.11_dbg_san/sql/sql_parse.cc:1407
    #9 0x5614b5d076dd in do_handle_one_connection(CONNECT*, bool) /test/10.11_dbg_san/sql/sql_connect.cc:1416
    #10 0x5614b5d08bf8 in handle_one_connection /test/10.11_dbg_san/sql/sql_connect.cc:1318
    #11 0x14b8d76f1b42 in start_thread nptl/pthread_create.c:442
 
Indirect leak of 11 byte(s) in 1 object(s) allocated from:
    #0 0x5614b49d2337 in __interceptor_malloc (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x7986337)
    #1 0x5614b8949ed6 in mem_strdup /test/10.11_dbg_san/storage/innobase/include/mem0mem.inl:452
    #2 0x5614b8949ed6 in trx_savepoint_for_mysql(trx_t*, char const*, long) /test/10.11_dbg_san/storage/innobase/trx/trx0roll.cc:525
    #3 0x5614b812d690 in innobase_savepoint /test/10.11_dbg_san/storage/innobase/handler/ha_innodb.cc:4910
    #4 0x5614b69e7bd4 in ha_savepoint(THD*, st_savepoint*) /test/10.11_dbg_san/sql/handler.cc:2952
    #5 0x5614b5d9e3d6 in trans_savepoint(THD*, st_mysql_const_lex_string) /test/10.11_dbg_san/sql/transaction.cc:617
    #6 0x5614b5336acd in mysql_execute_command(THD*, bool) /test/10.11_dbg_san/sql/sql_parse.cc:5711
    #7 0x5614b5344c73 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.11_dbg_san/sql/sql_parse.cc:8002
    #8 0x5614b53549cf in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.11_dbg_san/sql/sql_parse.cc:1894
    #9 0x5614b5362799 in do_command(THD*, bool) /test/10.11_dbg_san/sql/sql_parse.cc:1407
    #10 0x5614b5d076dd in do_handle_one_connection(CONNECT*, bool) /test/10.11_dbg_san/sql/sql_connect.cc:1416
    #11 0x5614b5d08bf8 in handle_one_connection /test/10.11_dbg_san/sql/sql_connect.cc:1318
    #12 0x14b8d76f1b42 in start_thread nptl/pthread_create.c:442
 
SUMMARY: AddressSanitizer: 51 byte(s) leaked in 2 allocation(s).
230401 12:21:47 [ERROR] mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
 
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
 
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed, 
something is definitely wrong and this may fail.
 
Server version: 10.11.3-MariaDB-debug source revision: 50c8ef01fc63e32acd38788107ae4029d0f1b9ce
read_buffer_size=131072
max_used_connections=1
thread_count=0
Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x0 thread_stack 0x100000
/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd(+0x79176fe)[0x5614b49636fe]
asan_interceptors.o:0(__interceptor_backtrace.part.0)[0x5614b9110f2a]
mysys/stacktrace.c:215(my_print_stacktrace)[0x5614b69beee2]
libc_sigaction.c:0(__restore_rt)[0x14b8d769f520]
nptl/pthread_kill.c:44(__pthread_kill_implementation)[0x14b8d76f3a7c]
posix/raise.c:27(__GI_raise)[0x14b8d769f476]
stdlib/abort.c:81(__GI_abort)[0x14b8d76857f3]
:0(__sanitizer::Abort())[0x5614b49f01c2]
:0(__sanitizer::Die())[0x5614b49fbd7c]
:0(__lsan::HandleLeaks())[0x5614b4a0128c]
:0(__lsan::DoLeakCheck())[0x5614b4a009d5]
stdlib/cxa_finalize.c:84(__cxa_finalize)[0x14b8d76a2a56]
crtstuff.c:0(__do_global_dtors_aux)[0x5614b49426a7]
The manual page at https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains
information that should help you find out what is causing the crash.
Writing a core file...
Working directory at /test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/data
Resource Limits:
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            unlimited            unlimited            bytes     
Max core file size        unlimited            unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             unlimited            unlimited            processes 
Max open files            1048576              1048576              files     
Max locked memory         unlimited            unlimited            bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       unlimited            unlimited            signals   
Max msgqueue size         unlimited            unlimited            bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us        
Core pattern: core
 
/test/10.11_dbg_san/mysys/my_read.c:63:30: runtime error: member access within null pointer of type 'struct st_my_thread_var'
    #0 0x5614b91073ea in my_read /test/10.11_dbg_san/mysys/my_read.c:63
    #1 0x5614b69be35f in output_core_info /test/10.11_dbg_san/sql/signal_handler.cc:91
    #2 0x5614b69bf7a7 in handle_fatal_signal /test/10.11_dbg_san/sql/signal_handler.cc:353
    #3 0x14b8d769f51f  (/lib/x86_64-linux-gnu/libc.so.6+0x4251f)
    #4 0x14b8d76f3a7b in __pthread_kill_implementation nptl/pthread_kill.c:43
    #5 0x14b8d76f3a7b in __pthread_kill_internal nptl/pthread_kill.c:78
    #6 0x14b8d76f3a7b in __GI___pthread_kill nptl/pthread_kill.c:89
    #7 0x14b8d769f475 in __GI_raise ../sysdeps/posix/raise.c:26
    #8 0x14b8d76857f2 in __GI_abort stdlib/abort.c:79
    #9 0x5614b49f01c1 in __sanitizer::Abort() (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x79a41c1)
    #10 0x5614b49fbd7b in __sanitizer::Die() (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x79afd7b)
    #11 0x5614b4a0128b in __lsan::HandleLeaks() (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x79b528b)
    #12 0x5614b4a009d4 in __lsan::DoLeakCheck() (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x79b49d4)
    #13 0x14b8d76a2a55 in __cxa_finalize stdlib/cxa_finalize.c:83
    #14 0x5614b49426a6  (/test/UBASAN_MD250323-mariadb-10.11.3-linux-x86_64-dbg/bin/mariadbd+0x78f66a6)
 
Fatal signal 11 while backtracing

10.8.8 e4b83f0febbd24b04687d4814871c758cbede111 (Debug, UBASAN)

==1441451==ERROR: LeakSanitizer: detected memory leaks
 
Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x55d408967337 in malloc (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x788d337)
    #1 0x55d40c8833f1 in trx_savepoint_for_mysql(trx_t*, char const*, long) /test/10.8_dbg_san/storage/innobase/trx/trx0roll.cc:523
    #2 0x55d40c070f72 in innobase_savepoint /test/10.8_dbg_san/storage/innobase/handler/ha_innodb.cc:4928
    #3 0x55d40a93a3da in ha_savepoint(THD*, st_savepoint*) /test/10.8_dbg_san/sql/handler.cc:2951
    #4 0x55d409d0a48d in trans_savepoint(THD*, st_mysql_const_lex_string) /test/10.8_dbg_san/sql/transaction.cc:617
    #5 0x55d4092bc2a5 in mysql_execute_command(THD*, bool) /test/10.8_dbg_san/sql/sql_parse.cc:5702
    #6 0x55d4092ca518 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.8_dbg_san/sql/sql_parse.cc:8019
    #7 0x55d4092da25e in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.8_dbg_san/sql/sql_parse.cc:1894
    #8 0x55d4092e8028 in do_command(THD*, bool) /test/10.8_dbg_san/sql/sql_parse.cc:1407
    #9 0x55d409c738ef in do_handle_one_connection(CONNECT*, bool) /test/10.8_dbg_san/sql/sql_connect.cc:1416
    #10 0x55d409c74e0a in handle_one_connection /test/10.8_dbg_san/sql/sql_connect.cc:1318
    #11 0x14bd6a711b42 in start_thread nptl/pthread_create.c:442
 
Indirect leak of 11 byte(s) in 1 object(s) allocated from:
    #0 0x55d408967337 in malloc (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x788d337)
    #1 0x55d40c883408 in mem_strdup /test/10.8_dbg_san/storage/innobase/include/mem0mem.inl:452
    #2 0x55d40c883408 in trx_savepoint_for_mysql(trx_t*, char const*, long) /test/10.8_dbg_san/storage/innobase/trx/trx0roll.cc:525
    #3 0x55d40c070f72 in innobase_savepoint /test/10.8_dbg_san/storage/innobase/handler/ha_innodb.cc:4928
    #4 0x55d40a93a3da in ha_savepoint(THD*, st_savepoint*) /test/10.8_dbg_san/sql/handler.cc:2951
    #5 0x55d409d0a48d in trans_savepoint(THD*, st_mysql_const_lex_string) /test/10.8_dbg_san/sql/transaction.cc:617
    #6 0x55d4092bc2a5 in mysql_execute_command(THD*, bool) /test/10.8_dbg_san/sql/sql_parse.cc:5702
    #7 0x55d4092ca518 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /test/10.8_dbg_san/sql/sql_parse.cc:8019
    #8 0x55d4092da25e in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool) /test/10.8_dbg_san/sql/sql_parse.cc:1894
    #9 0x55d4092e8028 in do_command(THD*, bool) /test/10.8_dbg_san/sql/sql_parse.cc:1407
    #10 0x55d409c738ef in do_handle_one_connection(CONNECT*, bool) /test/10.8_dbg_san/sql/sql_connect.cc:1416
    #11 0x55d409c74e0a in handle_one_connection /test/10.8_dbg_san/sql/sql_connect.cc:1318
    #12 0x14bd6a711b42 in start_thread nptl/pthread_create.c:442
 
SUMMARY: AddressSanitizer: 51 byte(s) leaked in 2 allocation(s).
230401 12:21:03 [ERROR] mysqld got signal 6 ;
This could be because you hit a bug. It is also possible that this binary
or one of the libraries it was linked against is corrupt, improperly built,
or misconfigured. This error can also be caused by malfunctioning hardware.
 
To report this bug, see https://mariadb.com/kb/en/reporting-bugs
 
We will try our best to scrape up some info that will hopefully help
diagnose the problem, but since we have already crashed, 
something is definitely wrong and this may fail.
 
Server version: 10.8.8-MariaDB-debug source revision: e4b83f0febbd24b04687d4814871c758cbede111
read_buffer_size=131072
max_used_connections=1
thread_count=0
Thread pointer: 0x0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
stack_bottom = 0x0 thread_stack 0x100000
/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd(+0x781e6fe)[0x55d4088f86fe]
asan_interceptors.o:0(__interceptor_backtrace.part.0)[0x55d40d04b4de]
mysys/stacktrace.c:215(my_print_stacktrace)[0x55d40a9116cc]
libc_sigaction.c:0(__restore_rt)[0x14bd6a6bf520]
nptl/pthread_kill.c:44(__pthread_kill_implementation)[0x14bd6a713a7c]
posix/raise.c:27(__GI_raise)[0x14bd6a6bf476]
stdlib/abort.c:81(__GI_abort)[0x14bd6a6a57f3]
:0(__sanitizer::Abort())[0x55d4089851c2]
:0(__sanitizer::Die())[0x55d408990d7c]
:0(__lsan::HandleLeaks())[0x55d40899628c]
:0(__lsan::DoLeakCheck())[0x55d4089959d5]
stdlib/cxa_finalize.c:84(__cxa_finalize)[0x14bd6a6c2a56]
crtstuff.c:0(__do_global_dtors_aux)[0x55d4088d76a7]
The manual page at https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/ contains
information that should help you find out what is causing the crash.
Writing a core file...
Working directory at /test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/data
Resource Limits:
Limit                     Soft Limit           Hard Limit           Units     
Max cpu time              unlimited            unlimited            seconds   
Max file size             unlimited            unlimited            bytes     
Max data size             unlimited            unlimited            bytes     
Max stack size            unlimited            unlimited            bytes     
Max core file size        unlimited            unlimited            bytes     
Max resident set          unlimited            unlimited            bytes     
Max processes             unlimited            unlimited            processes 
Max open files            1048576              1048576              files     
Max locked memory         unlimited            unlimited            bytes     
Max address space         unlimited            unlimited            bytes     
Max file locks            unlimited            unlimited            locks     
Max pending signals       unlimited            unlimited            signals   
Max msgqueue size         unlimited            unlimited            bytes     
Max nice priority         0                    0                    
Max realtime priority     0                    0                    
Max realtime timeout      unlimited            unlimited            us        
Core pattern: core
 
/test/10.8_dbg_san/mysys/my_read.c:63:30: runtime error: member access within null pointer of type 'struct st_my_thread_var'
    #0 0x55d40d04199e in my_read /test/10.8_dbg_san/mysys/my_read.c:63
    #1 0x55d40a910b49 in output_core_info /test/10.8_dbg_san/sql/signal_handler.cc:91
    #2 0x55d40a911f91 in handle_fatal_signal /test/10.8_dbg_san/sql/signal_handler.cc:353
    #3 0x14bd6a6bf51f  (/lib/x86_64-linux-gnu/libc.so.6+0x4251f)
    #4 0x14bd6a713a7b in __pthread_kill_implementation nptl/pthread_kill.c:43
    #5 0x14bd6a713a7b in __pthread_kill_internal nptl/pthread_kill.c:78
    #6 0x14bd6a713a7b in __GI___pthread_kill nptl/pthread_kill.c:89
    #7 0x14bd6a6bf475 in __GI_raise ../sysdeps/posix/raise.c:26
    #8 0x14bd6a6a57f2 in __GI_abort stdlib/abort.c:79
    #9 0x55d4089851c1 in __sanitizer::Abort() (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x78ab1c1)
    #10 0x55d408990d7b in __sanitizer::Die() (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x78b6d7b)
    #11 0x55d40899628b in __lsan::HandleLeaks() (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x78bc28b)
    #12 0x55d4089959d4 in __lsan::DoLeakCheck() (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x78bb9d4)
    #13 0x14bd6a6c2a55 in __cxa_finalize stdlib/cxa_finalize.c:83
    #14 0x55d4088d76a6  (/test/UBASAN_MD250323-mariadb-10.8.8-linux-x86_64-dbg/bin/mariadbd+0x77fd6a6)
 
Fatal signal 11 while backtracing

Setup:

Compiled with GCC >=7.5.0 (I use GCC 11.3.0) and:
    -DWITH_ASAN=ON -DWITH_ASAN_SCOPE=ON -DWITH_UBSAN=ON -DWITH_RAPID=OFF -DWSREP_LIB_WITH_ASAN=ON
Set before execution:
    export ASAN_OPTIONS=quarantine_size_mb=512:atexit=0:detect_invalid_pointer_pairs=3:dump_instruction_bytes=1:abort_on_error=1:allocator_may_return_null=1

Bug confirmed present in:
MariaDB: 10.6.13 (dbg), 10.6.13 (opt), 10.7.8 (dbg), 10.7.8 (opt), 10.8.8 (dbg), 10.8.8 (opt), 10.9.6 (dbg), 10.9.6 (opt), 10.10.4 (dbg), 10.10.4 (opt), 10.11.3 (dbg), 10.11.3 (opt), 11.0.2 (dbg), 11.0.2 (opt)

Bug (or feature/syntax) confirmed not present in:
MariaDB: 10.3.39 (dbg), 10.3.39 (opt), 10.4.29 (dbg), 10.4.29 (opt), 10.5.20 (dbg), 10.5.20 (opt)



 Comments   
Comment by Roel Van de Paar [ 2023-04-16 ]
  • The testcase requires MTR (does not reproduce at CLI).
  • Both testcases from MDEV-23073 yield both the LSAN memory leak and the UBSAN null pointer access.
  • Additional testing shows that the null pointer access only happens in 10.6+, unlike the memory loss of MDEV-23073 which is 10.5+
Comment by Daniel Black [ 2023-04-16 ]

The segfault in output_core_info (not innodb) was fixed in MDEV-30613 (94ed30e505f8a6d9dca8a2006f6dfced1bff9dec) (because of the my_read / my_errno macro).

So is the leak different from MDEV-23073?

Comment by Marko Mäkelä [ 2023-04-17 ]

The leak looks like a duplicate of MDEV-23073.

Thank you, danblack, for identifying the likely fix. It has been merged to 10.11 so far. psergei is working on a merge to 11.0.

Generated at Thu Feb 08 10:20:58 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.