[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: