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
This commit is contained in:
Andre Oppermann 2007-03-25 23:27:26 +00:00
parent 30916a2d1d
commit 07b64b901a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=167888

View File

@ -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.