Change protocol switch pru_abort() API so that it returns void rather

than an int, as an error here is not meaningful.  Modify soabort() to
unconditionally free the socket on the return of pru_abort(), and
modify most protocols to no longer conditionally free the socket,
since the caller will do this.

This commit likely leaves parts of netinet and netinet6 in a situation
where they may panic or leak memory, as they have not are not fully
updated by this commit.  This will be corrected shortly in followup
commits to these components.

MFC after:      3 months
This commit is contained in:
Robert Watson 2006-04-01 15:15:05 +00:00
parent c66235a6ab
commit ac45e92ff2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=157366
29 changed files with 124 additions and 100 deletions

View File

@ -1292,10 +1292,10 @@ sbcreatecontrol(p, size, type, level)
* Some routines that return EOPNOTSUPP for entry points that are not
* supported by a protocol. Fill in as needed.
*/
int
void
pru_abort_notsupp(struct socket *so)
{
return EOPNOTSUPP;
}
int

View File

@ -543,23 +543,41 @@ soclose(so)
}
/*
* soabort() must not be called with any socket locks held, as it calls
* into the protocol, which will call back into the socket code causing
* it to acquire additional socket locks that may cause recursion or lock
* order reversals.
* soabort() allows the socket code or protocol code to detach a socket that
* has been in an incomplete or completed listen queue, but has not yet been
* accepted.
*
* This interface is tricky, because it is called on an unreferenced socket,
* and must be called only by a thread that has actually removed the socket
* from the listen queue it was on, or races with other threads are risked.
*
* This interface will call into the protocol code, so must not be called
* with any socket locks held. Protocols do call it while holding their own
* recursible protocol mutexes, but this is something that should be subject
* to review in the future.
*
* XXXRW: Why do we maintain a distinction between pru_abort() and
* pru_detach()?
*/
void
soabort(so)
struct socket *so;
{
int error;
error = (*so->so_proto->pr_usrreqs->pru_abort)(so);
if (error) {
ACCEPT_LOCK();
SOCK_LOCK(so);
sotryfree(so); /* note: does not decrement the ref count */
}
/*
* In as much as is possible, assert that no references to this
* socket are held. This is not quite the same as asserting that the
* current thread is responsible for arranging for no references, but
* is as close as we can get for now.
*/
KASSERT(so->so_count == 0, ("soabort: so_count"));
KASSERT(!(so->so_state & SS_PROTOREF), ("soabort: SS_PROTOREF"));
KASSERT(so->so_state & SS_NOFDREF, ("soabort: !SS_NOFDREF"));
(*so->so_proto->pr_usrreqs->pru_abort)(so);
ACCEPT_LOCK();
SOCK_LOCK(so);
sofree(so);
}
int

View File

@ -1292,10 +1292,10 @@ sbcreatecontrol(p, size, type, level)
* Some routines that return EOPNOTSUPP for entry points that are not
* supported by a protocol. Fill in as needed.
*/
int
void
pru_abort_notsupp(struct socket *so)
{
return EOPNOTSUPP;
}
int

View File

@ -139,7 +139,7 @@ static int unp_internalize(struct mbuf **, struct thread *);
static int unp_listen(struct socket *, struct unpcb *, int,
struct thread *);
static int
static void
uipc_abort(struct socket *so)
{
struct unpcb *unp;
@ -150,10 +150,6 @@ uipc_abort(struct socket *so)
unp_drop(unp, ECONNABORTED);
unp_detach(unp);
UNP_UNLOCK_ASSERT();
ACCEPT_LOCK();
SOCK_LOCK(so);
sotryfree(so);
return (0);
}
static int

View File

@ -138,19 +138,14 @@ raw_ctlinput(cmd, arg, dummy)
/* INCOMPLETE */
}
static int
static void
raw_uabort(struct socket *so)
{
struct rawcb *rp = sotorawcb(so);
if (rp == 0)
return EINVAL;
KASSERT(rp != NULL, ("raw_uabort: rp == NULL"));
raw_disconnect(rp);
soisdisconnected(so);
ACCEPT_LOCK();
SOCK_LOCK(so);
sotryfree(so);
return 0;
}
/* pru_accept is EOPNOTSUPP */

