37-Year-Old OpenBSD Kernel Integer Overflow Yields Local Root
Calif disclosed a local privilege escalation in OpenBSD rooted in a signed 16-bit shared memory attachment counter that dates to the original BSD sources roughly 37 years ago. Repeatedly forking processes with shared memory attachments pushes the counter past 32,767, wrapping it negative. That integer overflow creates a use-after-free via a race condition, which, combined with a separate out-of-bounds write in the kernel, grants an unprivileged user a root shell. Both issues were patched in errata 026 and 018. Notably, the exploit works with KARL, SMAP, and SMEP all enabled and requires no information-disclosure primitive.
The exploit manipulates 127 SysV shared memory segments and 259 forked processes to trigger the counter wrap, then uses heap grooming guided by KERN_MALLOCSTATS metrics. It wins the race by issuing IPC_RMID in one process while a helper attaches a size-confused segment. A 16-byte ip_moptions struct is then positioned so a conditional -1 out-of-bounds write corrupts two 16-bit membership counters. Closing the socket triggers atomic decrements that flip a self-referential PTE from user to supervisor mode, yielding kernel code execution through a predictable kernel pointer.
Calif outlines several hardening measures beyond the errata fixes: safe-unlinking to validate doubly linked list invariants before memory writes, randomizing the PTE self-referential map allocation address at boot, and making the kernel allocator non-deterministic through base-address and allocation-order randomization. They also highlight compiler-level defenses such as the array bounds sanitizer and Alloc Tokens, and note that OpenBSD’s deterministic boot-time allocator leaves early allocations at predictable addresses across reboots on identical hardware, making function-pointer structures like lo0 and enc0 ioctl handlers reliable targets.
Read the full article
Continue reading at Hacker News →This is an AI-generated summary. Read the original for the full story.