A 37-Year-Old Bug Surfaces: Rooting OpenBSD via Code Older Than BSD Itself
Translated by a model; the original is in Russian.
The security firm Calif has detailed the exploitation of a kernel bug in OpenBSD whose history reaches back roughly 37 years, to the original BSD sources. The company usually publishes offensive research, but this time the work was done in cooperation with the project: the vulnerabilities were reported upstream, often together with suggested patches.
The flaw
The root cause is a shared-memory attachment counter defined as a signed 16-bit short. Repeatedly forking a process with attachment records could push the counter past its maximum of 32,767 and wrap it to a negative value. This integer overflow led to a use-after-free via a race condition, and combined with a separate out-of-bounds write in the kernel it allowed local privilege escalation to root. The issues were fixed in errata 026 and 018.
The exploitation path
The researchers reached local root without any information-disclosure bug. The recipe: map 127 SysV shared-memory segments, unmap them with munmap(), and fork 259 processes to drive the attach count to −32,643. Then came heap grooming guided by sysctl(KERN_MALLOCSTATS) metrics, winning the race with IPC_RMID, aligning IP-socket allocations and setting IP_MULTICAST_TTL to a non-default value to allocate an ip_moptions struct.
A conditional −1 out-of-bounds write then overwrites the membership count and maximum fields; closing the socket triggers atomic decrements that twice modify the self-referential PTE mapping, flipping it from user to supervisor access. That bypasses SMAP/SMEP and yields kernel code execution by overwriting a predictable kernel pointer. In essence it is a write-what-where primitive: the "what" is userland memory made supervisor-accessible, the "where" is a predictable kernel address.
Why the addresses are predictable
KARL relinks the kernel to randomize both function and data addresses, yet the memory allocators stay deterministic. Early boot allocations land in the same spots across reboots on identical hardware. The exploit reliably targets the lo0 and enc0 ioctl handlers: one is overwritten to seize control flow, the other is used to restore the clobbered pointer.
What the authors recommend
Calif lists several defences: safe-unlinking of doubly linked lists (as in FreeBSD and NetBSD), randomizing the self-referential PTE mapping address, and making the kernel allocator non-deterministic. They also highlight compiler features — the array-bounds sanitizer (proposed to FreeBSD along with 21 privately reported issues) and upcoming Alloc Tokens that isolate pointer-bearing allocations. In the age of AI-assisted vulnerability discovery, the authors argue, neutralizing whole classes of bugs and raising the attacker's cost matters more than ever.
Source: Hacker News
Comments
Sign in, to comment.