Skip to content

Commit

Permalink
Improve input validation of data chunks
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
tuexen committed Aug 3, 2024
1 parent 0b14cf4 commit 1330843
Showing 1 changed file with 17 additions and 18 deletions.
35 changes: 17 additions & 18 deletions usrsctplib/netinet/sctp_indata.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,21 +778,6 @@ sctp_build_readq_entry_from_ctl(struct sctp_queued_to_read *nc, struct sctp_queu
nc->do_not_ref_stcb = control->do_not_ref_stcb;
}

static void
sctp_reset_a_control(struct sctp_queued_to_read *control,
struct sctp_inpcb *inp, uint32_t tsn)
{
control->fsn_included = tsn;
if (control->on_read_q) {
/*
* We have to purge it from there,
* hopefully this will work :-)
*/
TAILQ_REMOVE(&inp->read_queue, control, next);
control->on_read_q = 0;
}
}

static int
sctp_handle_old_unordered_data(struct sctp_tcb *stcb,
struct sctp_association *asoc,
Expand Down Expand Up @@ -1923,7 +1908,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
SCTP_SNPRINTF(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", mid);
goto err_out;
} else {
if ((tsn == control->fsn_included + 1) &&
if ((control->first_frag_seen) &&
(tsn == control->fsn_included + 1) &&
(control->end_added == 0)) {
SCTP_SNPRINTF(msg, sizeof(msg),
"Illegal message sequence, missing end for MID: %8.8x",
Expand Down Expand Up @@ -5497,12 +5483,25 @@ sctp_flush_reassm_for_str_seq(struct sctp_tcb *stcb,
sctp_free_a_chunk(stcb, chk, SCTP_SO_NOT_LOCKED);
}
if (!TAILQ_EMPTY(&control->reasm)) {
/* This has to be old data, unordered */
KASSERT(!asoc->idata_supported,
("Reassembly queue not empty for I-DATA"));
KASSERT(!ordered,
("Reassembly queue not empty for ordered data"));
if (control->data) {
sctp_m_freem(control->data);
control->data = NULL;
}
sctp_reset_a_control(control, stcb->sctp_ep, cumtsn);
control->fsn_included = 0xffffffff;
control->first_frag_seen = 0;
control->last_frag_seen = 0;
if (control->on_read_q) {
/*
* We have to purge it from there,
* hopefully this will work :-)
*/
TAILQ_REMOVE(&stcb->sctp_ep->read_queue, control, next);
control->on_read_q = 0;
}
chk = TAILQ_FIRST(&control->reasm);
if (chk->rec.data.rcv_flags & SCTP_DATA_FIRST_FRAG) {
TAILQ_REMOVE(&control->reasm, chk, sctp_next);
Expand Down

0 comments on commit 1330843

Please sign in to comment.