View File

@ -137,11 +137,11 @@ rts_input(struct mbuf *m)
* It really doesn't make any sense at all for this code to share much
* with raw_usrreq.c, since its functionality is so restricted. XXX
*/
static int
static void
rts_abort(struct socket *so)
{
return (raw_usrreqs.pru_abort(so));
raw_usrreqs.pru_abort(so);
}
/* pru_accept is EOPNOTSUPP */

View File

@ -200,7 +200,7 @@ ddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
return (error);
}
static int
static void
ddp_abort(struct socket *so)
{
struct ddpcb *ddp;
@ -211,8 +211,6 @@ ddp_abort(struct socket *so)
DDP_LOCK(ddp);
at_pcbdetach(so, ddp);
DDP_LIST_XUNLOCK();
/* XXXRW: Should be calling sotryfree() here? */
return (0);
}
void

View File

@ -78,7 +78,7 @@ static int atm_aal5_disconnect(struct socket *);
static int atm_aal5_shutdown(struct socket *);
static int atm_aal5_send(struct socket *, int, KBuffer *,
struct sockaddr *, KBuffer *, struct thread *td);
static int atm_aal5_abort(struct socket *);
static void atm_aal5_abort(struct socket *);
static int atm_aal5_control(struct socket *, u_long, caddr_t,
struct ifnet *, struct thread *td);
static int atm_aal5_sense(struct socket *, struct stat *);
@ -204,6 +204,11 @@ static Atm_attributes atm_aal5_defattr = {
;
#endif /* DIAGNOSTIC */
#define ATM_INTRO_NOERR(f) \
int s; \
s = splnet(); \
;
#define ATM_OUTRO() \
/* \
* Drain any deferred calls \
@ -213,6 +218,14 @@ static Atm_attributes atm_aal5_defattr = {
return (err); \
;
#define ATM_OUTRO_NOERR() \
/* \
* Drain any deferred calls \
*/ \
STACK_DRAIN(); \
(void) splx(s); \
;
#define ATM_RETERR(errno) { \
err = errno; \
goto out; \
@ -546,16 +559,16 @@ atm_aal5_send(so, flags, m, addr, control, td)
* errno error processing request - reason indicated
*
*/
static int
static void
atm_aal5_abort(so)
struct socket *so;
{
ATM_INTRO("abort");
ATM_INTRO_NOERR("abort");
so->so_error = ECONNABORTED;
err = atm_sock_detach(so);
atm_sock_detach(so);
ATM_OUTRO();
ATM_OUTRO_NOERR();
}

View File

@ -184,3 +184,17 @@ atm_proto_notsupp4(so, i, m, addr, m2, td)
{
return (EOPNOTSUPP);
}
/*
* Protocol request not supported
*
* Arguments:
* so pointer to socket
*
*/
void
atm_proto_notsupp5(so)
struct socket *so;
{
}

View File

@ -66,7 +66,7 @@ static int atm_dgram_info(caddr_t);
* New-style socket request routines
*/
struct pr_usrreqs atm_dgram_usrreqs = {
.pru_abort = atm_proto_notsupp1,
.pru_abort = atm_proto_notsupp5,
.pru_attach = atm_dgram_attach,
.pru_bind = atm_proto_notsupp2,
.pru_control = atm_dgram_control,

View File

@ -136,6 +136,7 @@ int atm_proto_notsupp2(struct socket *, struct sockaddr *,
int atm_proto_notsupp3(struct socket *, struct sockaddr **);
int atm_proto_notsupp4(struct socket *, int, KBuffer *,
struct sockaddr *, KBuffer *, struct thread *);
void atm_proto_notsupp5(struct socket *);
/* atm_signal.c */
int atm_sigmgr_register(struct sigmgr *);

View File

@ -66,7 +66,7 @@ typedef struct ng_btsocket_hci_raw_pcb * ng_btsocket_hci_raw_pcb_p;
#ifdef _KERNEL
void ng_btsocket_hci_raw_init (void);
int ng_btsocket_hci_raw_abort (struct socket *);
void ng_btsocket_hci_raw_abort (struct socket *);
int ng_btsocket_hci_raw_attach (struct socket *, int, struct thread *);
int ng_btsocket_hci_raw_bind (struct socket *, struct sockaddr *,
struct thread *);

View File

@ -92,7 +92,7 @@ typedef struct ng_btsocket_l2cap_raw_pcb * ng_btsocket_l2cap_raw_pcb_p;
#ifdef _KERNEL
void ng_btsocket_l2cap_raw_init (void);
int ng_btsocket_l2cap_raw_abort (struct socket *);
void ng_btsocket_l2cap_raw_abort (struct socket *);
int ng_btsocket_l2cap_raw_attach (struct socket *, int, struct thread *);
int ng_btsocket_l2cap_raw_bind (struct socket *, struct sockaddr *,
struct thread *);
@ -183,7 +183,7 @@ typedef struct ng_btsocket_l2cap_pcb * ng_btsocket_l2cap_pcb_p;
#ifdef _KERNEL
void ng_btsocket_l2cap_init (void);
int ng_btsocket_l2cap_abort (struct socket *);
void ng_btsocket_l2cap_abort (struct socket *);
int ng_btsocket_l2cap_accept (struct socket *, struct sockaddr **);
int ng_btsocket_l2cap_attach (struct socket *, int, struct thread *);
int ng_btsocket_l2cap_bind (struct socket *, struct sockaddr *,

View File

@ -314,7 +314,7 @@ typedef struct ng_btsocket_rfcomm_pcb * ng_btsocket_rfcomm_pcb_p;
#ifdef _KERNEL
void ng_btsocket_rfcomm_init (void);
int ng_btsocket_rfcomm_abort (struct socket *);
void ng_btsocket_rfcomm_abort (struct socket *);
int ng_btsocket_rfcomm_accept (struct socket *, struct sockaddr **);
int ng_btsocket_rfcomm_attach (struct socket *, int, struct thread *);
int ng_btsocket_rfcomm_bind (struct socket *, struct sockaddr *,

View File

@ -872,10 +872,10 @@ ng_btsocket_hci_raw_init(void)
* Abort connection on socket
*/
int
void
ng_btsocket_hci_raw_abort(struct socket *so)
{
return (ng_btsocket_hci_raw_detach(so));
ng_btsocket_hci_raw_detach(so);
} /* ng_btsocket_hci_raw_abort */
/*

View File

@ -1912,12 +1912,12 @@ ng_btsocket_l2cap_init(void)
* Abort connection on socket
*/
int
void
ng_btsocket_l2cap_abort(struct socket *so)
{
so->so_error = ECONNABORTED;
return (ng_btsocket_l2cap_detach(so));
ng_btsocket_l2cap_detach(so);
} /* ng_btsocket_l2cap_abort */
/*

View File

@ -572,10 +572,10 @@ ng_btsocket_l2cap_raw_init(void)
* Abort connection on socket
*/
int
void
ng_btsocket_l2cap_raw_abort(struct socket *so)
{
return (ng_btsocket_l2cap_raw_detach(so));
ng_btsocket_l2cap_raw_detach(so);
} /* ng_btsocket_l2cap_raw_abort */
/*

View File

@ -343,12 +343,12 @@ ng_btsocket_rfcomm_init(void)
* Abort connection on socket
*/
int
void
ng_btsocket_rfcomm_abort(struct socket *so)
{
so->so_error = ECONNABORTED;
return (ng_btsocket_rfcomm_detach(so));
ng_btsocket_rfcomm_detach(so);
} /* ng_btsocket_rfcomm_abort */
/*

View File

@ -653,7 +653,7 @@ rip_detach(struct socket *so)
return 0;
}
static int
static void
rip_abort(struct socket *so)
{
struct inpcb *inp;
@ -662,7 +662,7 @@ rip_abort(struct socket *so)
inp = sotoinpcb(so);
if (inp == 0) {
INP_INFO_WUNLOCK(&ripcbinfo);
return EINVAL; /* ??? possible? panic instead? */
return; /* ??? possible? panic instead? */
}
INP_LOCK(inp);
soisdisconnected(so);
@ -671,7 +671,6 @@ rip_abort(struct socket *so)
else
INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&ripcbinfo);
return 0;
}
static int
@ -679,7 +678,8 @@ rip_disconnect(struct socket *so)
{
if ((so->so_state & SS_ISCONNECTED) == 0)
return ENOTCONN;
return rip_abort(so);
rip_abort(so);
return 0;
}
static int

View File

@ -755,17 +755,25 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
/*
* Abort the TCP.
*/
static int
static void
tcp_usr_abort(struct socket *so)
{
int error = 0;
struct inpcb *inp;
struct tcpcb *tp;
const int inirw = INI_WRITE;
TCPDEBUG0;
COMMON_START();
INP_INFO_WLOCK(&tcbinfo);
inp = sotoinpcb(so);
if (inp == NULL)
return;
INP_LOCK(inp);
tp = intotcpcb(inp);
TCPDEBUG1();
tp = tcp_drop(tp, ECONNABORTED);
COMMON_END(PRU_ABORT);
TCPDEBUG2(PRU_ABORT);
if (tp)
INP_UNLOCK(inp);
INP_INFO_WUNLOCK(&tcbinfo);
}
/*

View File

@ -929,7 +929,7 @@ u_long udp_recvspace = 40 * (1024 +
SYSCTL_ULONG(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW,
&udp_recvspace, 0, "Maximum space for incoming UDP datagrams");
static int
static void
udp_abort(struct socket *so)
{
struct inpcb *inp;
@ -938,13 +938,12 @@ udp_abort(struct socket *so)
inp = sotoinpcb(so);
if (inp == 0) {
INP_INFO_WUNLOCK(&udbinfo);
return EINVAL; /* ??? possible? panic instead? */
return; /* ??? possible? panic instead? */
}
INP_LOCK(inp);
soisdisconnected(so);
in_pcbdetach(inp);
INP_INFO_WUNLOCK(&udbinfo);
return 0;
}
static int

