mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
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
69 lines
2.2 KiB
Plaintext
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
|