1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00
Files
mariadb/mysql-test/main/events_debug.test
forkfun 85ecdbe546 MDEV-39146 Fix stack-use-after-return in PROCESSLIST for event threads
Event_job_data::execute() pointed thd->security_ctx at a local
Security_context. A concurrent PROCESSLIST scan captures that pointer
without a lock and can read it after execute() returns.

Make the Security_context a member of Event_job_data, which lives in
Event_worker_thread::run() until after thd is deleted.

Add main.events_debug test
2026-10-19 11:34:03 +02:00

69 lines
2.2 KiB
Plaintext

--source include/have_debug.inc
--source include/have_debug_sync.inc
--source include/not_embedded.inc
--echo #
--echo # MDEV-39146 Fix stack-use-after-return in PROCESSLIST for event threads
--echo #
CREATE USER definer@localhost;
GRANT EVENT ON *.* TO definer@localhost;
GRANT SUPER ON *.* TO definer@localhost;
SET DEBUG_SYNC= 'RESET';
--echo # Per-session DEBUG_SYNC: must arm from inside the event body (its own
--echo # thd), not from another connection.
--delimiter |
CREATE DEFINER=definer@localhost EVENT ev
ON SCHEDULE AT CURRENT_TIMESTAMP
DO
BEGIN
SET DEBUG_SYNC= 'event_worker_thread_after_execute_returned SIGNAL event_execute_returned';
SET DEBUG_SYNC= 'now SIGNAL definer_ctx_active WAIT_FOR event_may_finish';
END|
--delimiter ;
SET GLOBAL event_scheduler= ON;
--echo # Connect 'waiter' now: iterate() holds server_threads' rwlock for the
--echo # whole scan; connecting after would deadlock (needs that lock's
--echo # write side).
connect (waiter, localhost, root,,);
connection default;
SET DEBUG_SYNC= 'now WAIT_FOR definer_ctx_active';
--echo # Pause right after processlist_callback() captures the
--echo # DEFINER-switched security_ctx, before USER/HOST are read.
SET @saved_dbug= @@SESSION.debug_dbug;
SET SESSION debug_dbug= '+d,processlist_callback_pause_after_sctx_capture';
SET DEBUG_SYNC= 'processlist_callback_captured_sctx SIGNAL scanner_captured WAIT_FOR let_scanner_continue';
--echo # Filter by name: checks the value read through the captured pointer.
--send SELECT user, host FROM information_schema.processlist WHERE user = 'definer'
connection waiter;
SET DEBUG_SYNC= 'now WAIT_FOR scanner_captured';
--echo # Let the event finish and execute() return.
SET DEBUG_SYNC= 'now SIGNAL event_may_finish WAIT_FOR event_execute_returned TIMEOUT 60';
--echo # Release the scanner to dereference the pointer it captured.
SET DEBUG_SYNC= 'now SIGNAL let_scanner_continue';
--disconnect waiter
--connection default
--reap
SET SESSION debug_dbug= @saved_dbug;
SET DEBUG_SYNC= 'RESET';
SET GLOBAL event_scheduler= OFF;
--source include/check_events_off.inc
let $count_sessions= 1;
--source include/wait_until_count_sessions.inc
DROP USER definer@localhost;
--echo # End of 10.11 tests