linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* sigaltstack from signal handler succeeds but is overwritten on sigreturn
@ 2022-03-02 14:59 Jim Newsome
  0 siblings, 0 replies; only message in thread
From: Jim Newsome @ 2022-03-02 14:59 UTC (permalink / raw)
  To: linux-kernel

Context: I recently came across this behavior while developing [shadow], 
where we're using seccomp to trap syscalls to an LD_PRELOAD'd signal 
handler, as a fallback for syscalls we weren't able to intercept more 
efficiently at the libc API level via LD_PRELOAD. When a new thread is 
created, we do some self-initialization on its first intercepted 
syscall, including setting up a signal stack with sigaltstack. When the 
first syscall is trapped via seccomp, this initialization happens in the 
sigsys signal handler, and the sigaltstack configuration is lost on 
return. We can work around this behavior by initializing explicitly 
immediately after returning from clone in the child thread (which is 
probably a better design anyway), but it took a while to figure out what 
was going wrong.

[shadow]: https://github.com/shadow/shadow

Here is a simplified demonstration of the issue: 
https://godbolt.org/z/Mrxe119oj

 From the [sigaltstack man page], I'd only expect sigreturn to restore 
the sigaltstack configuration if there was already a sigaltstack 
configured for the thread on entry to the handler, and it had 
SS_AUTODISARM set.

[sigaltstack man page]: 
https://man7.org/linux/man-pages/man2/sigaltstack.2.html

I discovered this on x86-64 Ubuntu and their modified kernel 
5.13.0-30-generic and am not currently set up to try reproducing on a 
vanilla kernel, but if I'm reading the source correctly, this behavior 
exists in the latest kernel, at least on x86-64. The x86-64 [sigreturn] 
always calls [restore_altstack], which always restores the old 
sigaltstack config.

[sigreturn]: 
https://github.com/torvalds/linux/blob/5bfc75d92efd494db37f5c4c173d3639d4772966/arch/x86/kernel/signal.c#L656

[restore_altstack]: 
https://github.com/torvalds/linux/blob/a4fd49cdb5495f36a35bd27b69b3806e383c719b/kernel/signal.c#L4246

Is this unconditional restore intended? If so, maybe it could be 
documented more explicitly in the sigaltstack and/or sigreturn man pages?


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-03-02 15:08 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-02 14:59 sigaltstack from signal handler succeeds but is overwritten on sigreturn Jim Newsome

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).