#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)

net-close-4-7.diff (13.4 KB) - added by Chris Johns on 12/03/06 at 13:31:12.
net-close-4-7.diff
net-close-4-6-branch.diff (13.4 KB) - added by Chris Johns on 12/03/06 at 13:31:13.
net-close-4-6-branch.diff
net-close-4-10.diff (13.3 KB) - added by Chris Johns on 02/20/10 at 01:49:26.
Updated 4.7 patch for 4.10

Download all attachments as: .zip

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: assignedwaiting

Changed on 12/03/06 at 13:31:12 by Chris Johns

Attachment: net-close-4-7.diff added

net-close-4-7.diff

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: 01
attachments.mimetype: text/x-patchtext/plain

comment:4 Changed on 12/04/06 at 22:34:51 by Chris Johns

attachments.ispatch: 01
attachments.mimetype: text/x-patchtext/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: unknown4.6

comment:8 Changed on 12/19/14 at 04:52:02 by Gedare Bloom

Description: modified (diff)
Priority: normalhighest

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: assignedclosed

In f87ede57a2e97f0743a85b94072c7163fa485ae9/rtems:

libnetworking: Fix close of active sockets

Send a special event to notify tasks waiting for a socket state change
in case this socket gets closed. This prevents a use after free.

Close #785.

Note: See TracTickets for help on using tickets.