OpenBSD Journal

SROP mitigation committed

Contributed by tj on 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...

Module name:	src
Changes by:	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.

(Comments are closed)

      1. By Just Another OpenBSD User ( on

        > Oops, guess that's mips64. I was thinking kernel, not application arch.

        With these think powers start fresh in the media (sock-puppet(eer)) business. The journal comments are not your strongest ((handi)cap)ability.


Copyright © - Daniel Hartmeier. All rights reserved. Articles and comments are copyright their respective authors, submission implies license to publish on this web site. Contents of the archive prior to as well as images and HTML templates were copied from the fabulous original with Jose's and Jim's kind permission. This journal runs as CGI with httpd(8) on OpenBSD, the source code is BSD licensed. undeadly \Un*dead"ly\, a. Not subject to death; immortal. [Obs.]