Opened on 05/11/05 at 21:01:54
Closed on 01/20/15 at 06:15:12
#785 closed defect (fixed)
Threaded close of a socket with an accept call active.
Reported by: | Chris Johns | Owned by: | Chris Johns |
---|---|---|---|
Priority: | highest | Milestone: | 4.11 |
Component: | network/legacy | Version: | 4.6 |
Severity: | major | Keywords: | |
Cc: | bugs@… | Blocked By: | |
Blocking: |
Description (last modified by Gedare Bloom)
A listen socket is open and a thread blocked in the accept call. Closing the socket should result in an error code being passed back to the accept caller(ENXIO seems ok).
Closing a socket with a thread blocked in soconnsleep results in the blocked thread waking. As the thread closing the socket holds the network semaphore, the woken thread either does not get a look in or tries to obtain the network semaphore and blocks. The closing thread finishes freeing the socket structure back to the heap and releasing the network semaphore. The blocked thread gets a go, and then updates the socket structure which causes problems as the memory is now back in the heap.
The code flow. First the accept thread:
rtems/rtems_syscall.c:accept:
head->so_error = soconnsleep (head);
pointer that has been deleted.
Now the close thread:
rtems/rtems_syscall.c:rtems_bsdnet_close:
error = soclose (so);
kern/uipc_socket.c:soclose:
int error2 = (*so->so_proto->pr_usrreqs->pru_detach)(so);
netinet/tcp_usrreq.c:tcp_usr_detach:
tp = tcp_close(tp);
netinet/tcp_subr.c:tcp_close:
soisdisconnected(so);
kern/uipc_socket2.c:soisdisconnecting:
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
soconnwakeup(so);
sowwakeup(so);
sorwakeup(so);
kern/uipc_socket.c:soclose:
sofree(so);
I have not followed each syscall path to see what happens in each case (read/write/connect/...).
Release:
CVS
Environment:
Coldfire (Microcore).
How-To-Repeat:
Open a socket, block on accept, close the socket from another thread.
Attachments (3)
Change History (13)
comment:1 Changed on 05/11/05 at 21:05:14 by Chris Johns
Owner: | changed from eric to ccj |
---|
comment:2 Changed on 05/17/05 at 09:28:53 by Chris Johns
Status: | assigned → waiting |
---|
Changed on 12/03/06 at 13:31:12 by Chris Johns
Attachment: | net-close-4-7.diff added |
---|
Changed on 12/03/06 at 13:31:13 by Chris Johns
Attachment: | net-close-4-6-branch.diff added |
---|
net-close-4-6-branch.diff
comment:3 Changed on 12/04/06 at 22:34:28 by Chris Johns
attachments.ispatch: | 0 → 1 |
---|---|
attachments.mimetype: | text/x-patch → text/plain |
comment:4 Changed on 12/04/06 at 22:34:51 by Chris Johns
attachments.ispatch: | 0 → 1 |
---|---|
attachments.mimetype: | text/x-patch → text/plain |
Changed on 02/20/10 at 01:49:26 by Chris Johns
Attachment: | net-close-4-10.diff added |
---|
Updated 4.7 patch for 4.10
comment:5 Changed on 05/14/10 at 03:38:03 by Chris Johns
Milestone: | → 4.11 |
---|---|
rep_platform: | → All |
Move to 4.11. I will commit after 4.10 branches.
comment:6 Changed on 11/23/14 at 16:02:10 by Joel Sherrill
Description: | modified (diff) |
---|
Chris. Did you commit the fix for this? If so, please close this. I can't tell.
comment:7 Changed on 11/23/14 at 16:02:29 by Gedare Bloom
Version: | unknown → 4.6 |
---|
comment:8 Changed on 12/19/14 at 04:52:02 by Gedare Bloom
Description: | modified (diff) |
---|---|
Priority: | normal → highest |
4.10 and 4.11 have not been patched as far as I can tell. Bumping priority since the patch for 4.10 at least seems available.
comment:9 Changed on 01/15/15 at 10:37:11 by Sebastian Huber
The patch covers only the accept() case, but there are other users of sbwait() and sbconnsleep(). The patch includes unrelated comments. The usage of SS_ASYNC is an obfuscation. Why not simply return an error (e.g. ENXIO) in case a socket got deleted during the wait for event? A test case is missing.
comment:10 Changed on 01/20/15 at 06:15:12 by Sebastian Huber <sebastian.huber@…>
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
net-close-4-7.diff