View File

@ -615,11 +615,11 @@ rip6_detach(struct socket *so)
return 0;
}
static int
static void
rip6_abort(struct socket *so)
{
soisdisconnected(so);
return rip6_detach(so);
rip6_detach(so);
}
static int
@ -630,7 +630,8 @@ rip6_disconnect(struct socket *so)
if ((so->so_state & SS_ISCONNECTED) == 0)
return ENOTCONN;
inp->in6p_faddr = in6addr_any;
return rip6_abort(so);
rip6_abort(so);
return 0;
}
static int

View File

@ -497,7 +497,7 @@ SYSCTL_PROC(_net_inet6_udp6, OID_AUTO, getcred, CTLTYPE_OPAQUE|CTLFLAG_RW,
0, 0,
udp6_getcred, "S,xucred", "Get the xucred of a UDP6 connection");
static int
static void
udp6_abort(struct socket *so)
{
struct inpcb *inp;
@ -507,7 +507,7 @@ udp6_abort(struct socket *so)
inp = sotoinpcb(so);
if (inp == 0) {
INP_INFO_WUNLOCK(&udbinfo);
return EINVAL; /* ??? possible? panic instead? */
return; /* ??? possible? panic instead? */
}
soisdisconnected(so);
s = splnet();
@ -515,7 +515,6 @@ udp6_abort(struct socket *so)
in6_pcbdetach(inp);
INP_INFO_WUNLOCK(&udbinfo);
splx(s);
return 0;
}
static int

