Sigreturn-oriented programming (SROP) is acomputer security exploit technique that allows an attacker to execute code in presence of security measures such asnon-executable memory and code signing.[1] It was presented for the first time at the 35thIEEE Symposium on Security and Privacy in 2014 where it won thebest student paper award.[2] This technique employs the same basic assumptions behind thereturn-oriented programming (ROP) technique: an attacker controlling thecall stack, for example through astack buffer overflow, is able to influence thecontrol flow of the program through simple instruction sequences calledgadgets. The attack works bypushing a forgedsigcontext structure[3] on the call stack, overwriting the original return address with the location of a gadget that allows the attacker to call thesigreturn[4]system call.[5] Often just a single gadget is needed to successfully put this attack into effect. This gadget may reside at a fixed location, making this attack simple and effective, with a setup generally simpler and more portable than the one needed by the plain return-oriented programming technique.[1]
Sigreturn-oriented programming can be considered aweird machine since it allows code execution outside the original specification of the program.[1]
Sigreturn-oriented programming (SROP) is a technique similar to return-oriented programming (ROP), since it employscode reuse to execute code outside the scope of the original control flow. In this sense, the adversary needs to be able to carry out astack smashing attack, usually through a stack buffer overflow, to overwrite the return address contained inside the call stack.
If mechanisms such asdata execution prevention are employed, it won't be possible for the attacker to just place ashellcode on the stack and cause the machine to execute it by overwriting the return address. With such protections in place, the machine won't execute any code present in memory areas marked as writable and non-executable. Therefore, the attacker will need to reuse code already present in memory.
Most programs do not contain functions that will allow the attacker to directly carry out the desired action (e.g., obtain access to ashell), but the necessary instructions are often scattered around memory.[6]
Return-oriented programming requires these sequences of instructions, called gadgets, to end with aRET instruction. In this way, the attacker can write a sequence of addresses for these gadgets to the stack, and as soon as aRET instruction in one gadget is executed, the control flow will proceed to the next gadget in the list.

This attack is made possible by howsignals are handled in mostPOSIX-like systems. Whenever a signal is delivered, the kernel needs tocontext switch to the installed signal handler. To do so, the kernel saves the current execution context in a frame on the stack.[5][6] The structure pushed onto the stack is an architecture-specific variant of thesigcontext structure, which holds various data comprising the contents of the registers at the moment of the context switch. When the execution of the signal handler is completed, thesigreturn() system call is called.
Calling thesigreturn syscall means being able to easily set the contents of registers using a single gadget that can be easily found on most systems.[1]
There are several factors that characterize an SROP exploit and distinguish it from a classical return-oriented programming exploit.[7]
First, ROP is dependent on available gadgets, which can be very different in distinctbinaries, thus making chains of gadget non-portable.Address space layout randomization (ASLR) makes it hard to use gadgets without aninformation leakage to get their exact positions in memory.
AlthoughTuring-complete ROP compilers exist,[8] it is usually non-trivial to create a ROP chain.[7]
SROP exploits are usually portable across different binaries with minimal or no effort and allow easily setting the contents of the registers, which could be non-trivial or unfeasible for ROP exploits if the needed gadgets are not present.[6] Moreover, SROP requires a minimal number of gadgets and allows constructing effective shellcodes by chaining system calls. These gadgets are always present in memory, and in some cases are always at fixed locations:[7]
| OS | ASLR | Gadget | Memory Map | Fixed Memory Location |
|---|---|---|---|---|
| Linux i386 | sigreturn | [vdso] | ||
| Linux < 3.11 ARM | sigreturn | [vectors] | 0xffff0000 | |
| Linux < 3.3 x86-64 | syscall&return | [vsyscall] | 0xffffffffff600000 | |
| Linux ≥ 3.3 x86-64 | syscall&return | Libc | ||
| Linux x86-64 | sigreturn | Libc | ||
| FreeBSD 9.2 x86-64 | sigreturn | 0x7ffffffff000 | ||
| Mac OSX x86-64 | sigreturn | Libc | ||
| iOS ARM | sigreturn | Libsystem | ||
| iOS ARM | syscall & return | Libsystem |
An example of the kind of gadget needed for SROP exploits can always be found in thevirtual dynamic shared object (VDSO) memory area on x86-Linux systems:
__kernel_sigreturnprocnear:popeaxmoveax,77hint80h; LINUX - sys_sigreturnnopleaesi,[esi+0]__kernel_sigreturnendp
On someLinux kernel versions, ASLR can be disabled by setting the limit for the stack size to unlimited,[9] effectively bypassing ASLR and allowing easy access to the gadget present in a VDSO.
For Linux kernels prior to version 3.3, it is also possible to find a suitable gadget inside the vsyscall page, which is a mechanism to accelerate the access to certain system calls often used by legacy programs and resides always at a fixed location.
It is possible to use gadgets to write into the contents of the stack frames, thereby constructing aself-modifying program. Using this technique, it is possible to devise a simplevirtual machine, which can be used as the compilation target for aTuring-complete language. An example of such an approach can be found in Bosman's paper, which demonstrates the construction of an interpreter for a language similar to theBrainfuck programming language. The language provides a program counterPC, a memory pointerP, and a temporary register used for 8-bit additionA. This means that complexbackdoors or obfuscated attacks can also be devised.[1]
A number of techniques exists to mitigate SROP attacks, relying onaddress space layout randomization,canaries andcookies, orshadow stacks.
Address space layout randomization makes it harder to use suitable gadgets by making their locations unpredictable.
A mitigation for SROP calledsignal cookies has been proposed. It consists of a way of verifying that the sigcontext structure has not been tampered with by the means of a random cookieXORed with the address of the stack location where it is to be stored. In this way, thesigreturn syscall just needs to verify the cookie's existence at the expected location, effectively mitigating SROP with a minimal impact on performances.[1][10]
In Linux kernel versions greater than 3.3, the vsyscall interface is emulated, and any attempt to directly execute gadgets in the page will result in an exception.[11][12]
Grsecurity is a set of patches for theLinux kernel to harden and improve system security.[13] It includes the so-called return-address protection (RAP) to help protect against code reuse attacks.[14]
Starting in 2016,Intel is developing aControl-flow Enforcement Technology (CET) to help mitigate and prevent stack-hopping exploits. CET works by implementing a shadow stack in RAM which will only contain return addresses, protected by the CPU'smemory management unit.[15][16]