Defer SIGTERM/SIGINT shutdown out of the signal handler - #1925
Open
willbuckner wants to merge 1 commit into
Open
Defer SIGTERM/SIGINT shutdown out of the signal handler#1925willbuckner wants to merge 1 commit into
willbuckner wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c7b0ec9bda
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
willbuckner
force-pushed
the
will/fix-sigterm-use-after-free
branch
from
August 2, 2026 11:00
87bba21 to
c7b0ec9
Compare
Found by: michaelortmann Fixes: eggheads#1770 got_term() ran the entire shutdown sequence (Tcl callbacks, botnet messages, userfile write) directly inside the signal handler. None of that is async-signal-safe: if the signal arrives while the main program is in the middle of modifying the heap or the user list, writing the userfile reads freed memory, as caught by AddressSanitizer: heap-use-after-free in def_write_userfile <- write_user <- write_userfile <- kill_bot <- got_term Instead, set a volatile sig_atomic_t flag in the handler (the same pattern got_quit()/got_hup() use with do_restart) and perform the sigterm Tcl bind check and kill_bot() from mainloop(). Since the signal interrupts select(), the flag is acted on immediately. A second SIGTERM/SIGINT while the first is still pending or shutdown is in progress now exits immediately, so a hung bot can still be terminated.
willbuckner
force-pushed
the
will/fix-sigterm-use-after-free
branch
from
August 2, 2026 11:12
e1336a7 to
4e0628b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by: michaelortmann
Fixes: #1770
Patch by: willbuckner
One-line summary: Defer SIGTERM/SIGINT shutdown out of the signal handler
Additional description (if needed):
got_term() ran the entire shutdown sequence (Tcl callbacks, botnet messages, userfile write) directly inside the signal handler. None of that is async-signal-safe: if the signal arrives while the main program is in the middle of modifying the heap or the user list, writing the userfile reads freed memory, as caught by AddressSanitizer:
heap-use-after-free in def_write_userfile <- write_user <-
write_userfile <- kill_bot <- got_term
Instead, set a volatile sig_atomic_t flag in the handler (the same pattern got_quit()/got_hup() use with do_restart) and perform the sigterm Tcl bind check and kill_bot() from mainloop(). Since the signal interrupts select(), the flag is acted on immediately.
A second SIGTERM/SIGINT before the first is processed now exits immediately, so a hung bot can still be terminated.
Test cases demonstrating functionality (if applicable): N/A