Hi,
It was possible to leak the control mbuf in raw ip user request
with sendmsg(2) and MSG_OOB. Sync the code in udp, rip, and
rip6_usrreq. Add an inp NULL check in rip6_usrreq for consistency.
ok?
bluhm
Index: netinet/raw_ip.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.110
diff -u -p -r1.110 raw_ip.c
--- netinet/raw_ip.c 4 Jul 2018 02:08:13 -0000 1.110
+++ netinet/raw_ip.c 4 Jul 2018 20:12:28 -0000
@@ -365,7 +365,7 @@ int
rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct mbuf *control, struct proc *p)
{
- struct inpcb *inp = sotoinpcb(so);
+ struct inpcb *inp;
int error = 0;
if (req == PRU_CONTROL)
@@ -374,6 +374,7 @@ rip_usrreq(struct socket *so, int req, s
soassertlocked(so);
+ inp = sotoinpcb(so);
if (inp == NULL) {
error = EINVAL;
goto release;
@@ -504,6 +505,7 @@ rip_usrreq(struct socket *so, int req, s
panic("rip_usrreq");
}
release:
+ m_freem(control);
m_freem(m);
return (error);
}
Index: netinet/udp_usrreq.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.249
diff -u -p -r1.249 udp_usrreq.c
--- netinet/udp_usrreq.c 8 Jun 2018 14:09:57 -0000 1.249
+++ netinet/udp_usrreq.c 4 Jul 2018 20:09:46 -0000
@@ -1203,7 +1203,6 @@ udp_usrreq(struct socket *so, int req, s
default:
panic("udp_usrreq");
}
-
release:
m_freem(control);
m_freem(m);
Index: netinet6/raw_ip6.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.128
diff -u -p -r1.128 raw_ip6.c
--- netinet6/raw_ip6.c 4 Jul 2018 02:08:13 -0000 1.128
+++ netinet6/raw_ip6.c 4 Jul 2018 20:40:05 -0000
@@ -544,7 +544,7 @@ int
rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
struct mbuf *control, struct proc *p)
{
- struct inpcb *in6p = sotoinpcb(so);
+ struct inpcb *in6p;
int error = 0;
if (req == PRU_CONTROL)
@@ -553,6 +553,12 @@ rip6_usrreq(struct socket *so, int req,
soassertlocked(so);
+ in6p = sotoinpcb(so);
+ if (in6p == NULL) {
+ error = EINVAL;
+ goto release;
+ }
+
switch (req) {
case PRU_DISCONNECT:
if ((so->so_state & SS_ISCONNECTED) == 0) {
@@ -654,6 +660,7 @@ rip6_usrreq(struct socket *so, int req,
dst.sin6_scope_id = addr6->sin6_scope_id;
}
error = rip6_output(m, so, sin6tosa(&dst), control);
+ control = NULL;
m = NULL;
break;
}
@@ -687,6 +694,8 @@ rip6_usrreq(struct socket *so, int req,
default:
panic("rip6_usrreq");
}
+release:
+ m_freem(control);
m_freem(m);
return (error);
}