Skip site navigation (1)Skip section navigation (2)
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>