diff options
author | ps <ps@FreeBSD.org> | 2005-06-09 14:01:04 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2005-06-09 14:01:04 +0000 |
commit | 0c131b3254b0b5c60301d440396e5154a882b42b (patch) | |
tree | 7fa55c19ac3d1ea4bb1f2b0cabdba7dcd53bbd16 | |
parent | 9f2fa9c999a02d853ea712c68c2734e723edf468 (diff) | |
download | FreeBSD-src-0c131b3254b0b5c60301d440396e5154a882b42b.zip FreeBSD-src-0c131b3254b0b5c60301d440396e5154a882b42b.tar.gz |
Fix for a crash in tcp_sack_option() caused by hitting the limit on
the number of sack holes.
Reported by: Andrey Chernov
Submitted by: Noritoshi Demizu
Reviewed by: Raja Mukerji
-rw-r--r-- | sys/netinet/tcp_sack.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 7708e9d..a159ce8 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -458,6 +458,9 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen) * beyond the current fack, they will be inserted by * way of hole splitting in the while-loop below. */ + temp = tcp_sackhole_insert(tp, tp->snd_fack,sblkp->start,NULL); + if (temp == NULL) + return 0; tcp_sackhole_insert(tp, tp->snd_fack, sblkp->start, NULL); tp->snd_fack = sblkp->end; /* Go to the previous sack block. */ @@ -465,6 +468,8 @@ tcp_sack_option(struct tcpcb *tp, struct tcphdr *th, u_char *cp, int optlen) } else if (SEQ_LT(tp->snd_fack, sblkp->end)) /* fack is advanced. */ tp->snd_fack = sblkp->end; + /* We must have at least one SACK hole in scoreboard */ + KASSERT(!TAILQ_EMPTY(&tp->snd_holes), ("SACK scoreboard must not be empty")); cur = TAILQ_LAST(&tp->snd_holes, sackhole_head); /* Last SACK hole */ /* * Since the incoming sack blocks are sorted, we can process them |