mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-14 10:09:48 +00:00
Port NetBSD's 19990120-accept bug fix. This works around the race condition
where select(2) can return that a listening socket has a connected socket queued, the connection is broken, and the user calls accept(2), which then blocks because there are no connections queued. Reviewed by: wollman Obtained from: NetBSD (ftp://ftp.NetBSD.ORG/pub/NetBSD/misc/security/patches/19990120-accept)
This commit is contained in:
parent
ec42cbfc24
commit
527b7a14a5
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=43196
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: uipc_socket2.c,v 1.42 1998/11/23 00:45:38 truckman Exp $
|
||||
* $Id: uipc_socket2.c,v 1.43 1998/12/07 21:58:29 archie Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -136,7 +136,7 @@ soisdisconnected(so)
|
||||
{
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
|
||||
wakeup((caddr_t)&so->so_timeo);
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_socket.c 8.3 (Berkeley) 4/15/94
|
||||
* $Id: uipc_socket.c,v 1.50 1999/01/20 17:31:54 fenner Exp $
|
||||
* $Id: uipc_socket.c,v 1.51 1999/01/20 17:45:22 fenner Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -193,7 +193,12 @@ sofree(so)
|
||||
TAILQ_REMOVE(&head->so_incomp, so, so_list);
|
||||
head->so_incqlen--;
|
||||
} else if (so->so_state & SS_COMP) {
|
||||
TAILQ_REMOVE(&head->so_comp, so, so_list);
|
||||
/*
|
||||
* We must not decommission a socket that's
|
||||
* on the accept(2) queue. If we do, then
|
||||
* accept(2) may hang after select(2) indicated
|
||||
* that the listening socket was ready.
|
||||
*/
|
||||
} else {
|
||||
panic("sofree: not queued");
|
||||
}
|
||||
@ -228,6 +233,7 @@ soclose(so)
|
||||
}
|
||||
for (sp = so->so_comp.tqh_first; sp != NULL; sp = sonext) {
|
||||
sonext = sp->so_list.tqe_next;
|
||||
TAILQ_REMOVE(&so->so_comp, sp, so_list);
|
||||
(void) soabort(sp);
|
||||
}
|
||||
}
|
||||
@ -288,7 +294,13 @@ soaccept(so, nam)
|
||||
if ((so->so_state & SS_NOFDREF) == 0)
|
||||
panic("soaccept: !NOFDREF");
|
||||
so->so_state &= ~SS_NOFDREF;
|
||||
error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
|
||||
if ((so->so_state & SS_ISDISCONNECTED) == 0)
|
||||
error = (*so->so_proto->pr_usrreqs->pru_accept)(so, nam);
|
||||
else {
|
||||
if (nam)
|
||||
*nam = 0;
|
||||
error = 0;
|
||||
}
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id: uipc_socket2.c,v 1.42 1998/11/23 00:45:38 truckman Exp $
|
||||
* $Id: uipc_socket2.c,v 1.43 1998/12/07 21:58:29 archie Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -136,7 +136,7 @@ soisdisconnected(so)
|
||||
{
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE|SS_ISDISCONNECTED);
|
||||
wakeup((caddr_t)&so->so_timeo);
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)socketvar.h 8.3 (Berkeley) 2/19/95
|
||||
* $Id: socketvar.h,v 1.31 1998/11/11 10:04:13 truckman Exp $
|
||||
* $Id: socketvar.h,v 1.32 1998/11/11 10:56:07 truckman Exp $
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SOCKETVAR_H_
|
||||
@ -127,6 +127,7 @@ struct socket {
|
||||
|
||||
#define SS_INCOMP 0x0800 /* unaccepted, incomplete connection */
|
||||
#define SS_COMP 0x1000 /* unaccepted, complete connection */
|
||||
#define SS_ISDISCONNECTED 0x2000 /* socket disconnected from peer */
|
||||
|
||||
/*
|
||||
* Externalized form of struct socket used by the sysctl(3) interface.
|
||||
|
Loading…
Reference in New Issue
Block a user