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>