RFC arm64: Signal context expansion
Get series with b4
b4 am [email protected]Versions newest first
- v1 RFC Latest0 of 5 patches 0 repliesNew
Patches in v1 No applies recorded yet
None of the 5 patches the cover letter announces are in this archive.
Reviews trailers per patch
No Reviewed-by, Acked-by or Tested-by trailers for v1 yet.
Cover letter [RFC PATCH 0/5] arm64: Signal context expansion
Quoted 49 lines · Dave Martin
Quoted 13 lines · Florian Weimer
Quoted 11 lines · Dave Martin
Quoted 6 lines
Do you add this extra information only if the stack is sufficiently large?
x86_64adds the new information even for small stacks set up with sigaltstack, leading to memory corruption on bleeding-edge hardware:Hmmm, not yet. We already check that the whole frame is writable user memory, but this isn't sufficient to avoid user corruption in the case of alternate signal stacks. I'll fix this -- thanks for flagging it.
Quoted 5 lines
Quoted 2 lines
If the stack isn't large enough, we'll still have to SEGV the task though.
You could skip copying the data and not install a pointer to it in the existing signal context.
We could, but then we'd corrupt the task state in sigreturn, since we wouldn't have been able to save/restore part of the state.
Quoted 7 lines
Quoted 2 lines
We can (and should) bump up the SIG{,MIN}STKSZ constants when adding the SVE support proper to the kernel,
That's a userspace ABI change (libraries use these constants to size struct members), and not a good idea. You might get away with at this stage, but you can't do this every time you add some new process state you want to add to signal handlers.
For internal interfaces within a single component that's tolerable, since a single value would be used for each of these constants throughout the build of that component.
A quick search on sources.debian.org suggests that the total number of packages that expose {,MIN}SIGSTKSZ dependent definitions in their public interfaces is small (I couldn't find any after paging through dozens of pages of results -- so the total is maybe in the range 0-10) -- hopefully few enough to eyeball.
Quoted 2 lines
Quoted 2 lines
I wonder whether we should make the signal stack size runtime discoverable through
sysconf()instead...I will likely suggest this for the future, but of course it doesn't help for current binaries.
Quoted 9 lines
Note that MINSIGSTKSZ stared life wrong for arm64, and has since gone through a few ABI breaking changes. I don't condone this, but we have form in this area :/
sigaltstack()already fails with ENOMEM for software that passesss_size= MINSIGSTKSZ, and is built against glibc<2.22 [1], [2], running on linux>=4.3 [3], which is an ABI break in case wheresigaltstack()is otherwise guaranteed to succeed.
yes, this was abi breaking change.
if glibc does not care about existing binaries that use sigaltstack with MINSIGSTKSZ then it can increase the size, but i think the kernel should not change the abi (there are other libcs and libc independent runtime systems on linux for aarch64 with their own sigaltstack setup, not all of them may care about SVE).
i assume the kernel can avoid saving SVE regs when they are not used by the process.
Quoted 5 lines
The bottom line here is that the
sigaltstack()API is broken with regard to extensibility, so we cannot extend the amount of signal state without breaking something.
extending signal state can break things independently of sigaltstack.
binaries with strict guarantees about worst case stack usage can change behaviour.
fortunately glibc PTHREAD_STACK_MIN is huge on aarch64 so applications using it are unlikely to break because of the increased signal state.
(this also means it's impossible to have threads with tiny stacks on glibc, so large amount of threads means large amount of commit charge.)
Quoted 47 lines
The least-wrong thing I can think of to do is:
* deprecate but continue to support the existing sigaltstack API/ABI with today's {,MIN}SIGSTKSZ definitions
* guarantee (as much as possible) that software using this ABI continues to work (by saving/restoring only data that _must_ be saved/restored at each signal, which may be small enough to fit)
* providing a clean failure mode (fatal signal) when this proves impossible at signal delivery/return time;
* define a new interface for runtime-querying the required signal stack size;
* define a new syscall or new stack_t.ss_flags flags (say,
SS_STRICT) that permits the kernel to enforce a runtime-determined minimum greater than MINSIGSTKSZ when callingsigaltstack().Another option would be:
* define a new interface for runtime-querying the required signal stack size, and
* support the current API/ABI, but make a call to
sigaltstack()SEGV or SIGILL the caller if it specifiesss_stack>= MINSIGSTKSZ but smaller than the actual runtime minimum.(this would cause old software to break immediately in an obvious way on new systems, forcing people to fix their software -- which they might or might not actually bother to do).
Thoughts?
Cheers
---Dave[1] https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b763f6ae859ecea70a5dacb8ad45c71d5f667e2e