summaryrefslogtreecommitdiffstats
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
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
-rw-r--r--sys/kern/uipc_usrreq.c12
-rw-r--r--sys/net/pfkeyv2.c12
-rw-r--r--sys/net/rtsock.c15
-rw-r--r--sys/netinet/ip_divert.c16
-rw-r--r--sys/netinet/raw_ip.c16
-rw-r--r--sys/netinet/udp_usrreq.c16
-rw-r--r--sys/netinet6/ip6_divert.c16
-rw-r--r--sys/netinet6/raw_ip6.c16
8 files changed, 60 insertions, 59 deletions
diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index e8ba18b1632..01a65ccf3f2 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uipc_usrreq.c,v 1.137 2018/11/21 17:07:07 claudio Exp $ */
+/* $OpenBSD: uipc_usrreq.c,v 1.138 2019/02/04 21:40:52 bluhm Exp $ */
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
/*
@@ -285,12 +285,10 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
sb->st_mtim.tv_nsec =
sb->st_ctim.tv_nsec = unp->unp_ctime.tv_nsec;
sb->st_ino = unp->unp_ino;
- return (0);
+ break;
}
case PRU_RCVOOB:
- return (EOPNOTSUPP);
-
case PRU_SENDOOB:
error = EOPNOTSUPP;
break;
@@ -310,8 +308,10 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
panic("uipc_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/net/pfkeyv2.c b/sys/net/pfkeyv2.c
index c0864f99369..a976c5b79d1 100644
--- a/sys/net/pfkeyv2.c
+++ b/sys/net/pfkeyv2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfkeyv2.c,v 1.196 2019/02/01 13:32:00 mpi Exp $ */
+/* $OpenBSD: pfkeyv2.c,v 1.197 2019/02/04 21:40:52 bluhm Exp $ */
/*
* @(#)COPYRIGHT 1.1 (NRL) 17 January 1995
@@ -373,7 +373,7 @@ pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m,
break;
case PRU_SENSE:
/* stat: don't bother with a blocksize. */
- return (0);
+ break;
/* minimal support, just implement a fake peer address */
case PRU_SOCKADDR:
@@ -386,8 +386,6 @@ pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m,
case PRU_RCVOOB:
case PRU_RCVD:
- return (EOPNOTSUPP);
-
case PRU_SENDOOB:
error = EOPNOTSUPP;
break;
@@ -404,8 +402,10 @@ pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m,
}
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/net/rtsock.c b/sys/net/rtsock.c
index 30e87e33334..89315b49466 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rtsock.c,v 1.281 2018/12/20 10:27:37 claudio Exp $ */
+/* $OpenBSD: rtsock.c,v 1.282 2019/02/04 21:40:52 bluhm Exp $ */
/* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */
/*
@@ -237,7 +237,7 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
break;
case PRU_SENSE:
/* stat: don't bother with a blocksize. */
- return (0);
+ break;
/* minimal support, just implement a fake peer address */
case PRU_SOCKADDR:
@@ -248,8 +248,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
nam->m_len = route_src.sa_len;
break;
- case PRU_RCVOOB:
- return (EOPNOTSUPP);
case PRU_RCVD:
/*
* If we are in a FLUSH state, check if the buffer is
@@ -259,8 +257,9 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
((sbspace(rop->rop_socket, &rop->rop_socket->so_rcv) ==
rop->rop_socket->so_rcv.sb_hiwat)))
rop->rop_flags &= ~ROUTECB_FLAG_FLUSH;
- return (0);
+ break;
+ case PRU_RCVOOB:
case PRU_SENDOOB:
error = EOPNOTSUPP;
break;
@@ -277,8 +276,10 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
}
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/netinet/ip_divert.c b/sys/netinet/ip_divert.c
index 3b7cb84a511..b74c0a2ba4c 100644
--- a/sys/netinet/ip_divert.c
+++ b/sys/netinet/ip_divert.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_divert.c,v 1.60 2018/11/10 18:40:34 bluhm Exp $ */
+/* $OpenBSD: ip_divert.c,v 1.61 2019/02/04 21:40:52 bluhm Exp $ */
/*
* Copyright (c) 2009 Michele Marchetto <michele@openbsd.org>
@@ -278,7 +278,7 @@ divert_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:
@@ -290,20 +290,20 @@ divert_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("divert_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/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 9fa04f328a3..9e1c0d1df37 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.118 2019/01/08 01:47:55 claudio Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.119 2019/02/04 21:40:52 bluhm Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -544,7 +544,7 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
/*
* stat: don't bother with a blocksize.
*/
- return (0);
+ break;
/*
* Not supported.
@@ -552,12 +552,10 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
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:
in_setsockaddr(inp, nam);
@@ -571,8 +569,10 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
panic("rip_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/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index f224f35787f..4c0f831615f 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.254 2018/11/10 18:40:34 bluhm Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.255 2019/02/04 21:40:52 bluhm Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -1184,26 +1184,26 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *addr,
* Perhaps Path MTU might be returned for a connected
* UDP socket in this case.
*/
- return (0);
+ break;
case PRU_SENDOOB:
case PRU_FASTTIMO:
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("udp_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/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);
}