diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2019-02-04 21:40:53 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2019-02-04 21:40:53 +0000 |
commit | 4425e9bbfb4c5db368521828a0a414813d286ead (patch) | |
tree | 3b48fa737daccb525ea8d9d22d874f6b9e58178b /sys/net/rtsock.c | |
parent | f26d6481410d505c29f1fb0f7f5bbd5f526698f4 (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.c | 15 |
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); } |