[MDEV-26115] Crash when calling stored function in FOR loop argument Created: 2021-07-08  Updated: 2023-12-11

Status: Confirmed
Project: MariaDB Server
Component/s: Stored routines
Affects Version/s: 10.4.14, 10.5.10, 10.6.3, 10.3, 10.4, 10.5, 10.6
Fix Version/s: 10.4, 10.5, 10.6, 10.11, 11.0, 11.1, 11.2

Type: Bug Priority: Critical
Reporter: Anders Karlsson Assignee: Dmitry Shulga
Resolution: Unresolved Votes: 1
Labels: crash
Environment:

Linux CentOS 7.7


Issue Links:
Duplicate
is duplicated by MDEV-32850 MariaDB got crash when call procedure Closed
Relates
relates to MDEV-23902 MariaDB crash on calling function Closed

 Description   

When a stored function is used to provide the upper bound of a FOR loop, the server crashes. Example:

delimiter //
 
CREATE OR REPLACE FUNCTION cnt()
RETURNS INTEGER
NO SQL
BEGIN
   RETURN 1;
END;
//
 
CREATE OR REPLACE PROCEDURE p1()
NO SQL
BEGIN
   DECLARE i INTEGER;
   FOR i IN 1..cnt() DO
      SELECT i;
   END FOR;
END;
//

Calling this will crash the server on the second attempt:

MariaDB [test]> CALL p1();
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0.002 sec)
 
Query OK, 0 rows affected (0.002 sec)
 
MariaDB [test]> CALL p1();
ERROR 2013 (HY000): Lost connection to MySQL server during query

The effect is the same when using SQL_MODE=Oracle and when using FOR loops outside a stored procedure, like this:

MARIADB> delimiter //
MARIADB> BEGIN NOT ATOMIC
DECLARE i INTEGER;
FOR i IN 1..cnt() DO
  SELECT i;
END FOR;
END;
//
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    4
Current database: test
 
+---+
| i |
+---+
| 1 |
+---+
1 row in set (0.014 sec)
 
ERROR 2013 (HY000): Lost connection to MySQL server during query



 Comments   
Comment by Alice Sherepa [ 2021-07-12 ]

Thanks!
Repeatable on 10.3-10.6 (also test is applicable only from 10.3)

CREATE FUNCTION cnt () RETURNS INT RETURN 1;
 
delimiter //;
CREATE PROCEDURE p1()
BEGIN
   DECLARE i int;
   FOR i IN 1..cnt() DO SELECT i;
   END FOR;
END;
//
 
delimiter ;//
 
CALL p1();
CALL p1();

10.3 3fbe30024ff0b4e3f6e6302

Version: '10.3.31-MariaDB-debug-log'  
=================================================================
==77853==ERROR: AddressSanitizer: heap-use-after-free on address 0x625000145518 at pc 0x55b600480482 bp 0x7fea6b5d69b0 sp 0x7fea6b5d69a0
READ of size 8 at 0x625000145518 thread T27
    #0 0x55b600480481 in Item_sp::cleanup() /10.3/src/sql/item.cc:2866
    #1 0x55b6005ab0cd in Item_func_sp::cleanup() /10.3/src/sql/item_func.cc:6353
    #2 0x55b5ffc9c460 in cleanup_items(Item*) /10.3/src/sql/sql_parse.cc:1160
    #3 0x55b5ffa831eb in sp_head::execute(THD*, bool) /10.3/src/sql/sp_head.cc:1468
    #4 0x55b5ffa88d72 in sp_head::execute_procedure(THD*, List<Item>*) /10.3/src/sql/sp_head.cc:2404
    #5 0x55b5ffca8051 in do_execute_sp /10.3/src/sql/sql_parse.cc:3019
    #6 0x55b5ffca9c2d in Sql_cmd_call::execute(THD*) /10.3/src/sql/sql_parse.cc:3259
    #7 0x55b5ffcbdfdc in mysql_execute_command(THD*) /10.3/src/sql/sql_parse.cc:6075
    #8 0x55b5ffcca307 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.3/src/sql/sql_parse.cc:7870
    #9 0x55b5ffca11d8 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.3/src/sql/sql_parse.cc:1852
    #10 0x55b5ffc9dd1b in do_command(THD*) /10.3/src/sql/sql_parse.cc:1398
    #11 0x55b60006ca16 in do_handle_one_connection(CONNECT*) /10.3/src/sql/sql_connect.cc:1403
    #12 0x55b60006c2d0 in handle_one_connection /10.3/src/sql/sql_connect.cc:1308
    #13 0x55b60169f36a in pfs_spawn_thread /10.3/src/storage/perfschema/pfs.cc:1869
    #14 0x7fea81ec7608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
    #15 0x7fea81dee292 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122292)
 
