summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2019-02-06 17:32:17 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2019-02-06 17:32:17 +0000
commitbfc2fcc73e669773d56e65b608d5ecb328b7cb41 (patch)
tree1ec38a37a7511cf82acdded6a95fae231af1c2b1 /sys
parent2219c6a5738ad07be1718f281f4c0c142dd51c7d (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.c26
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