Rust's signal stack should be guarded against overflow #69533
Labels
A-runtime
Area: std's runtime and "pre-main" init for handling backtraces, unwinds, stack overflows
C-enhancement
Category: An issue proposing an enhancement or a PR with one.
T-libs-api
Relevant to the library API team, which will review and decide on the PR/issue.
Rust's runtime installs a
SIGSEGV
signal handler to distinguish stack overflows from other faults. This requires using an alternate signal stack (sigaltstack
), which we create with the default sizeSIGSTKSZ
. That's usually quite small, 8KB or so depending on the target, but it's still plenty for what theSIGSEGV
handler is doing. There's currently no guard page like we have on normal stacks.That alternate stack is shared by all signals for a thread, so if a user installs any other signal handler, and they opt in with the flag
SA_ONSTACK
, they'll be limited to the same tiny stack. If their handler happens to be more involved and overflows that stack, it may silently clobber other memory. If we had a guard page on the signal stack, that would cause a process abort instead.This was reported to the Security Response WG with a reproducer in this repo. However, after discussion we decided to treat this as a normal issue for a few reasons:
unsafe
code.signal-safety(7)
.SA_ONSTACK
for signals other thanSIGSEGV
, and if you choose so, you also bear responsibility to make sure that stack suffices.Nevertheless, as a defensive measure, it's still a reasonable idea to map a
PROT_NONE
guard page when Rust is creating its signal stack, so an unexpected overflow will abort rather than silently corrupting memory. For full protection, that would also depend on the guard page not being skipped, but not all targets have stack probes yet (#43241).Thanks to @eust for reporting this in accordance with our security policy, even though we have decided not to treat this as a security issue at this time.
cc @rust-lang/security
The text was updated successfully, but these errors were encountered: