[MDEV-19380] ASAN heap-use-after-free in Protocol::net_store_data Created: 2019-05-01  Updated: 2019-12-17  Resolved: 2019-12-11

Status: Closed
Project: MariaDB Server
Component/s: Optimizer - Window functions
Affects Version/s: 10.2, 10.3, 10.4
Fix Version/s: 10.2.31, 10.3.22, 10.4.12

Type: Bug Priority: Major
Reporter: Alice Sherepa Assignee: Varun Gupta (Inactive)
Resolution: Fixed Votes: 0
Labels: None


 Description   

CREATE TABLE t1 (i int);
INSERT INTO t1 VALUES (1),(2),(3);
 
SELECT (SELECT MIN('foo') OVER () FROM t1 LIMIT 1);

10.2 810f014ca7a705381e110cb2664

==14283==ERROR: AddressSanitizer: heap-use-after-free on address 0x6190000f8dea at pc 0x7f8196a54935 bp 0x7f817e383b30 sp 0x7f817e3832d8
READ of size 3 at 0x6190000f8dea thread T27
    #0 0x7f8196a54934 in __asan_memcpy (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x8c934)
    #1 0x558870257c6e in Protocol::net_store_data(unsigned char const*, unsigned long) /10.2/sql/protocol.cc:61
    #2 0x55887025d849 in Protocol::store_string_aux(char const*, unsigned long, charset_info_st const*, charset_info_st const*) /10.2/sql/protocol.cc:1092
    #3 0x55887025e009 in Protocol_text::store(char const*, unsigned long, charset_info_st const*) /10.2/sql/protocol.cc:1129
    #4 0x558870a461be in Item::send(Protocol*, String*) /10.2/sql/item.cc:6893
    #5 0x55887025cf85 in Protocol::send_result_set_row(List<Item>*) /10.2/sql/protocol.cc:979
    #6 0x5588703771bf in select_send::send_data(List<Item>&) /10.2/sql/sql_class.cc:2722
    #7 0x5588704c8f06 in JOIN::exec_inner() /10.2/sql/sql_select.cc:3500
    #8 0x5588704c7d83 in JOIN::exec() /10.2/sql/sql_select.cc:3419
    #9 0x5588704cb0d0 in mysql_select(THD*, TABLE_LIST*, unsigned int, List<Item>&, Item*, unsigned int, st_order*, st_order*, Item*, st_order*, unsigned long long, select_result*, st_select_lex_unit*, st_select_lex*) /10.2/sql/sql_select.cc:3819
    #10 0x5588704aa80e in handle_select(THD*, LEX*, select_result*, unsigned long) /10.2/sql/sql_select.cc:376
    #11 0x558870432322 in execute_sqlcom_select /10.2/sql/sql_parse.cc:6479
    #12 0x55887041f7e8 in mysql_execute_command(THD*) /10.2/sql/sql_parse.cc:3537
    #13 0x55887043aa86 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.2/sql/sql_parse.cc:8013
    #14 0x55887041613b in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.2/sql/sql_parse.cc:1833
    #15 0x5588704132ba in do_command(THD*) /10.2/sql/sql_parse.cc:1387
    #16 0x55887073bce5 in do_handle_one_connection(CONNECT*) /10.2/sql/sql_connect.cc:1335
    #17 0x55887073b6ed in handle_one_connection /10.2/sql/sql_connect.cc:1241
    #18 0x5588718efa71 in pfs_spawn_thread /10.2/storage/perfschema/pfs.cc:1862
    #19 0x7f819592a6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
    #20 0x7f8194dbf41c in clone (/lib/x86_64-linux-gnu/libc.so.6+0x10741c)



 Comments   
Comment by Varun Gupta (Inactive) [ 2019-12-10 ]

Patch
http://lists.askmonty.org/pipermail/commits/2019-December/014096.html

Comment by Sergei Petrunia [ 2019-12-11 ]

Take-aways from yesterday discussion:

The bug happens because of the following: Item_cache_str::cache_value() calls this:

  value= example->str_result(&value_buff);

The window function makes the passed string object (value_buff) to point to an area in a temporary table's record buffer.
Then, the temporary table is freed, together with its record buffer.
Then, Item_cache_str attempts to read the value.

The cause of the problem is that Item_cache_str::cache_value returns control while Item_cache_str::value_buff is left having its pointer pointing to a string somewhere.

The fix is to call value_buff.copy(). This will make the value_buff to store its string in a buffer that it owns, which will not disappear unexpectedly.

Comment by Sergei Petrunia [ 2019-12-11 ]

like so:

diff --git a/sql/item.cc b/sql/item.cc
index 333d71ddf70..10087ef1974 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -10044,6 +10044,8 @@ bool Item_cache_str::cache_value()
     value_buff.copy(*value);
     value= &value_buff;
   }
+  else
+    value_buff.copy();
   return TRUE;
 }
 

Generated at Thu Feb 08 08:51:14 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.