Skip to content

Commit 1330843

Browse files
committed
Improve input validation of data chunks
fsn_included should only be considered, if first_frag_seen is true. Also, fix the resetting of the control structure, if stream queues are flushed. This fixes #597 where a legitimate message sequence was incorrectly classified as illegitimate.
1 parent 0b14cf4 commit 1330843

File tree

1 file changed

+17
-18
lines changed

1 file changed

+17
-18
lines changed

usrsctplib/netinet/sctp_indata.c

+17-18
Original file line numberDiff line numberDiff line change
@@ -778,21 +778,6 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_read *nc, struct sctp_queu
778778
nc->do_not_ref_stcb = control->do_not_ref_stcb;
779779
}
780780

781-
static void
782-
sctp_reset_a_control(struct sctp_queued_to_read *control,
783-
struct sctp_inpcb *inp, uint32_t tsn)
784-
{
785-
control->fsn_included = tsn;
786-
if (control->on_read_q) {
787-
/*
788-
* We have to purge it from there,
789-
* hopefully this will work :-)
790-
*/
791-
TAILQ_REMOVE(&inp->read_queue, control, next);
792-
control->on_read_q = 0;
793-
}
794-
}
795-
796781
static int
797782
sctp_handle_old_unordered_data(struct sctp_tcb *stcb,
798783
struct sctp_association *asoc,
@@ -1923,7 +1908,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
19231908
SCTP_SNPRINTF(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", mid);
19241909
goto err_out;
19251910
} else {
1926-
if ((tsn == control->fsn_included + 1) &&
1911+
if ((control->first_frag_seen) &&
1912+
(tsn == control->fsn_included + 1) &&
19271913
(control->end_added == 0)) {
19281914
SCTP_SNPRINTF(msg, sizeof(msg),
19291915
"Illegal message sequence, missing end for MID: %8.8x",
@@ -5497,12 +5483,25 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
54975483
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
54985484
}
54995485
if (!TAILQ_EMPTY(&control->reasm)) {
5500-
/* This has to be old data, unordered */
5486+
KASSERT(!asoc->idata_supported,
5487+
("Reassembly queue not empty for I-DATA"));
5488+
KASSERT(!ordered,
5489+
("Reassembly queue not empty for ordered data"));
55015490
if (control->data) {
55025491
sctp_m_freem(control->data);
55035492
control->data = NULL;
55045493
}
5505-
sctp_reset_a_control(control, stcb->sctp_ep, cumtsn);
5494+
control->fsn_included = 0xffffffff;
5495+
control->first_frag_seen = 0;
5496+
control->last_frag_seen = 0;
5497+
if (control->on_read_q) {
5498+
/*
5499+
* We have to purge it from there,
5500+
* hopefully this will work :-)
5501+
*/
5502+
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
5503+
control->on_read_q = 0;
5504+
}
55065505
chk = TAILQ_FIRST(&control->reasm);
55075506
if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
55085507
TAILQ_REMOVE(&control->reasm, chk, sctp_next);

0 commit comments

Comments
 (0)