View File

@ -369,14 +369,11 @@ key_sendup_mbuf(so, m, target)
* key_abort()
* derived from net/rtsock.c:rts_abort()
*/
static int
static void
key_abort(struct socket *so)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_abort(so);
splx(s);
return error;
raw_usrreqs.pru_abort(so);
}
/*

View File

@ -75,7 +75,7 @@ static int ipxrecvspace = IPXRCVQ;
SYSCTL_INT(_net_ipx_ipx, OID_AUTO, ipxrecvspace, CTLFLAG_RW,
&ipxrecvspace, 0, "");
static int ipx_usr_abort(struct socket *so);
static void ipx_usr_abort(struct socket *so);
static int ipx_attach(struct socket *so, int proto, struct thread *td);
static int ipx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
static int ipx_connect(struct socket *so, struct sockaddr *nam,
@ -428,7 +428,7 @@ ipx_ctloutput(so, sopt)
return (error);
}
static int
static void
ipx_usr_abort(so)
struct socket *so;
{
@ -441,10 +441,6 @@ ipx_usr_abort(so)
ipx_pcbfree(ipxp);
IPX_LIST_UNLOCK();
soisdisconnected(so);
ACCEPT_LOCK();
SOCK_LOCK(so);
sotryfree(so);
return (0);
}
static int

View File

@ -97,7 +97,7 @@ static void spx_template(struct spxpcb *cb);
static void spx_timers(struct spxpcb *cb, int timer);
static void spx_usrclosed(struct spxpcb *cb);
static int spx_usr_abort(struct socket *so);
static void spx_usr_abort(struct socket *so);
static int spx_accept(struct socket *so, struct sockaddr **nam);
static int spx_attach(struct socket *so, int proto, struct thread *td);
static int spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td);
@ -1305,7 +1305,7 @@ spx_ctloutput(struct socket *so, struct sockopt *sopt)
return (error);
}
static int
static void
spx_usr_abort(struct socket *so)
{
struct ipxpcb *ipxp;
@ -1324,10 +1324,6 @@ spx_usr_abort(struct socket *so)
ipx_pcbdetach(ipxp);
ipx_pcbfree(ipxp);
IPX_LIST_UNLOCK();
ACCEPT_LOCK();
SOCK_LOCK(so);
sotryfree(so);
return (0);
}
/*

View File

@ -278,14 +278,11 @@ key_sendup_mbuf(so, m, target)
* key_abort()
* derived from net/rtsock.c:rts_abort()
*/
static int
static void
key_abort(struct socket *so)
{
int s, error;
s = splnet();
error = raw_usrreqs.pru_abort(so);
splx(s);
return error;
raw_usrreqs.pru_abort(so);
}
/*

View File

@ -83,7 +83,7 @@ static int natm_usr_send(struct socket *, int, struct mbuf *,
static int natm_usr_peeraddr(struct socket *, struct sockaddr **);
static int natm_usr_control(struct socket *, u_long, caddr_t,
struct ifnet *, d_thread_t *);
static int natm_usr_abort(struct socket *);
static void natm_usr_abort(struct socket *);
static int natm_usr_bind(struct socket *, struct sockaddr *, d_thread_t *);
static int natm_usr_sockaddr(struct socket *, struct sockaddr **);
@ -333,14 +333,10 @@ natm_usr_control(struct socket *so, u_long cmd, caddr_t arg,
return (error);
}
static int
static void
natm_usr_abort(struct socket *so)
{
natm_usr_shutdown(so);
ACCEPT_LOCK();
SOCK_LOCK(so);
sotryfree(so);
return (0);
}
static int

View File

@ -196,7 +196,7 @@ struct uio;
*/
struct pr_usrreqs {
double __Break_the_struct_layout_for_now;
int (*pru_abort)(struct socket *so);
void (*pru_abort)(struct socket *so);
int (*pru_accept)(struct socket *so, struct sockaddr **nam);
int (*pru_attach)(struct socket *so, int proto, struct thread *td);
int (*pru_bind)(struct socket *so, struct sockaddr *nam,
@ -246,7 +246,7 @@ struct pr_usrreqs {
* All nonvoid pru_*() functions below return EOPNOTSUPP.
*/
int pru_abort_notsupp(struct socket *so);
void pru_abort_notsupp(struct socket *so);
int pru_accept_notsupp(struct socket *so, struct sockaddr **nam);
int pru_attach_notsupp(struct socket *so, int proto, struct thread *td);
int pru_bind_notsupp(struct socket *so, struct sockaddr *nam,