Missing mitigations
This is a small arbitrary list of cools and/or interesting mitigations that OpenBSD doesn’t have.
Kernel stack protections
In December 2002, pipacs published RANDKSTACK, randomizing each task’s kernel stack pointer before returning from a system call to userland.
In 2011, Jon Oberheide and Dan Rosenberg presented STACKJACKING - your way to
grsec/pax
bypass
at Infiltrate, along with a
blogpost,
prompting pipacs and spender to move thread_info
out of the kernel stack,
port RANDKSTACK to amd64, improve PAX_USERCOPY
, …
But RANDKSTACK
could make things worse, as highlighted in the followup
presentation at SummerCon 11, Stackjacking and Other Kernel
Nonsense,
as well as in the accompanying blogpost.
In response, based on Jon Oberheide and Dan Rosenberg’s recommendations, pipacs
implemented PAX_MEMORY_STACKLEAK
, to erase completely the kernel stack after
each syscall.
In August 2017, Theo de Raadt
added
a small random offset to each process’ kernel stack. This can be bypassed
with the kstack self-discovery
technique, as explained in the STACKJACKING
slides, if you have a kernel stack memory disclosure, which aren’t
uncommon. By the way, this isn’t the only trick from this slide deck that can
be applied to OpenBSD ;)
In October 2017, Alexander Popov tried to
upstream
a custom version of PAX_MEMORY_STACKLEAK
in Linux. It was
merged
in September 2018, after a lot of
back-and-forth.
SEGVGUARD/GRKERNSEC_KERN_\LOCKOUT/GRKERNSEC_BRUTE
segvguard was created by Rafal (Nergal) Wojtczuk around 2001, and discussed in his The advanced return-into-lib(c) exploits: PaX case study Phrack article. It’s a daemon notified by the kernel every time a process crashes with a SIGSEGV, able to temporarily disable the execution of the crashing programs, thwarting bruteforce-based ASLR bypass.
In 2002, spender implemented GRKERNSEC_BRUTE
:
When a child of a forking daemon is killed by PaX or crashes due to an illegal instruction or other suspicious signal, the parent process will be delayed 30 seconds upon every subsequent fork until the administrator is able to assess the situation and restart the daemon.
In November 2006, Elad Efrat added PaX' Segvguard in NetBSD, along with a nice public explanation of its threat model. Unfortunately, as of 2019, it’s still not enabled by default.
In 2011, it was enhanced to be more severe for suid/sgid binaries:
In the suid/sgid case, the attempt is logged, the user has all their existing instances of the suid/sgid binary terminated and will be unable to execute any suid/sgid binaries for 15 minutes.
Also in 2011, GRKERNSEC_KERN_LOCKOUT
was implemented in grsecurity: if an
UDEREF
/USERCOPY
/KERNEXEC
violation is triggered, or an OOPS due to bad
memory access, if the user is root the system will panic, otherwise
the attempt are logged, all the processes from the users are killed,
and the user won’t be allowed to create new process until the system is
restarted.
HardenedBSD had its own port of PaX’ Segvguard since at least 2014, and NetBSD since 2006!
This is a bit similar to the idea of trustlevels in OpenBSD, except that it’s way more granular, proactive and completely automatic. It can also be compared to password bruteforce prevention: increasing delays between tentative, followed by a lockout.
It’s also the only way to make sure that ASLR can’t be bruteforced, even partially. It also acts as a deterrent for unreliable exploits: if the exploit doesn’t work reliably in a single shot, there is no way to launch it again, escalade privileges, and clean the traces.
GRKERNSEC_TPE
This grsecurity’s option provide a way to create a group whose members won’t be able to execute any files that are not in root-owned directories writeable only by root. Of course, with interpreters, it’s still possible for a user to execute arbitrary code, but porting a privilege escalation exploit into Python isn’t fun™.
This mitigation can be emulated by chrooting users, and bind mounting everything
except /bin
and /usr/bin
with noexec
, and while it’s not something as
fundamental as ASLR or NX, but it still deserves a mention.
GUI isolation
Modern linux distributions are now using wayland instead of Xorg, making it possible to isolate GUI programs. An other approach would be to do something similar to Qubes: use an hypervisor.
OpenBSD is currently using a fork of Xorg called Xenocara, which is basically the latest Xorg with modifications to be able to run some parts without root privileges.
Guarded memcpy
snmalloc’s
Guarded Memcpy
is a low-impact memcpy
hardening preventing a lot of OOB-write.
Mitigations against data-only exploits
Data-only exploits have been a thing for years now, yet no one currently has comprehensive mitigations against those, but things are starting to take form: