Description:
The server crashes with SIGSEGV in Item_sum::add_used_tables_for_aggr_func() when a stored procedure executes a cached statement that contains an aggregate inside an EXISTS subquery, after a session variable affecting that aggregate's prepare-time metadata (e.g. group_concat_max_len) is changed between calls.
The variable change forces a reprepare of the cached SP statement:
* validate_lex_and_execute_core() calls free_lex() (releasing the old item arena, including the aggregate Item) and then re-parses the expression.
* The new query block is parsed but never resolved — m_first_execution is set to true, m_saved_base_items is empty, leaf_tables is nullptr.
* Despite that, sp_lex_instr::execute_expression() still invokes Query_block::restore_cmd_properties(), which recurses into the unresolved EXISTS subquery and calls update_used_tables() over a field list that still references the freed aggregate Item — a use-after-free, manifesting as a SIGSEGV when Item_sum::add_used_tables_for_aggr_func() dereferences base_query_block.
// Crash signature in mysql 8.4.10
2026-06-16T21:07:02Z UTC - mysqld got signal 11 ;
Signal SIGSEGV (Address not mapped to object) at address 0x320
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
BuildID[sha1]=5dec4dc319fbee88f4663559ae92333a7e41273e
Thread pointer: 0x7f2da00128b0
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 = 7f2e003f1be0 thread_stack 0x100000
#0 0x7f2e1843ebef <unknown> at sysdeps/unix/sysv/linux/x86_64/libc_sigaction.c:0
#1 0xd34b8e Query_block::all_tables_map() const at mysql-8.4.10/sql/sql_lex.h:1260
#2 0xd34b8e Item_sum::add_used_tables_for_aggr_func() at mysql-8.4.10/sql/item_sum.cc:853
#3 0xd34b8e Item_sum::update_used_tables() at mysql-8.4.10/sql/item_sum.cc:800
#4 0xe6af52 Query_block::update_used_tables() at mysql-8.4.10/sql/sql_resolver.cc:922
#5 0xe6aa88 Query_expression::restore_cmd_properties() at mysql-8.4.10/sql/sql_lex.cc:4032
#6 0xe6ad5d Query_block::restore_cmd_properties() at mysql-8.4.10/sql/sql_lex.cc:4975
#7 0xe6aa88 Query_expression::restore_cmd_properties() at mysql-8.4.10/sql/sql_lex.cc:4032
#8 0xe67956 LEX::restore_cmd_properties() at mysql-8.4.10/sql/sql_lex.h:4509
#9 0xe67956 sp_lex_instr::execute_expression(THD*, unsigned int*) at mysql-8.4.10/sql/sp_instr.cc:369
#10 0xe6231c sp_lex_instr::reset_lex_and_exec_core(THD*, unsigned int*, bool) at mysql-8.4.10/sql/sp_instr.cc:463
#11 0xe61c48 sp_lex_instr::validate_lex_and_execute_core(THD*, unsigned int*, bool) at mysql-8.4.10/sql/sp_instr.cc:767
#12 0xe60200 sp_lex_instr::execute(THD*, unsigned int*) at mysql-8.4.10/sql/sp_instr.h:334
#13 0xe60200 sp_head::execute(THD*, bool) at mysql-8.4.10/sql/sp_head.cc:2244
#14 0x12e0128 sp_head::execute_procedure(THD*, mem_root_deque<Item*>*) at mysql-8.4.10/sql/sp_head.cc:3117
#15 0x12dfb9e Sql_cmd_call::execute_inner(THD*) at mysql-8.4.10/sql/sql_call.cc:233
#16 0xcd8a1d Sql_cmd_dml::execute(THD*) at mysql-8.4.10/sql/sql_select.cc:782
#17 0xb7d920 mysql_execute_command(THD*, bool) at mysql-8.4.10/sql/sql_parse.cc:4739
#18 0xd6ddb4 dispatch_sql_command(THD*, Parser_state*) at mysql-8.4.10/sql/sql_parse.cc:5406
#19 0xd69f67 dispatch_command(THD*, COM_DATA const*, enum_server_command) at mysql-8.4.10/sql/sql_parse.cc:2136
#20 0xd65939 do_command(THD*) at mysql-8.4.10/sql/sql_parse.cc:1465
#21 0xd54450 handle_connection at mysql-8.4.10/sql/conn_handler/connection_handler_per_thread.cc:304
#22 0x104bba1 pfs_spawn_thread at mysql-8.4.10/storage/perfschema/pfs.cc:3067
#23 0x7f2e1848a4a9 start_thread at /usr/src/debug/glibc-2.34-196.amzn2023.0.1.x86_64/nptl/pthread_create.c:443
#24 0x7f2e1850f50f clone3 at sysdeps/unix/sysv/linux/x86_64/clone3.S:81
#25 0xffffffffffffffff <unknown>
Trying to get some variables.
Some pointers may be invalid and cause the dump to abort.
Query (7f2da0148960): CALL bug_test.test_proc2
Connection ID (thread ID): 10
Status: NOT_KILLED
The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains
information that should help you find out what is causing the crash.
How to repeat:
CREATE DATABASE IF NOT EXISTS bug_test;
USE bug_test;
DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
value VARCHAR(20) DEFAULT NULL,
modified INT UNSIGNED NOT NULL,
status INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (value)
) ENGINE=InnoDB
CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
DROP PROCEDURE IF EXISTS bug_test.test_proc2;
DELIMITER $$
CREATE PROCEDURE bug_test.test_proc2()
BEGIN
IF NOT EXISTS (
SELECT GROUP_CONCAT(value) FROM test_table
) THEN
SELECT 1;
ELSE
SELECT 2;
END IF;
END$$
DELIMITER ;
SET SESSION group_concat_max_len = 1500;
CALL bug_test.test_proc2; -- 1st call: prepares & caches the IF expression
SET SESSION group_concat_max_len = 16384;
CALL bug_test.test_proc2; -- 2nd call: forces reprepare -> SIGSEGV
Result: client receives `ERROR 2013 (HY000): Lost connection to MySQL server during query` on the 2nd call; server restarts.
Suggested fix:
In `sql/sp_instr.cc`, function `sp_lex_instr::execute_expression()`, the guard around `restore_cmd_properties()` should also test `m_first_execution`. After a forced reparse the SP runtime sets `m_first_execution = true` to signal "treat as first execution"; the existing guard ignores that and runs restore on a never-resolved LEX, which dereferences a freed Item from the prior arena.
```cpp
- if (m_arena.get_state() != Query_arena::STMT_INITIALIZED_FOR_SP) {
+ if (!m_first_execution &&
+ m_arena.get_state() != Query_arena::STMT_INITIALIZED_FOR_SP) {
m_lex->restore_cmd_properties();
bind_fields(m_arena.item_list());
}
```
Rationale: `m_first_execution == true` -> `exec_core()` has not run on this LEX -> the LEX has not been resolved/optimized -> nothing was ever saved by `save_cmd_properties()`. In that state, restore must be skipped and `exec_core()` must (re)resolve the statement from scratch which is exactly what already happens on a genuine first execution (the safe path).