summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2016-11-21 09:09:07 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2016-11-21 09:09:07 +0000
commitbb797f408613b46cee97b8cac9de83beb3e39876 (patch)
treeff8330db4de384bfe2bafe652e2fe880ccde2d37
parentd6f258cf3464ccffb98335df1b2181475cfc792e (diff)
Enforce that pr_usrreq functions are called at IPL_SOFTNET.
This will allow us to keep locking simple as soon as we trade splsoftnet() for a rwlock. ok bluhm@, claudio@
-rw-r--r--sys/kern/sys_socket.c12
-rw-r--r--sys/kern/uipc_socket.c4
-rw-r--r--sys/kern/uipc_syscalls.c13
-rw-r--r--sys/net/if.c4
-rw-r--r--sys/net/raw_usrreq.c10
-rw-r--r--sys/net/rtsock.c9
-rw-r--r--sys/netinet/ip_divert.c23
-rw-r--r--sys/netinet/raw_ip.c8
-rw-r--r--sys/netinet/tcp_usrreq.c10
-rw-r--r--sys/netinet/udp_usrreq.c10
-rw-r--r--sys/netinet6/ip6_divert.c23
-rw-r--r--sys/netinet6/raw_ip6.c8
12 files changed, 54 insertions, 80 deletions
diff --git a/sys/kern/sys_socket.c b/sys/kern/sys_socket.c
index 7a90f780067..1ed6dff439c 100644
--- a/sys/kern/sys_socket.c
+++ b/sys/kern/sys_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_socket.c,v 1.22 2016/10/06 17:02:10 bluhm Exp $ */
+/* $OpenBSD: sys_socket.c,v 1.23 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: sys_socket.c,v 1.13 1995/08/12 23:59:09 mycroft Exp $ */
/*
@@ -73,6 +73,7 @@ int
soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
{
struct socket *so = (struct socket *)fp->f_data;
+ int s, error = 0;
switch (cmd) {
@@ -122,8 +123,12 @@ soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct proc *p)
return (ifioctl(so, cmd, data, p));
if (IOCGROUP(cmd) == 'r')
return (rtioctl(cmd, data, p));
- return ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
+ s = splsoftnet();
+ error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
(struct mbuf *)cmd, (struct mbuf *)data, (struct mbuf *)NULL, p));
+ splx(s);
+
+ return (error);
}
int
@@ -167,6 +172,7 @@ int
soo_stat(struct file *fp, struct stat *ub, struct proc *p)
{
struct socket *so = fp->f_data;
+ int s;
memset(ub, 0, sizeof (*ub));
ub->st_mode = S_IFSOCK;
@@ -177,8 +183,10 @@ soo_stat(struct file *fp, struct stat *ub, struct proc *p)
ub->st_mode |= S_IWUSR | S_IWGRP | S_IWOTH;
ub->st_uid = so->so_euid;
ub->st_gid = so->so_egid;
+ s = splsoftnet();
(void) ((*so->so_proto->pr_usrreq)(so, PRU_SENSE,
(struct mbuf *)ub, NULL, NULL, p));
+ splx(s);
return (0);
}
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 12edabecfbd..81c6c6d4b5e 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.164 2016/11/14 08:45:30 mpi Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.165 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -652,8 +652,10 @@ soreceive(struct socket *so, struct mbuf **paddr, struct uio *uio,
flags |= MSG_DONTWAIT;
if (flags & MSG_OOB) {
m = m_get(M_WAIT, MT_DATA);
+ s = splsoftnet();
error = (*pr->pr_usrreq)(so, PRU_RCVOOB, m,
(struct mbuf *)(long)(flags & MSG_PEEK), NULL, curproc);
+ splx(s);
if (error)
goto bad;
do {
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
index 3ae8670b0e0..5dc464e863c 100644
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_syscalls.c,v 1.139 2016/11/09 09:39:43 mpi Exp $ */
+/* $OpenBSD: uipc_syscalls.c,v 1.140 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: uipc_syscalls.c,v 1.19 1996/02/09 19:00:48 christos Exp $ */
/*
@@ -1066,7 +1066,7 @@ sys_getsockname(struct proc *p, void *v, register_t *retval)
struct socket *so;
struct mbuf *m = NULL;
socklen_t len;
- int error;
+ int error, s;
if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
return (error);
@@ -1078,14 +1078,15 @@ sys_getsockname(struct proc *p, void *v, register_t *retval)
if (error)
goto bad;
m = m_getclr(M_WAIT, MT_SONAME);
+ s = splsoftnet();
error = (*so->so_proto->pr_usrreq)(so, PRU_SOCKADDR, 0, m, 0, p);
+ splx(s);
if (error)
goto bad;
error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
bad:
FRELE(fp, p);
- if (m)
- m_freem(m);
+ m_freem(m);
return (error);
}
@@ -1104,7 +1105,7 @@ sys_getpeername(struct proc *p, void *v, register_t *retval)
struct socket *so;
struct mbuf *m = NULL;
socklen_t len;
- int error;
+ int error, s;
if ((error = getsock(p, SCARG(uap, fdes), &fp)) != 0)
return (error);
@@ -1120,7 +1121,9 @@ sys_getpeername(struct proc *p, void *v, register_t *retval)
if (error)
goto bad;
m = m_getclr(M_WAIT, MT_SONAME);
+ s = splsoftnet();
error = (*so->so_proto->pr_usrreq)(so, PRU_PEERADDR, 0, m, 0, p);
+ splx(s);
if (error)
goto bad;
error = copyaddrout(p, m, SCARG(uap, asa), len, SCARG(uap, alen));
diff --git a/sys/net/if.c b/sys/net/if.c
index 02e5433a20f..1e6d190dc81 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.461 2016/11/14 10:52:04 mpi Exp $ */
+/* $OpenBSD: if.c,v 1.462 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -2046,9 +2046,11 @@ ifioctl(struct socket *so, u_long cmd, caddr_t data, struct proc *p)
default:
if (so->so_proto == 0)
return (EOPNOTSUPP);
+ s = splsoftnet();
error = ((*so->so_proto->pr_usrreq)(so, PRU_CONTROL,
(struct mbuf *) cmd, (struct mbuf *) data,
(struct mbuf *) ifp, p));
+ splx(s);
break;
}
diff --git a/sys/net/raw_usrreq.c b/sys/net/raw_usrreq.c
index d17ea931ad0..837c1f0901a 100644
--- a/sys/net/raw_usrreq.c
+++ b/sys/net/raw_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_usrreq.c,v 1.25 2016/10/08 03:32:25 claudio Exp $ */
+/* $OpenBSD: raw_usrreq.c,v 1.26 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: raw_usrreq.c,v 1.11 1996/02/13 22:00:43 christos Exp $ */
/*
@@ -137,7 +137,9 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
{
struct rawcb *rp = sotorawcb(so);
int error = 0;
- int len, s;
+ int len;
+
+ splsoftassert(IPL_SOFTNET);
if (req == PRU_CONTROL)
return (EOPNOTSUPP);
@@ -149,7 +151,6 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
m_freem(m);
return (EINVAL);
}
- s = splsoftnet();
switch (req) {
/*
@@ -230,7 +231,6 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
/*
* stat: don't bother with a blocksize.
*/
- splx(s);
return (0);
/*
@@ -238,7 +238,6 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
*/
case PRU_RCVOOB:
case PRU_RCVD:
- splx(s);
return (EOPNOTSUPP);
case PRU_LISTEN:
@@ -270,7 +269,6 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
default:
panic("raw_usrreq");
}
- splx(s);
m_freem(m);
return (error);
}
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 46150c61310..8953a30a60b 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.208 2016/10/18 11:05:45 bluhm Exp $ */
+/* $OpenBSD: rtsock.c,v 1.209 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -149,10 +149,11 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
{
struct rawcb *rp;
struct routecb *rop;
- int s, af;
+ int af;
int error = 0;
- s = splsoftnet();
+ splsoftassert(IPL_SOFTNET);
+
rp = sotorawcb(so);
switch (req) {
@@ -178,7 +179,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = raw_attach(so, (int)(long)nam);
if (error) {
free(rop, M_PCB, sizeof(struct routecb));
- splx(s);
return (error);
}
rop->rtableid = curproc->p_p->ps_rtableid;
@@ -229,7 +229,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = raw_usrreq(so, req, m, nam, control, p);
}
- splx(s);
return (error);
}
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index c737fbbe93c..e660b79a2f2 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.39 2016/03/07 18:44:00 naddy Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.40 2016/11/21 09:09:06 mpi Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -63,7 +63,6 @@ int divbhashsize = DIVERTHASHSIZE;
static struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
-void divert_detach(struct inpcb *);
int divert_output(struct inpcb *, struct mbuf *, struct mbuf *,
struct mbuf *);
void
@@ -248,7 +247,8 @@ divert_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
{
struct inpcb *inp = sotoinpcb(so);
int error = 0;
- int s;
+
+ splsoftassert(IPL_SOFTNET);
if (req == PRU_CONTROL) {
return (in_control(so, (u_long)m, (caddr_t)addr,
@@ -269,9 +269,7 @@ divert_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
error = EACCES;
break;
}
- s = splsoftnet();
error = in_pcballoc(so, &divbtable);
- splx(s);
if (error)
break;
@@ -282,13 +280,11 @@ divert_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
break;
case PRU_DETACH:
- divert_detach(inp);
+ in_pcbdetach(inp);
break;
case PRU_BIND:
- s = splsoftnet();
error = in_pcbbind(inp, addr, p);
- splx(s);
break;
case PRU_SHUTDOWN:
@@ -300,7 +296,7 @@ divert_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
case PRU_ABORT:
soisdisconnected(so);
- divert_detach(inp);
+ in_pcbdetach(inp);
break;
case PRU_SOCKADDR:
@@ -341,15 +337,6 @@ release:
return (error);
}
-void
-divert_detach(struct inpcb *inp)
-{
- int s = splsoftnet();
-
- in_pcbdetach(inp);
- splx(s);
-}
-
/*
* Sysctl for divert variables.
*/
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 147d6266e79..34c307c1215 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.87 2016/11/14 03:51:53 dlg Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.88 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -409,7 +409,8 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
{
struct inpcb *inp = sotoinpcb(so);
int error = 0;
- int s;
+
+ splsoftassert(IPL_SOFTNET);
if (req == PRU_CONTROL)
return (in_control(so, (u_long)m, (caddr_t)nam,
@@ -433,13 +434,10 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = EPROTONOSUPPORT;
break;
}
- s = splsoftnet();
if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
(error = in_pcballoc(so, &rawcbtable))) {
- splx(s);
break;
}
- splx(s);
inp = sotoinpcb(so);
inp->inp_ip.ip_p = (long)nam;
break;
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index a530575f07b..5b5f724022c 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_usrreq.c,v 1.135 2016/09/24 14:51:37 naddy Exp $ */
+/* $OpenBSD: tcp_usrreq.c,v 1.136 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */
/*
@@ -130,10 +130,11 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct sockaddr_in *sin;
struct inpcb *inp;
struct tcpcb *tp = NULL;
- int s;
int error = 0;
short ostate;
+ splsoftassert(IPL_SOFTNET);
+
if (req == PRU_CONTROL) {
#ifdef INET6
if (sotopf(so) == PF_INET6)
@@ -150,7 +151,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
return (EINVAL);
}
- s = splsoftnet();
inp = sotoinpcb(so);
/*
* When a TCP is attached to a socket, then there will be
@@ -161,7 +161,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = so->so_error;
if (error == 0)
error = EINVAL;
- splx(s);
/*
* The following corrects an mbuf leak under rare
* circumstances
@@ -174,7 +173,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
tp = intotcpcb(inp);
/* tp might get 0 when using socket splicing */
if (tp == NULL) {
- splx(s);
return (0);
}
#ifdef KPROF
@@ -382,7 +380,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
case PRU_SENSE:
((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat;
- splx(s);
return (0);
case PRU_RCVOOB:
@@ -447,7 +444,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
}
if (tp && (so->so_options & SO_DEBUG))
tcp_trace(TA_USER, ostate, tp, (caddr_t)0, req, 0);
- splx(s);
return (error);
}
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 957f01a595f..83d96cc84b0 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.221 2016/11/18 02:53:47 dlg Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.222 2016/11/21 09:09:06 mpi Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -1107,7 +1107,8 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
{
struct inpcb *inp;
int error = 0;
- int s;
+
+ splsoftassert(IPL_SOFTNET);
if (req == PRU_CONTROL) {
#ifdef INET6
@@ -1120,7 +1121,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
(struct ifnet *)control));
}
- s = splsoftnet();
inp = sotoinpcb(so);
if (inp == NULL && req != PRU_ATTACH) {
error = EINVAL;
@@ -1257,7 +1257,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
else
#endif
error = udp_output(inp, m, addr, control);
- splx(s);
return (error);
case PRU_ABORT:
@@ -1291,7 +1290,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
* Perhaps Path MTU might be returned for a connected
* UDP socket in this case.
*/
- splx(s);
return (0);
case PRU_SENDOOB:
@@ -1304,7 +1302,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
case PRU_RCVD:
case PRU_RCVOOB:
- splx(s);
return (EOPNOTSUPP); /* do not free mbuf's */
default:
@@ -1312,7 +1309,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
}
release:
- splx(s);
m_freem(control);
m_freem(m);
return (error);
diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c
index 4a5f61de24f..42bea1ad86b 100644
--- a/sys/netinet6/ip6_divert.c
+++ b/sys/netinet6/ip6_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.c,v 1.41 2016/03/29 11:57:51 chl Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.42 2016/11/21 09:09:06 mpi Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -64,7 +64,6 @@ int divb6hashsize = DIVERTHASHSIZE;
static struct sockaddr_in6 ip6addr = { sizeof(ip6addr), AF_INET6 };
-void divert6_detach(struct inpcb *);
int divert6_output(struct inpcb *, struct mbuf *, struct mbuf *,
struct mbuf *);
@@ -251,7 +250,8 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
{
struct inpcb *inp = sotoinpcb(so);
int error = 0;
- int s;
+
+ splsoftassert(IPL_SOFTNET);
if (req == PRU_CONTROL) {
return (in6_control(so, (u_long)m, (caddr_t)addr,
@@ -272,9 +272,7 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
error = EACCES;
break;
}
- s = splsoftnet();
error = in_pcballoc(so, &divb6table);
- splx(s);
if (error)
break;
@@ -285,13 +283,11 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
break;
case PRU_DETACH:
- divert6_detach(inp);
+ in_pcbdetach(inp);
break;
case PRU_BIND:
- s = splsoftnet();
error = in_pcbbind(inp, addr, p);
- splx(s);
break;
case PRU_SHUTDOWN:
@@ -303,7 +299,7 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
case PRU_ABORT:
soisdisconnected(so);
- divert6_detach(inp);
+ in_pcbdetach(inp);
break;
case PRU_SOCKADDR:
@@ -344,15 +340,6 @@ release:
return (error);
}
-void
-divert6_detach(struct inpcb *inp)
-{
- int s = splsoftnet();
-
- in_pcbdetach(inp);
- splx(s);
-}
-
/*
* Sysctl for divert variables.
*/
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 69c96a4f7b3..d0512dac18e 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.98 2016/10/25 19:40:57 florian Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.99 2016/11/21 09:09:06 mpi Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -568,9 +568,10 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
{
struct inpcb *in6p = sotoinpcb(so);
int error = 0;
- int s;
int priv;
+ splsoftassert(IPL_SOFTNET);
+
priv = 0;
if ((so->so_state & SS_PRIV) != 0)
priv++;
@@ -591,13 +592,10 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
error = EPROTONOSUPPORT;
break;
}
- s = splsoftnet();
if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
(error = in_pcballoc(so, &rawin6pcbtable))) {
- splx(s);
break;
}
- splx(s);
in6p = sotoinpcb(so);
in6p->inp_ipv6.ip6_nxt = (long)nam;
in6p->inp_cksum6 = -1;