On Wed, Apr 06, 2011 at 02:53:46PM -0700, Kees Cook wrote: > On Wed, Apr 06, 2011 at 05:35:07PM -0400, Scott Kitterman wrote: > > He offers this as a test case: > > I can confirm the behavior difference between maverick and natty by doing > this: > > while ./testcase.pl ; do echo -n . ; done > > On maverick, this runs forever. Natty immediately fails: > > Parent 792 > > Child 793 > .bind: Address already in use at ./testcase.pl line 9. > > > I hope this is a Net::Server delta and not a kernel delta.
This looks like a kernel bug to me. I can reproduce it with C as well. $ ./testcase parent: 3781 before: tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTEN after: child: 3786 $ ./testcase bind: Address already in use $ kill 3786 $ ./testcase parent: 3810 before: tcp 0 0 0.0.0.0:12345 0.0.0.0:* LISTEN after: child: 3817 :( -- Kees Cook Ubuntu Security Team
/* Author: Kees Cook <[email protected]> * Copyright 2011 Canonical, Ltd * License: GPLv2 */ #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <stdint.h> #include <string.h> #include <stdint.h> #include <signal.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/socket.h> #include <netdb.h> #include <errno.h> #include <netinet/in.h> #define PORT 12345 int main(int argc, char * argv[]) { struct sigaction reaper; struct protoent *proto; struct sockaddr_in saddr; int server, on=1; char cmd[80]; if (!(proto=getprotobyname("tcp"))) { perror("getprotobyname"); return 1; } if ((server = socket(PF_INET, SOCK_STREAM, proto->p_proto))<0) { perror("socket"); return 1; } if (setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) { perror("setsockopt"); return 1; } memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_addr.s_addr = htonl(INADDR_ANY); saddr.sin_port = htons(PORT); if (bind(server, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) { perror("bind"); return 1; } if (listen(server,5)<0) { perror("listen"); return 1; } printf("parent: %d\n", getpid()); printf("before:\n"); sprintf(cmd, "netstat -an | grep :%d", PORT); system(cmd); int pid = fork(); if (pid == 0) { printf("child: %d\n", getpid()); sleep(100); exit(0); } shutdown(server, SHUT_RDWR); printf("after:\n"); system(cmd); return 0; }
-- ubuntu-devel mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/ubuntu-devel
