diff options
author | andre <andre@FreeBSD.org> | 2007-03-25 23:27:26 +0000 |
---|---|---|
committer | andre <andre@FreeBSD.org> | 2007-03-25 23:27:26 +0000 |
commit | 40f7cba48dbb0a1a972c957c9b81f2ea3647ef20 (patch) | |
tree | d17f45bbcf74f0d173fa00c5ec0e2337888c25e0 /sys/netinet/tcp_sack.c | |
parent | 124744263c60bbdc3eff9bae36783d3987835140 (diff) | |
download | FreeBSD-src-40f7cba48dbb0a1a972c957c9b81f2ea3647ef20.zip FreeBSD-src-40f7cba48dbb0a1a972c957c9b81f2ea3647ef20.tar.gz |
In tcp_sack_doack() remove too tight KASSERT() added in last revision. This
function may be called without any TCP SACK option blocks present. Protect
iteration over SACK option blocks by checking for SACK options present flag
first.
Bug reported by: wkoszek, keramida, Nicolas Blais
Diffstat (limited to 'sys/netinet/tcp_sack.c')
-rw-r--r-- | sys/netinet/tcp_sack.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/sys/netinet/tcp_sack.c b/sys/netinet/tcp_sack.c index 39aa87a..5c88480 100644 --- a/sys/netinet/tcp_sack.c +++ b/sys/netinet/tcp_sack.c @@ -371,7 +371,6 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) int i, j, num_sack_blks; INP_LOCK_ASSERT(tp->t_inpcb); - KASSERT(to->to_flags & TOF_SACK, ("%s: SACK invalid", __func__)); num_sack_blks = 0; /* @@ -383,21 +382,24 @@ tcp_sack_doack(struct tcpcb *tp, struct tcpopt *to, tcp_seq th_ack) sack_blocks[num_sack_blks++].end = th_ack; } /* - * Append received valid SACK blocks to sack_blocks[]. + * Append received valid SACK blocks to sack_blocks[], but only + * if we received new blocks from the other side. */ - for (i = 0; i < to->to_nsacks; i++) { - bcopy((to->to_sacks + i * TCPOLEN_SACK), &sack, sizeof(sack)); - sack.start = ntohl(sack.start); - sack.end = ntohl(sack.end); - if (SEQ_GT(sack.end, sack.start) && - SEQ_GT(sack.start, tp->snd_una) && - SEQ_GT(sack.start, th_ack) && - SEQ_LT(sack.start, tp->snd_max) && - SEQ_GT(sack.end, tp->snd_una) && - SEQ_LEQ(sack.end, tp->snd_max)) - sack_blocks[num_sack_blks++] = sack; + if (to->to_flags & TOF_SACK) { + for (i = 0; i < to->to_nsacks; i++) { + bcopy((to->to_sacks + i * TCPOLEN_SACK), + &sack, sizeof(sack)); + sack.start = ntohl(sack.start); + sack.end = ntohl(sack.end); + if (SEQ_GT(sack.end, sack.start) && + SEQ_GT(sack.start, tp->snd_una) && + SEQ_GT(sack.start, th_ack) && + SEQ_LT(sack.start, tp->snd_max) && + SEQ_GT(sack.end, tp->snd_una) && + SEQ_LEQ(sack.end, tp->snd_max)) + sack_blocks[num_sack_blks++] = sack; + } } - /* * Return if SND.UNA is not advanced and no valid SACK block * is received. |