summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_socket.c
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2017-09-01 15:05:31 +0000
committermpi <mpi@openbsd.org>2017-09-01 15:05:31 +0000
commite09b1b7c399f82ae784da0bb3508c9e74fbd7692 (patch)
tree39a99b2b3f132da588e6d96ba211e45cf2f5b1e9 /sys/kern/uipc_socket.c
parentMake 'tcpdump -v' decode RSN information elements in beacons (diff)
downloadwireguard-openbsd-e09b1b7c399f82ae784da0bb3508c9e74fbd7692.tar.xz
wireguard-openbsd-e09b1b7c399f82ae784da0bb3508c9e74fbd7692.zip
Change sosetopt() to no longer free the mbuf it receives and change
all the callers to call m_freem(9). Support from deraadt@ and tedu@, ok visa@, bluhm@
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r--sys/kern/uipc_socket.c81
1 files changed, 28 insertions, 53 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 369e32ecdc5..a54338e28a7 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.202 2017/08/22 09:13:36 mpi Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.203 2017/09/01 15:05:31 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -1558,17 +1558,16 @@ sowwakeup(struct socket *so)
}
int
-sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
+sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
{
int error = 0;
- struct mbuf *m = m0;
soassertlocked(so);
if (level != SOL_SOCKET) {
if (so->so_proto->pr_ctloutput) {
error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
- level, optname, m0);
+ level, optname, m);
return (error);
}
error = ENOPROTOOPT;
@@ -1576,7 +1575,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
switch (optname) {
case SO_BINDANY:
if ((error = suser(curproc, 0)) != 0) /* XXX */
- goto bad;
+ return (error);
break;
}
@@ -1585,10 +1584,8 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
case SO_LINGER:
if (m == NULL || m->m_len != sizeof (struct linger) ||
mtod(m, struct linger *)->l_linger < 0 ||
- mtod(m, struct linger *)->l_linger > SHRT_MAX) {
- error = EINVAL;
- goto bad;
- }
+ mtod(m, struct linger *)->l_linger > SHRT_MAX)
+ return (EINVAL);
so->so_linger = mtod(m, struct linger *)->l_linger;
/* FALLTHROUGH */
@@ -1602,10 +1599,8 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
case SO_OOBINLINE:
case SO_TIMESTAMP:
case SO_ZEROIZE:
- if (m == NULL || m->m_len < sizeof (int)) {
- error = EINVAL;
- goto bad;
- }
+ if (m == NULL || m->m_len < sizeof (int))
+ return (EINVAL);
if (*mtod(m, int *))
so->so_options |= optname;
else
@@ -1613,10 +1608,8 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
break;
case SO_DONTROUTE:
- if (m == NULL || m->m_len < sizeof (int)) {
- error = EINVAL;
- goto bad;
- }
+ if (m == NULL || m->m_len < sizeof (int))
+ return (EINVAL);
if (*mtod(m, int *))
error = EOPNOTSUPP;
break;
@@ -1628,38 +1621,28 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
{
u_long cnt;
- if (m == NULL || m->m_len < sizeof (int)) {
- error = EINVAL;
- goto bad;
- }
+ if (m == NULL || m->m_len < sizeof (int))
+ return (EINVAL);
cnt = *mtod(m, int *);
if ((long)cnt <= 0)
cnt = 1;
switch (optname) {
case SO_SNDBUF:
- if (so->so_state & SS_CANTSENDMORE) {
- error = EINVAL;
- goto bad;
- }
+ if (so->so_state & SS_CANTSENDMORE)
+ return (EINVAL);
if (sbcheckreserve(cnt, so->so_snd.sb_wat) ||
- sbreserve(so, &so->so_snd, cnt)) {
- error = ENOBUFS;
- goto bad;
- }
+ sbreserve(so, &so->so_snd, cnt))
+ return (ENOBUFS);
so->so_snd.sb_wat = cnt;
break;
case SO_RCVBUF:
- if (so->so_state & SS_CANTRCVMORE) {
- error = EINVAL;
- goto bad;
- }
+ if (so->so_state & SS_CANTRCVMORE)
+ return (EINVAL);
if (sbcheckreserve(cnt, so->so_rcv.sb_wat) ||
- sbreserve(so, &so->so_rcv, cnt)) {
- error = ENOBUFS;
- goto bad;
- }
+ sbreserve(so, &so->so_rcv, cnt))
+ return (ENOBUFS);
so->so_rcv.sb_wat = cnt;
break;
@@ -1683,16 +1666,12 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
struct timeval tv;
int val;
- if (m == NULL || m->m_len < sizeof (tv)) {
- error = EINVAL;
- goto bad;
- }
+ if (m == NULL || m->m_len < sizeof (tv))
+ return (EINVAL);
memcpy(&tv, mtod(m, struct timeval *), sizeof tv);
val = tvtohz(&tv);
- if (val > USHRT_MAX) {
- error = EDOM;
- goto bad;
- }
+ if (val > USHRT_MAX)
+ return (EDOM);
switch (optname) {
@@ -1714,7 +1693,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
level = dom->dom_protosw->pr_protocol;
error = (*so->so_proto->pr_ctloutput)
- (PRCO_SETOPT, so, level, optname, m0);
+ (PRCO_SETOPT, so, level, optname, m);
return (error);
}
error = ENOPROTOOPT;
@@ -1725,8 +1704,7 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
if (m == NULL) {
error = sosplice(so, -1, 0, NULL);
} else if (m->m_len < sizeof(int)) {
- error = EINVAL;
- goto bad;
+ return (EINVAL);
} else if (m->m_len < sizeof(struct splice)) {
error = sosplice(so, *mtod(m, int *), 0, NULL);
} else {
@@ -1744,13 +1722,10 @@ sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
}
if (error == 0 && so->so_proto->pr_ctloutput) {
(*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
- level, optname, m0);
- m = NULL; /* freed by protocol */
+ level, optname, m);
}
}
-bad:
- if (m)
- (void) m_free(m);
+
return (error);
}