Breaking Hardware CFI with Sigreturn
Where
Main Stage
DEF CON 34
Duration
25 min
Shows how sigreturn can bypass ARM64 BTI and PAC on Linux and Android, and how it chains with COOP and coroutine attacks for code execution.
Summary
This talk examines whether hardware control-flow integrity on 64-bit ARM Linux and Android, pointer authentication for return addresses and branch target identification for indirect jumps, can be bypassed through the signal return path. The presenter explains that sigreturn restores the saved processor state, including the branch-type field that BTI checks. By crafting a signal frame with that field zeroed, an attacker can land on ordinary code gadgets without a valid landing pad.
Because forged frames must sit on the stack, the attack needs a bootstrap. The talk introduces CFI-safe stack pivots that begin on a valid landing pad, using a glibc context function and a statically linked unwinder inside Android's Bionic library. Chained frames then loop through gadgets and sigreturn calls. The presenter also shows composition with COOP, which abuses C++ virtual calls, and with C++20 coroutine frames, whose resume pointer can be overwritten. This reduces the need to control the first argument and cuts the memory used by the frames.
A live demo on an Ubuntu server on AWS ARM hardware with BTI and PAC enabled used a heap overflow to scan a 256 KB buffer for a random secret, which the exploit then recovered. The practical takeaway is that BTI and PAC do not close these reuse paths on current Linux systems, and the presenter suggests the issue may be hard to fix.
Materials
Related talks
Main Stage·44 min
Vladimir Tokarev
Shows three ways to write attacker-chosen return addresses into Linux shadow stacks, undermining Intel CET and ARM GCS backward-edge protection.
Main Stage·37 min
Daniel Hillel · Noam Trobishi
Shows how a use-after-free in the NVIDIA Linux kernel module lets an unprivileged container user escape to root on the host.
Main Stage·37 min
Can Ozian · Kagan Capar
Follows a mistriaged PHP fuzzer crash from a core Zend use-after-free to a command run on stock PHP despite ASLR and disable_functions.


