lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <2fb2902d-f844-d018-aa4c-94009886ad1d@torproject.org>
Date:   Wed, 2 Mar 2022 08:59:56 -0600
From:   Jim Newsome <jnewsome@...project.org>
To:     linux-kernel@...r.kernel.org
Subject: sigaltstack from signal handler succeeds but is overwritten on
 sigreturn

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?

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