diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2019-02-06 17:32:17 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2019-02-06 17:32:17 +0000 |
commit | bfc2fcc73e669773d56e65b608d5ecb328b7cb41 (patch) | |
tree | 1ec38a37a7511cf82acdded6a95fae231af1c2b1 /sys | |
parent | 2219c6a5738ad07be1718f281f4c0c142dd51c7d (diff) |
Fix a possible mbuf leak in tcp_usrreq(). Make the error handling
more consistent to the other protocols' usrreq functions.
OK visa@ claudio@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/tcp_usrreq.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 73828d10fed..4eed4630e6c 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tcp_usrreq.c,v 1.170 2018/11/04 19:36:25 bluhm Exp $ */ +/* $OpenBSD: tcp_usrreq.c,v 1.171 2019/02/06 17:32:16 bluhm Exp $ */ /* $NetBSD: tcp_usrreq.c,v 1.20 1996/02/13 23:44:16 christos Exp $ */ /* @@ -145,9 +145,8 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, soassertlocked(so); if (control && control->m_len) { - m_freem(control); - m_freem(m); - return (EINVAL); + error = EINVAL; + goto release; } inp = sotoinpcb(so); @@ -160,18 +159,12 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, error = so->so_error; if (error == 0) error = EINVAL; - /* - * The following corrects an mbuf leak under rare - * circumstances - */ - if (req == PRU_SEND || req == PRU_SENDOOB) - m_freem(m); - return (error); + goto release; } tp = intotcpcb(inp); /* tp might get 0 when using socket splicing */ if (tp == NULL) - return (0); + goto release; if (so->so_options & SO_DEBUG) { otp = tp; ostate = tp->t_state; @@ -340,7 +333,7 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, case PRU_SENSE: ((struct stat *) m)->st_blksize = so->so_snd.sb_hiwat; - return (0); + break; case PRU_RCVOOB: if ((so->so_oobmark == 0 && @@ -405,6 +398,13 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam, if (otp) tcp_trace(TA_USER, ostate, tp, otp, NULL, req, 0); return (error); + + release: + if (req != PRU_RCVD && req != PRU_RCVOOB && req != PRU_SENSE) { + m_freem(control); + m_freem(m); + } + return (error); } int |