0x625000145518 is located 1048 bytes inside of 8268-byte region [0x625000145100,0x62500014714c)
freed by thread T27 here:
    #0 0x7fea8282d7cf in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10d7cf)
    #1 0x55b6017ea9b5 in free_memory /10.3/src/mysys/safemalloc.c:279
    #2 0x55b6017e9f71 in sf_free /10.3/src/mysys/safemalloc.c:197
    #3 0x55b6017b82a8 in my_free /10.3/src/mysys/my_malloc.c:223
    #4 0x55b601794a18 in free_root /10.3/src/mysys/my_alloc.c:430
    #5 0x55b5ffa832e4 in sp_head::execute(THD*, bool) /10.3/src/sql/sp_head.cc:1482
    #6 0x55b5ffa88d72 in sp_head::execute_procedure(THD*, List<Item>*) /10.3/src/sql/sp_head.cc:2404
    #7 0x55b5ffca8051 in do_execute_sp /10.3/src/sql/sql_parse.cc:3019
    #8 0x55b5ffca9c2d in Sql_cmd_call::execute(THD*) /10.3/src/sql/sql_parse.cc:3259
    #9 0x55b5ffcbdfdc in mysql_execute_command(THD*) /10.3/src/sql/sql_parse.cc:6075
    #10 0x55b5ffcca307 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.3/src/sql/sql_parse.cc:7870
    #11 0x55b5ffca11d8 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.3/src/sql/sql_parse.cc:1852
    #12 0x55b5ffc9dd1b in do_command(THD*) /10.3/src/sql/sql_parse.cc:1398
    #13 0x55b60006ca16 in do_handle_one_connection(CONNECT*) /10.3/src/sql/sql_connect.cc:1403
    #14 0x55b60006c2d0 in handle_one_connection /10.3/src/sql/sql_connect.cc:1308
    #15 0x55b60169f36a in pfs_spawn_thread /10.3/src/storage/perfschema/pfs.cc:1869
    #16 0x7fea81ec7608 in start_thread /build/glibc-eX1tMB/glibc-2.31/nptl/pthread_create.c:477
 
