diff options
author | Richard Scheffenegger <rscheff@FreeBSD.org> | 2022-06-08 07:14:16 +0000 |
---|---|---|
committer | Richard Scheffenegger <rscheff@FreeBSD.org> | 2022-06-08 07:18:32 +0000 |
commit | ce2525c8108a830d08d75771621d1bc580edd82c (patch) | |
tree | d2dc2d9808309ad368259305dae255638a837d0e | |
parent | c4c5981c14d5bd69e9df9ae691069ec4c2e92174 (diff) | |
download | src-ce2525c8108a830d08d75771621d1bc580edd82c.tar.gz src-ce2525c8108a830d08d75771621d1bc580edd82c.zip |
tcp: remove goto and address another NULL deref in SACK
Missed another NULL dereference during KASSERTS after traversing
the scoreboard. While at it, scratch the goto by making the
traversal conditional, and remove duplicate checks using an
unconditional loop with all checks inside.
Reviewed By: hselasky
PR: 263445
MFC after: 1 week
Sponsored by: NetApp, Inc.
Differential Revision: https://reviews.freebsd.org/D35428
-rw-r--r-- | sys/netinet/tcp_sack.c | 16 |
1 files changed, 9 insertions, 7 deletions
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 273d56c510e2..97f9f6546ca9 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -958,15 +958,17 @@ tcp_sack_output(struct tcpcb *tp, int *sack_bytes_rexmt) hole = tp->sackhint.nexthole; if (hole == NULL) return (hole); - if (SEQ_LT(hole->rxmit, hole->end)) - goto out; - while ((hole = TAILQ_NEXT(hole, scblink)) != NULL) { - if (SEQ_LT(hole->rxmit, hole->end)) { - tp->sackhint.nexthole = hole; - break; + if (SEQ_GEQ(hole->rxmit, hole->end)) { + for (;;) { + hole = TAILQ_NEXT(hole, scblink); + if (hole == NULL) + return (hole); + if (SEQ_LT(hole->rxmit, hole->end)) { + tp->sackhint.nexthole = hole; + break; + } } } -out: KASSERT(SEQ_LT(hole->start, hole->end), ("%s: hole.start >= hole.end", __func__)); KASSERT(SEQ_LT(hole->start, tp->snd_fack), ("%s: hole.start >= snd.fack", __func__)); KASSERT(SEQ_LT(hole->end, tp->snd_fack), ("%s: hole.end >= snd.fack", __func__)); |