atrosinenko wrote: By the way, it should probably be feasible to fix the oracle in `stepThroughSigReturn` purely in userspace (in libc): instead of directly passing user-provided signal handler to the kernel, libc could store this handler in its private ptrauth-protected handler table and pass a trampoline function to the kernel instead: * Before: `sigaction(signum, act, oldact)` - pass though `act->sa_sigaction` to the kernel - pass `__restore_rt` as `sa_restorer` * After: `sigaction(signum, act, oldact)` - save `act->sa_sigaction` to libc's internal data structure - pass `__custom_signal_entry` to the kernel as `sa_sigaction` - pass `__custom_signal_exit` to the kernel as `sa_restorer` - `__custom_signal_entry` ensures sensitive registers are signed just a few instructions after userspace code is called back by the kernel, looks up actual signal handler in libc's own handler table and transfers execution to it - `__custom_signal_exit` authenticates sensitive registers just before calling `__restore_rt`. CFI information should be provided for `__custom_signal_exit`, so that it can be unwound as usual and ultimately lead the unwinder to a well-known contents of `__restore_rt` function
This would harden against [register clobbering](https://clang.llvm.org/docs/PointerAuthentication.html#register-clobbering) along the way, though careful signal masking would be probably required to protect against another signal interrupting `__custom_signal_entry` before it finishes signing sensitive registers saved by the kernel. https://github.com/llvm/llvm-project/pull/184661 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
