summaryrefslogtreecommitdiffstats
path: root/sys/netinet/tcp_sack.c
diff options
context:
space:
mode:
authorandre <andre@FreeBSD.org>2007-03-25 23:27:26 +0000
committerandre <andre@FreeBSD.org>2007-03-25 23:27:26 +0000
commit40f7cba48dbb0a1a972c957c9b81f2ea3647ef20 (patch)
treed17f45bbcf74f0d173fa00c5ec0e2337888c25e0 /sys/netinet/tcp_sack.c
parent124744263c60bbdc3eff9bae36783d3987835140 (diff)
downloadFreeBSD-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.c30
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.
OpenPOWER on IntegriCloud