summaryrefslogtreecommitdiff
path: root/sys/net/rtsock.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2019-02-04 21:40:53 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2019-02-04 21:40:53 +0000
commit4425e9bbfb4c5db368521828a0a414813d286ead (patch)
tree3b48fa737daccb525ea8d9d22d874f6b9e58178b /sys/net/rtsock.c
parentf26d6481410d505c29f1fb0f7f5bbd5f526698f4 (diff)
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/net/rtsock.c')
-rw-r--r--sys/net/rtsock.c15
1 files changed, 8 insertions, 7 deletions
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);
}