previously allocated by thread T27 here:
    #0 0x7fea8282dbc8 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x55b6017e9925 in sf_malloc /10.3/src/mysys/safemalloc.c:118
    #2 0x55b6017b77b1 in my_malloc /10.3/src/mysys/my_malloc.c:101
    #3 0x55b60179381e in alloc_root /10.3/src/mysys/my_alloc.c:251
    #4 0x55b5ff9ef831 in Query_arena::alloc(unsigned long) /10.3/src/sql/sql_class.h:1033
    #5 0x55b5ffb46ca4 in lock_tables(THD*, TABLE_LIST*, unsigned int, unsigned int) /10.3/src/sql/sql_base.cc:5381
    #6 0x55b5ffb45255 in open_and_lock_tables(THD*, DDL_options_st const&, TABLE_LIST*, bool, unsigned int, Prelocking_strategy*) /10.3/src/sql/sql_base.cc:5128
    #7 0x55b5ffaa9389 in open_and_lock_tables(THD*, TABLE_LIST*, bool, unsigned int) /10.3/src/sql/sql_base.h:503
    #8 0x55b5ffb5e2ed in open_system_tables_for_read(THD*, TABLE_LIST*, Open_tables_backup*) /10.3/src/sql/sql_base.cc:8927
    #9 0x55b600834770 in open_proc_table_for_read(THD*, Open_tables_backup*) /10.3/src/sql/sp.cc:486
    #10 0x55b600836476 in Sp_handler::db_find_routine(THD*, Database_qualified_name const*, sp_head**) const /10.3/src/sql/sp.cc:696
    #11 0x55b600836f96 in Sp_handler::db_find_and_cache_routine(THD*, Database_qualified_name const*, sp_head**) const /10.3/src/sql/sp.cc:767
    #12 0x55b600845e45 in Sp_handler::sp_cache_routine(THD*, Database_qualified_name const*, bool, sp_head**) const /10.3/src/sql/sp.cc:2788
    #13 0x55b600845990 in Sroutine_hash_entry::sp_cache_routine(THD*, bool, sp_head**) const /10.3/src/sql/sp.cc:2741
    #14 0x55b5ffb3bb9e in open_and_process_routine /10.3/src/sql/sql_base.cc:3362
    #15 0x55b5ffb40358 in open_tables(THD*, DDL_options_st const&, TABLE_LIST**, unsigned int*, unsigned int, Prelocking_strategy*) /10.3/src/sql/sql_base.cc:4262
    #16 0x55b5ffb45139 in open_and_lock_tables(THD*, DDL_options_st const&, TABLE_LIST*, bool, unsigned int, Prelocking_strategy*) /10.3/src/sql/sql_base.cc:5119
    #17 0x55b5ffaa9389 in open_and_lock_tables(THD*, TABLE_LIST*, bool, unsigned int) /10.3/src/sql/sql_base.h:503
    #18 0x55b5ffa90e80 in sp_instr::exec_open_and_lock_tables(THD*, TABLE_LIST*) /10.3/src/sql/sp_head.cc:3549
    #19 0x55b5ffa904ad in sp_lex_keeper::reset_lex_and_exec_core(THD*, unsigned int*, bool, sp_instr*) /10.3/src/sql/sp_head.cc:3429
    #20 0x55b5ffa91f38 in sp_instr_set::execute(THD*, unsigned int*) /10.3/src/sql/sp_head.cc:3718
    #21 0x55b5ffa82d85 in sp_head::execute(THD*, bool) /10.3/src/sql/sp_head.cc:1377
    #22 0x55b5ffa88d72 in sp_head::execute_procedure(THD*, List<Item>*) /10.3/src/sql/sp_head.cc:2404
    #23 0x55b5ffca8051 in do_execute_sp /10.3/src/sql/sql_parse.cc:3019
    #24 0x55b5ffca9c2d in Sql_cmd_call::execute(THD*) /10.3/src/sql/sql_parse.cc:3259
    #25 0x55b5ffcbdfdc in mysql_execute_command(THD*) /10.3/src/sql/sql_parse.cc:6075
    #26 0x55b5ffcca307 in mysql_parse(THD*, char*, unsigned int, Parser_state*, bool, bool) /10.3/src/sql/sql_parse.cc:7870
    #27 0x55b5ffca11d8 in dispatch_command(enum_server_command, THD*, char*, unsigned int, bool, bool) /10.3/src/sql/sql_parse.cc:1852
    #28 0x55b5ffc9dd1b in do_command(THD*) /10.3/src/sql/sql_parse.cc:1398
    #29 0x55b60006ca16 in do_handle_one_connection(CONNECT*) /10.3/src/sql/sql_connect.cc:1403
 
Thread T27 created by T0 here:
    #0 0x7fea8275a805 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
    #1 0x55b60169f75b in spawn_thread_v1 /10.3/src/storage/perfschema/pfs.cc:1919
    #2 0x55b5ff9c732e in inline_mysql_thread_create /10.3/src/include/mysql/psi/mysql_thread.h:1275
    #3 0x55b5ff9e010d in create_thread_to_handle_connection(CONNECT*) /10.3/src/sql/mysqld.cc:6664
    #4 0x55b5ff9e08a8 in create_new_thread /10.3/src/sql/mysqld.cc:6734
    #5 0x55b5ff9e1a4b in handle_connections_sockets() /10.3/src/sql/mysqld.cc:6992
    #6 0x55b5ff9df3fe in mysqld_main(int, char**) /10.3/src/sql/mysqld.cc:6286
    #7 0x55b5ff9c5b2c in main /10.3/src/sql/main.cc:25
    #8 0x7fea81cf30b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
 
SUMMARY: AddressSanitizer: heap-use-after-free /10.3/src/sql/item.cc:2866 in Item_sp::cleanup()
Shadow bytes around the buggy address:
  0x0c4a80020a50: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020a60: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020a70: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020a80: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020a90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
=>0x0c4a80020aa0: fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020ab0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020ac0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020ad0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020ae0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c4a80020af0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
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
  Shadow gap:              cc
==77853==ABORTING
----------SERVER LOG END-------------

Comment by Oleksandr Byelkin [ 2021-09-20 ]

freed sp_result_field, I remember there was such bug somewhere.

Comment by Shawn Yan [ 2023-11-21 ]

the similar bug MDEV-32850, still exists in the latest mariadb 10.6.16.

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