From cd68a3f706b8dbc78a1d0f57a41913d3c710b79d Mon Sep 17 00:00:00 2001 From: Gleb Smirnoff Date: Thu, 22 Mar 2007 13:21:24 +0000 Subject: [PATCH] Move the dom_dispose and pru_detach calls in sofree() earlier. Only after calling pru_detach we can be absolutely sure, that we don't have any references to the socket in the stack. This closes race between lockless sbdestroy() and data arriving on socket. Reviewed by: rwatson --- sys/kern/uipc_socket.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index e4e35d5cf96c..2c9363ed750d 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -606,6 +606,11 @@ sofree(so) SOCK_UNLOCK(so); ACCEPT_UNLOCK(); + if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL) + (*pr->pr_domain->dom_dispose)(so->so_rcv.sb_mb); + if (pr->pr_usrreqs->pru_detach != NULL) + (*pr->pr_usrreqs->pru_detach)(so); + /* * From this point on, we assume that no other references to this * socket exist anywhere else in the stack. Therefore, no locks need @@ -624,11 +629,7 @@ sofree(so) KASSERT((so->so_snd.sb_flags & SB_LOCK) == 0, ("sofree: snd sblock")); KASSERT((so->so_rcv.sb_flags & SB_LOCK) == 0, ("sofree: rcv sblock")); sbdestroy(&so->so_snd, so); - if (pr->pr_flags & PR_RIGHTS && pr->pr_domain->dom_dispose != NULL) - (*pr->pr_domain->dom_dispose)(so->so_rcv.sb_mb); sbdestroy(&so->so_rcv, so); - if (pr->pr_usrreqs->pru_detach != NULL) - (*pr->pr_usrreqs->pru_detach)(so); knlist_destroy(&so->so_rcv.sb_sel.si_note); knlist_destroy(&so->so_snd.sb_sel.si_note); sodealloc(so);