git: ce2525c8108a - main - tcp: remove goto and address another NULL deref in SACK

From: Richard Scheffenegger <rscheff_at_FreeBSD.org>
Date: Wed, 08 Jun 2022 07:39:14 UTC
The branch main has been updated by rscheff:

URL: https://cgit.FreeBSD.org/src/commit/?id=ce2525c8108a830d08d75771621d1bc580edd82c

commit ce2525c8108a830d08d75771621d1bc580edd82c
Author:     Richard Scheffenegger <rscheff@FreeBSD.org>
AuthorDate: 2022-06-08 07:14:16 +0000
Commit:     Richard Scheffenegger <rscheff@FreeBSD.org>
CommitDate: 2022-06-08 07:18:32 +0000

    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
---
 sys/netinet/tcp_sack.c | 16 +++++++++-------
 1 file 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__));