summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorbluhm <bluhm@openbsd.org>2019-02-04 21:40:52 +0000
committerbluhm <bluhm@openbsd.org>2019-02-04 21:40:52 +0000
commit418b2720a1c00ce069c8a9d07505aceb34bd5dcf (patch)
tree1fe8354c6364f1e93827cfa6a64a19e33ba469ed /sys/netinet6
parentRemove .gitignore from libc++ and libc++abi that I usually remove before (diff)
downloadwireguard-openbsd-418b2720a1c00ce069c8a9d07505aceb34bd5dcf.tar.xz
wireguard-openbsd-418b2720a1c00ce069c8a9d07505aceb34bd5dcf.zip
Avoid an mbuf double free in the oob soreceive() path. In the
usrreq functions move the mbuf m_freem() logic to the release block instead of distributing it over the switch statement. Then the goto release in the initial check, whether the pcb still exists, will not free the mbuf for the PRU_RCVD, PRU_RVCOOB, PRU_SENSE command. OK claudio@ mpi@ visa@ Reported-by: syzbot+8e7997d4036ae523c79c@syzkaller.appspotmail.com
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/ip6_divert.c16
-rw-r--r--sys/netinet6/raw_ip6.c16
2 files changed, 16 insertions, 16 deletions
diff --git a/sys/netinet6/ip6_divert.c b/sys/netinet6/ip6_divert.c
index 2c60fe91f84..f99f87d4f8a 100644
--- a/sys/netinet6/ip6_divert.c
+++ b/sys/netinet6/ip6_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip6_divert.c,v 1.58 2018/10/04 17:33:41 bluhm Exp $ */
+/* $OpenBSD: ip6_divert.c,v 1.59 2019/02/04 21:40:52 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -283,7 +283,7 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
break;
case PRU_SENSE:
- return (0);
+ break;
case PRU_LISTEN:
case PRU_CONNECT:
@@ -295,20 +295,20 @@ divert6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
case PRU_SLOWTIMO:
case PRU_PROTORCV:
case PRU_PROTOSEND:
- error = EOPNOTSUPP;
- break;
-
case PRU_RCVD:
case PRU_RCVOOB:
- return (EOPNOTSUPP); /* do not free mbuf's */
+ error = EOPNOTSUPP;
+ break;
default:
panic("divert6_usrreq");
}
release:
- m_freem(control);
- m_freem(m);
+ if (req != PRU_RCVD && req != PRU_RCVOOB && req != PRU_SENSE) {
+ m_freem(control);
+ m_freem(m);
+ }
return (error);
}
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 6bce9a963f0..25c924b2ee2 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.133 2018/11/09 13:26:12 claudio Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.134 2019/02/04 21:40:52 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -668,19 +668,17 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
/*
* stat: don't bother with a blocksize
*/
- return (0);
+ break;
/*
* Not supported.
*/
case PRU_LISTEN:
case PRU_ACCEPT:
case PRU_SENDOOB:
- error = EOPNOTSUPP;
- break;
-
case PRU_RCVD:
case PRU_RCVOOB:
- return (EOPNOTSUPP); /* do not free mbuf's */
+ error = EOPNOTSUPP;
+ break;
case PRU_SOCKADDR:
in6_setsockaddr(in6p, nam);
@@ -694,8 +692,10 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
panic("rip6_usrreq");
}
release:
- m_freem(control);
- m_freem(m);
+ if (req != PRU_RCVD && req != PRU_RCVOOB && req != PRU_SENSE) {
+ m_freem(control);
+ m_freem(m);
+ }
return (error);
}