git: 4287aa56197f - main - tcp_usr_shutdown: don't cast inp_ppcb to tcpcb before checking inp_flags
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 28 Dec 2021 16:53:24 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=4287aa56197fc2e37cad07c23b52f9ed4f1a7fd0
commit 4287aa56197fc2e37cad07c23b52f9ed4f1a7fd0
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2021-12-28 16:50:02 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2021-12-28 16:50:02 +0000
tcp_usr_shutdown: don't cast inp_ppcb to tcpcb before checking inp_flags
While here move out one more erroneous condition out of the epoch and
common return. The only functional change is that if we send control
on a shut down socket we would get EINVAL instead of ECONNRESET.
Reviewed by: tuexen
Reported by: syzbot+8388cf7f401a7b6bece6@syzkaller.appspotmail.com
Fixes: f64dc2ab5be38e5366271ef85ea90d8cb1c7841a
---
sys/netinet/tcp_usrreq.c | 39 ++++++++++++++++++---------------------
1 file changed, 18 insertions(+), 21 deletions(-)
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index 2dea7253e0d6..def7d477c72b 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -993,34 +993,31 @@ tcp_usr_send(struct socket *so, int flags, struct mbuf *m,
bool restoreflags;
TCPDEBUG0;
- /*
- * We require the pcbinfo "read lock" if we will close the socket
- * as part of this call.
- */
- NET_EPOCH_ENTER(et);
- inp = sotoinpcb(so);
- KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
- INP_WLOCK(inp);
- tp = intotcpcb(inp);
- vflagsav = inp->inp_vflag;
- incflagsav = inp->inp_inc.inc_flags;
- restoreflags = false;
- if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
- if (control)
- m_freem(control);
- error = ECONNRESET;
- goto out;
- }
if (control != NULL) {
/* TCP doesn't do control messages (rights, creds, etc) */
if (control->m_len) {
m_freem(control);
- error = EINVAL;
- goto out;
+ return (EINVAL);
}
m_freem(control); /* empty control, just free it */
- control = NULL;
}
+
+ inp = sotoinpcb(so);
+ KASSERT(inp != NULL, ("tcp_usr_send: inp == NULL"));
+ INP_WLOCK(inp);
+ if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) {
+ if (m != NULL && (flags & PRUS_NOTREADY) == 0)
+ m_freem(m);
+ INP_WUNLOCK(inp);
+ return (ECONNRESET);
+ }
+
+ vflagsav = inp->inp_vflag;
+ incflagsav = inp->inp_inc.inc_flags;
+ restoreflags = false;
+ tp = intotcpcb(inp);
+
+ NET_EPOCH_ENTER(et);
if ((flags & PRUS_OOB) != 0 &&
(error = tcp_pru_options_support(tp, PRUS_OOB)) != 0)
goto out;