Date: Wed, 28 Aug 2002 15:30:03 -0700 (PDT) From: Archie Cobbs <archie@packetdesign.com> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/42100: libc_r: accept(2) can't handle descriptor being closed/shutdown Message-ID: <200208282230.g7SMU3JB072398@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/42100; it has been noted by GNATS.
From: Archie Cobbs <archie@packetdesign.com>
To: freebsd-gnats-submit@FreeBSD.org
Cc: eischen@pcnet1.pcnet.com
Subject: Re: bin/42100: libc_r: accept(2) can't handle descriptor being
closed/shutdown
Date: Wed, 28 Aug 2002 15:28:15 -0700
*** SUMMARY OF THIS BUG ***
There are three separate bugs going on here. The first bug is a
kernel bug. The second two bugs are libc_r bugs.
#1. Calling accept() on a socket that has been shutdown() and is
marked as non-blocking returns EAGAIN instead of ECONNABORTED
(which is what you get with blocking sockets). This bug is not
specific to libc_r.
--> This has been fixed in sys/kern/uipc_syscalls.c, rev. 1.130
and will be MFC'd soon.
#2. With libc_r, if one thread is blocked in an accept() call and
another thread close()'s the file descriptor, or the first thread
receives a signal and close()'s the file descriptor from within
the signal handler, then the first thread never wakes up. Same
thing will happen for lots of other calls besides accept().
--> Daniel's patch to uthread_kern.c fixes this problem *IF* you also
include the POLLNVAL flag along with POLLHUP and POLLERR. However,
see #3.
Hopefully this will be commited soon as well.
#3. With libc_r plus the fix for #2, if a program blocks in an
accept() (or other calls), receives a signal, and the signal handler
close()'s the file descriptor, then the process core dumps. The same
program not linked with -pthread behaves correctly (i.e, accept()
returns EBADF). Same thing happens if you use separate threads
instead of signals. E.g., see the original test program.
--> This is because in libc_r, when a file descriptor is closed,
_thread_fd_table[fd] is free()'d. When the first thread wakes
back up, it dereferences the NULL pointer. This could be fixed by
checking for NULL each time around the loop and returning EBADF
if so.
-Archie
__________________________________________________________________________
Archie Cobbs * Packet Design * http://www.packetdesign.com
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208282230.g7SMU3JB072398>
