Contributed by tj on 2016-05-12 from the his-name-was-sigurd dept.

In a recent email , Theo de Raadt explains the SROP mitigation technique, a recent team effort.

This is the first demonstration of a mitigation against SROP. Utilizing a trick from kbind(2), the kernel now only accepts signal returns from the PC address of the sigreturn(2) syscall in the signal trampoline. Since the signal trampoline page is randomized placed per process, it is only known by directly returning from a signal handler. As well, the sigcontext provided to sigreturn(2) now contains a magic cookie constructed from a per-process cookie XOR'd against the address of the signal context. That part is similar to the LWN discussion mentioned above. I came to the same conclusion semi-independently as a result of Antoine's ports builds, which identified all the parts of the application software ecosystem I had to study. Woe is me!

These two changes together make it largely impossible for a sigcontext to be constructed manually, and then passed to the kernel to act upon. sigreturn(2) becomes a highly difficult gadget to use; the setup required to utilize it means the attacker probably already has sufficient codeflow control that they don't need to utilize sigreturn(2). To make the PC tracking trick work, sigreturn(2) provision from libc will die. This is not a standard-mandated function, it is simply a back-end piece of code to make signals actually work right. A few longjmp-style routines in libc on some architectures abused sigreturn(2) have been fixed. syscall(SYS_sigreturn) also becomes illegal. The process is killed if either the cookie or the PC are wrong.

And now, the code has landed in the -current tree...

CVSROOT: /cvs Module name: src Changes by: deraadt@cvs.openbsd.org 2016/05/10 12:39:53 Modified files: sys/arch/alpha/alpha: locore.s machdep.c sys/arch/alpha/include: signal.h sys/arch/amd64/amd64: locore.S machdep.c sys/arch/amd64/include: signal.h sys/arch/arm/arm: sig_machdep.c sigcode.S sys/arch/arm/include: signal.h sys/arch/hppa/hppa: locore.S machdep.c sys/arch/hppa/include: signal.h sys/arch/hppa64/hppa64: locore.S machdep.c sys/arch/hppa64/include: signal.h sys/arch/i386/i386: locore.s machdep.c sys/arch/i386/include: signal.h sys/arch/m88k/m88k: sig_machdep.c subr.S sys/arch/macppc/macppc: locore.S machdep.c sys/arch/mips64/include: signal.h sys/arch/mips64/mips64: lcore_access.S sendsig.c sys/arch/powerpc/include: signal.h sys/arch/sh/include: signal.h sys/arch/sh/sh : locore_subr.S sh_machdep.c sys/arch/socppc/socppc: locore.S machdep.c sys/arch/sparc/include: signal.h sys/arch/sparc/sparc: machdep.c sys/arch/sparc64/include: signal.h sys/arch/sparc64/sparc64: locore.s machdep.c sys/kern : exec_elf.c init_main.c kern_exec.c sys/sys : proc.h Log message: SROP mitigation. sendsig() stores a (per-process ^ &sigcontext) cookie inside the sigcontext. sigreturn(2) checks syscall entry was from the exact PC addr in the (per-process ASLR) sigtramp, verifies the cookie, and clears it to prevent sigcontext reuse. not yet tested on landisk, sparc, *88k, socppc. ok kettenis

More information about SROP can be found in this paper.