summaryrefslogtreecommitdiffstats
path: root/sys/kern/uipc_socket.c
diff options
context:
space:
mode:
authormpi <mpi@openbsd.org>2017-08-22 09:13:36 +0000
committermpi <mpi@openbsd.org>2017-08-22 09:13:36 +0000
commit0bad721a22b5b65b644fe726746ef68bc247f3bc (patch)
tree65b13693ba1979f2212fbddf01dc3692288faf15 /sys/kern/uipc_socket.c
parentFix off by one overwrite. Covery CID 1452938. (diff)
downloadwireguard-openbsd-0bad721a22b5b65b644fe726746ef68bc247f3bc.tar.xz
wireguard-openbsd-0bad721a22b5b65b644fe726746ef68bc247f3bc.zip
Make sogetopt(9) caller responsible for allocating an MT_SOOPTS mbuf.
Move a blocking memory allocation out of the socket lock and create a simpler alloc/free pattern to review. Now both m_get() and m_free() are in the same place. Discussed with bluhm@. Encouragements from deraadt@ and tedu@, ok kettenis@, florian@, visa@
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r--sys/kern/uipc_socket.c21
1 files changed, 4 insertions, 17 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index c499f46de04..369e32ecdc5 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_socket.c,v 1.201 2017/08/10 19:20:43 mpi Exp $ */
+/* $OpenBSD: uipc_socket.c,v 1.202 2017/08/22 09:13:36 mpi Exp $ */
/* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */
/*
@@ -1755,30 +1755,24 @@ bad:
}
int
-sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
+sogetopt(struct socket *so, int level, int optname, struct mbuf *m)
{
int error = 0;
- struct mbuf *m;
soassertlocked(so);
if (level != SOL_SOCKET) {
if (so->so_proto->pr_ctloutput) {
- m = m_get(M_WAIT, MT_SOOPTS);
m->m_len = 0;
error = (*so->so_proto->pr_ctloutput)(PRCO_GETOPT, so,
level, optname, m);
- if (error) {
- m_free(m);
+ if (error)
return (error);
- }
- *mp = m;
return (0);
} else
return (ENOPROTOOPT);
} else {
- m = m_get(M_WAIT, MT_SOOPTS);
m->m_len = sizeof (int);
switch (optname) {
@@ -1856,13 +1850,10 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
level = dom->dom_protosw->pr_protocol;
error = (*so->so_proto->pr_ctloutput)
(PRCO_GETOPT, so, level, optname, m);
- if (error) {
- (void)m_free(m);
+ if (error)
return (error);
- }
break;
}
- (void)m_free(m);
return (ENOPROTOOPT);
#ifdef SOCKET_SPLICE
@@ -1887,17 +1878,13 @@ sogetopt(struct socket *so, int level, int optname, struct mbuf **mp)
&(unp->unp_connid), m->m_len);
break;
}
- (void)m_free(m);
return (ENOTCONN);
}
- (void)m_free(m);
return (EOPNOTSUPP);
default:
- (void)m_free(m);
return (ENOPROTOOPT);
}
- *mp = m;
return (0);
}
}