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
48 lines
1.9 KiB
Plaintext
48 lines
1.9 KiB
Plaintext
#
|
|
# MDEV-39146 Fix stack-use-after-return in PROCESSLIST for event threads
|
|
#
|
|
CREATE USER definer@localhost;
|
|
GRANT EVENT ON *.* TO definer@localhost;
|
|
GRANT SUPER ON *.* TO definer@localhost;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
# Per-session DEBUG_SYNC: must arm from inside the event body (its own
|
|
# thd), not from another connection.
|
|
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|
|
|
Warnings:
|
|
Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it.
|
|
SET GLOBAL event_scheduler= ON;
|
|
# Connect 'waiter' now: iterate() holds server_threads' rwlock for the
|
|
# whole scan; connecting after would deadlock (needs that lock's
|
|
# write side).
|
|
connect waiter, localhost, root,,;
|
|
connection default;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR definer_ctx_active';
|
|
# Pause right after processlist_callback() captures the
|
|
# 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';
|
|
# Filter by name: checks the value read through the captured pointer.
|
|
SELECT user, host FROM information_schema.processlist WHERE user = 'definer';
|
|
connection waiter;
|
|
SET DEBUG_SYNC= 'now WAIT_FOR scanner_captured';
|
|
# Let the event finish and execute() return.
|
|
SET DEBUG_SYNC= 'now SIGNAL event_may_finish WAIT_FOR event_execute_returned TIMEOUT 60';
|
|
# Release the scanner to dereference the pointer it captured.
|
|
SET DEBUG_SYNC= 'now SIGNAL let_scanner_continue';
|
|
disconnect waiter;
|
|
connection default;
|
|
user host
|
|
definer localhost
|
|
SET SESSION debug_dbug= @saved_dbug;
|
|
SET DEBUG_SYNC= 'RESET';
|
|
SET GLOBAL event_scheduler= OFF;
|
|
DROP USER definer@localhost;
|
|
# End of 10.11 tests
|