Bug #91801 Read of free memory in mysqld_list_processes
Submitted: 26 Jul 2018 13:20 Modified: 27 Jul 2018 12:16
Reporter: Sveta Smirnova (OCA) Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Information schema Severity:S3 (Non-critical)
Version:5.6.40 OS:Any
Assigned to: CPU Architecture:Any
Tags: ASAN build

[26 Jul 2018 13:20] Sveta Smirnova
Description:
In the following scenario:

- SHOW PROCESSLIST (mysqld_list_processes) copies list of active threads, but does not print it yet
- After list is copied slave SQL thread sets query to NULL in Relay_log_info::cleanup_context  
- mysqld_list_processes accesses query and depending on the luck either prints garbage or crashes

Bug is hard to repeat with normal build, but if compiled with option WITH_ASAN=1 it fails with attached test case with:

=================================================================
==4180==ERROR: AddressSanitizer: heap-use-after-free on address 0x7fb25f4e9800 at pc 0x7fb274a974ff bp 0x7fb262ae4800 sp 0x7fb262ae3fa8
READ of size 193036 at 0x7fb25f4e9800 thread T22
    #0 0x7fb274a974fe  (/usr/lib/x86_64-linux-gnu/libasan.so.3+0x5f4fe)
    #1 0x102df87 in memcpy /usr/include/x86_64-linux-gnu/bits/string3.h:53
    #2 0x102df87 in strmake_root /home/sveta/src/mysql-server/mysys/my_alloc.c:436
    #3 0xaac41d in Query_arena::strmake(char const*, unsigned long) /home/sveta/src/mysql-server/sql/sql_class.h:782
    #4 0xaac41d in mysqld_list_processes(THD*, char const*, bool) /home/sveta/src/mysql-server/sql/sql_show.cc:2173
    #5 0x9e0da6 in mysql_execute_command(THD*) /home/sveta/src/mysql-server/sql/sql_parse.cc:3709
    #6 0x9ec676 in mysql_parse(THD*, char*, unsigned int, Parser_state*) /home/sveta/src/mysql-server/sql/sql_parse.cc:6453
    #7 0x9f13ec in dispatch_command(enum_server_command, THD*, char*, unsigned int) /home/sveta/src/mysql-server/sql/sql_parse.cc:1374
    #8 0x9f5e56 in do_command(THD*) /home/sveta/src/mysql-server/sql/sql_parse.cc:1039
    #9 0x92fb1d in do_handle_one_connection(THD*) /home/sveta/src/mysql-server/sql/sql_connect.cc:982
    #10 0x92fc14 in handle_one_connection /home/sveta/src/mysql-server/sql/sql_connect.cc:899
    #11 0x171e711 in pfs_spawn_thread /home/sveta/src/mysql-server/storage/perfschema/pfs.cc:1861
    #12 0x7fb273fd96b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #13 0x7fb27346241c in clone (/lib/x86_64-linux-gnu/libc.so.6+0x10741c)

0x7fb25f4e9800 is located 0 bytes inside of 193037-byte region [0x7fb25f4e9800,0x7fb25f518a0d)
freed by thread T25 here:
    #0 0x7fb274afeb60 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc6b60)
    #1 0x103ba32 in my_free /home/sveta/src/mysql-server/mysys/my_malloc.c:140
    #2 0xec0612 in Rows_query_log_event::~Rows_query_log_event() /home/sveta/src/mysql-server/sql/log_event.cc:13618
    #3 0xec063c in Rows_query_log_event::~Rows_query_log_event() /home/sveta/src/mysql-server/sql/log_event.cc:13619
    #4 0xfd4ed4 in Relay_log_info::cleanup_context(THD*, bool) /home/sveta/src/mysql-server/sql/rpl_rli.cc:1535
    #5 0xeca5dc in rows_event_stmt_cleanup /home/sveta/src/mysql-server/sql/log_event.cc:11797
    #6 0xef9d90 in Rows_log_event::do_apply_event(Relay_log_info const*) /home/sveta/src/mysql-server/sql/log_event.cc:11676
    #7 0xeddae4 in Log_event::apply_event(Relay_log_info*) /home/sveta/src/mysql-server/sql/log_event.cc:3118
    #8 0xfa0489 in apply_event_and_update_pos(Log_event**, THD*, Relay_log_info*) /home/sveta/src/mysql-server/sql/rpl_slave.cc:3934
    #9 0xfaaf32 in exec_relay_log_event /home/sveta/src/mysql-server/sql/rpl_slave.cc:4429
    #10 0xfb1fbe in handle_slave_sql /home/sveta/src/mysql-server/sql/rpl_slave.cc:6326
    #11 0x171e711 in pfs_spawn_thread /home/sveta/src/mysql-server/storage/perfschema/pfs.cc:1861
    #12 0x7fb273fd96b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)

