[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

library/1427: close(2) with -pthread fails closing sockets




>Number:         1427
>Category:       library
>Synopsis:       close(2) with -pthread fails closing sockets
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Oct  1 16:00:01 MDT 2000
>Last-Modified:
>Originator:     Yuval Yarom
>Organization:
net
>Release:        
>Environment:
	
	System      : OpenBSD 2.7
	Architecture: OpenBSD.i386
	Machine     : i386
>Description:
	The thread safe version of close(2) fstats a file descriptor
	before closing it.  If the FD is a socket that has no PCB
	fstat fails, and the socket is never closed, resulting
	in FD leak.
>How-To-Repeat:
	Compile the following code with -pthread
------- cut here ------- cut here -------- cut here -------
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>


void error(char *s)
{
        perror(s);
        exit(1);
}

void mkaddr(struct sockaddr_in *sinp, int port)
{
        bzero(sinp, sizeof(*sinp));
        sinp->sin_family = AF_INET;
        sinp->sin_port = htons(port);
        sinp->sin_addr.s_addr = inet_addr("127.1");
}

int main(int c, char **v)
{
        struct sockaddr_in sin;
        int sd1, sd2, sd3;
        int top_fd = -1;
        int l;
        int port = 9977;

        setbuf(stdout,NULL);
        if (v[1])
                port = atoi(v[1]);
        sd1 = socket(PF_INET, SOCK_STREAM, 0);
        if (sd1 < 0)
                error("create server socket");

        mkaddr(&sin, port);
        if (bind(sd1, &sin, sizeof(sin)) < 0)
                error("bind");

        if (listen(sd1, 5) < 0)
                error("listen");

        for (l = 0; l < 2000; l++) {
                //if ((l % 100) == 0)
                        printf("%d  \r", l);
                sd2 = socket(PF_INET, SOCK_STREAM, 0);
                if (sd2 < 0)
                        error("creating connection socket");

                if (sd2 > top_fd) {
                        printf("Got socket %d\n", sd2);
                        top_fd = sd2;
                }

                mkaddr(&sin, port);
                if (connect(sd2, &sin, sizeof(sin)) < 0)
                        error("connect");

                usleep(1000);
                sd3 = accept(sd1, NULL, NULL);
                if (sd3 < 0)
                        error("creating connection socket");

                shutdown(sd3, 2);
                if (close(sd3))
                        printf("Error closing accepted socket\n");
                usleep(1000);
                shutdown(sd2, 2);
                usleep(1000);
                if (close(sd2))
                        printf("Error closing connected socket\n");
        }
}
------- cut here ------- cut here -------- cut here -------
>Fix:
	

>Audit-Trail:
>Unformatted: