diff options
author | bluhm <bluhm@openbsd.org> | 2019-02-04 21:40:52 +0000 |
---|---|---|
committer | bluhm <bluhm@openbsd.org> | 2019-02-04 21:40:52 +0000 |
commit | 418b2720a1c00ce069c8a9d07505aceb34bd5dcf (patch) | |
tree | 1fe8354c6364f1e93827cfa6a64a19e33ba469ed /sys/netinet6 | |
parent | Remove .gitignore from libc++ and libc++abi that I usually remove before (diff) | |
download | wireguard-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.c | 16 | ||||
-rw-r--r-- | sys/netinet6/raw_ip6.c | 16 |
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); } |