...

Version 5.7 is not affected

How to repeat:
cmake ../mysql-server/ -DCMAKE_INSTALL_PREFIX="/home/sveta/build/msyql-5.6" -DWITH_DEBUG=1 -DDOWNLOAD_BOOST=1 -DDOWNLOAD_BOOST_TIMEOUT=1800 -DWITH_BOOST="/home/sveta/src/mysql-5.6/boost" -DENABLE_DTRACE=0 -DWITH_ROCKSDB=0 -DWITH_ASAN=1
ASAN_OPTIONS="detect_leaks=0" make -j4 install
export ASAN_OPTIONS="detect_leaks=0"
cd /home/sveta/build/mysql-5.6/mysql-test

Copy attached *test and *opt files into t directory
Copy attached sysbench_async.sh and oltp_rw.lua into some directory(s)
Make sure you have sysbench at lease version 1.1 (otherwise lua test won't work)
Edit paths in *test and sysbench_async.sh, so they point to correct locations in your system

chmod 755 sysbench_async.sh
./mtr rpl_PS-4475.test

Practically Lua script content does not matter a lot, just more SHOW PROCESSLIST iterations and longer queries increase chances to repeat the issue.
[26 Jul 2018 13:20] Sveta Smirnova
test case for MTR

Attachment: rpl_PS-4475.test (application/octet-stream, text), 920 bytes.

[26 Jul 2018 13:21] Sveta Smirnova
Option file for master

Attachment: rpl_PS-4475-master.opt (application/octet-stream, text), 110 bytes.

[26 Jul 2018 13:21] Sveta Smirnova
Option file for slave

Attachment: rpl_PS-4475-slave.opt (application/octet-stream, text), 133 bytes.

[26 Jul 2018 13:21] Sveta Smirnova
script which calls SysBench from MTR asynchronously

Attachment: sysbench_async.sh (application/x-shellscript, text), 1024 bytes.

[26 Jul 2018 13:22] Sveta Smirnova
Lua script

Attachment: oltp_rw.lua (text/x-lua), 689 bytes.

[26 Jul 2018 13:31] Sveta Smirnova
Suggested fix: backport fix from version 5.7.

diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc
index f2e4dc2..c01c1cf 100644
--- a/sql/rpl_rli.cc
+++ b/sql/rpl_rli.cc
@@ -1532,9 +1532,9 @@ void Relay_log_info::cleanup_context(THD *thd, bool error)
   }
   if (rows_query_ev)
   {
+    info_thd->reset_query();
     delete rows_query_ev;
     rows_query_ev= NULL;
-    info_thd->set_query(NULL, 0);
   }
   m_table_map.clear_tables();
   slave_close_thread_tables(thd);
[27 Jul 2018 12:04] MySQL Verification Team
Hello Sveta,

Thank you for the report.
Verified as described.

regards,
Umesh
[27 Jul 2018 12:05] MySQL Verification Team
5.6.40 Build details + Test results

Attachment: 91630_5.6.40.results (application/octet-stream, text), 21.38 KiB.

[27 Jul 2018 12:06] MySQL Verification Team
Hi Sveta,

Please ensure to re-send the patch via "Contribution" tab. Otherwise we would not be able to accept it.

regards,
Umesh
[27 Jul 2018 12:16] Sveta Smirnova
Umesh,

this is not real contribution. This is just pointer on what changed in version 5.7. This is not my code, this is Oracle's code =) 

It looks like this issue was discovered by internal QA and fixed in 5.7, but not in 5.6.
[27 Jul 2018 12:21] MySQL Verification Team
Okay :)

regards,
umesh