summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2016-08-15 05:07:02 +0000
committertuexen <tuexen@FreeBSD.org>2016-08-15 05:07:02 +0000
commit7ada4ea39af0296c65a7cc37661a5d883fdfa3f4 (patch)
tree4aa750d8c95278924eaea6c65f07cf5fa8e34ae4
parenta49b7a52e6efd5cb4204f759cb5ed4202658952c (diff)
downloadFreeBSD-src-7ada4ea39af0296c65a7cc37661a5d883fdfa3f4.zip
FreeBSD-src-7ada4ea39af0296c65a7cc37661a5d883fdfa3f4.tar.gz
MFC r304082:
Improve a consistency check to not detect valid cases for unordered user messages using DATA chunks as invalid ones. While there, ensure that error causes are provided when sending ABORT chunks in case of reassembly problems detected. Thanks to Taylor Brandstetter for making me aware of this problem. Approved by: re (gjb)
-rw-r--r--sys/netinet/sctp_indata.c45
1 files changed, 31 insertions, 14 deletions
diff --git a/sys/netinet/sctp_indata.c b/sys/netinet/sctp_indata.c
index e5ff349..4011253 100644
--- a/sys/netinet/sctp_indata.c
+++ b/sys/netinet/sctp_indata.c
@@ -1747,21 +1747,27 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* If its a fragmented message, lets see if we can find the control
* on the reassembly queues.
*/
- if ((chtype == SCTP_IDATA) && ((chunk_flags & SCTP_DATA_FIRST_FRAG) == 0) && (fsn == 0)) {
+ if ((chtype == SCTP_IDATA) &&
+ ((chunk_flags & SCTP_DATA_FIRST_FRAG) == 0) &&
+ (fsn == 0)) {
/*
* The first *must* be fsn 0, and other (middle/end) pieces
- * can *not* be fsn 0.
+ * can *not* be fsn 0. XXX: This can happen in case of a
+ * wrap around. Ignore is for now.
*/
+ snprintf(msg, sizeof(msg), "FSN zero for MID=%8.8x, but flags=%2.2x",
+ msg_id, chunk_flags);
goto err_out;
}
+ control = sctp_find_reasm_entry(strm, msg_id, ordered, old_data);
+ SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for control on queues %p\n",
+ chunk_flags, control);
if ((chunk_flags & SCTP_DATA_NOT_FRAG) != SCTP_DATA_NOT_FRAG) {
/* See if we can find the re-assembly entity */
- control = sctp_find_reasm_entry(strm, msg_id, ordered, old_data);
- SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for control on queues %p\n",
- chunk_flags, control);
- if (control) {
+ if (control != NULL) {
/* We found something, does it belong? */
if (ordered && (msg_id != control->sinfo_ssn)) {
+ snprintf(msg, sizeof(msg), "Reassembly problem (MID=%8.8x)", msg_id);
err_out:
op_err = sctp_generate_cause(SCTP_CAUSE_PROTOCOL_VIOLATION, msg);
stcb->sctp_ep->last_abort_code = SCTP_FROM_SCTP_INDATA + SCTP_LOC_15;
@@ -1774,6 +1780,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* We can't have a switched order with an
* unordered chunk
*/
+ snprintf(msg, sizeof(msg), "All fragments of a user message must be ordered or unordered (TSN=%8.8x)",
+ tsn);
goto err_out;
}
if (!ordered && (((control->sinfo_flags >> 8) & SCTP_DATA_UNORDERED) == 0)) {
@@ -1781,6 +1789,8 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* We can't have a switched unordered with a
* ordered chunk
*/
+ snprintf(msg, sizeof(msg), "All fragments of a user message must be ordered or unordered (TSN=%8.8x)",
+ tsn);
goto err_out;
}
}
@@ -1790,14 +1800,21 @@ sctp_process_a_data_chunk(struct sctp_tcb *stcb, struct sctp_association *asoc,
* re-assembly going on with the same Stream/Seq (for
* ordered) or in the same Stream for unordered.
*/
- SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags:0x%x look for msg in case we have dup\n",
- chunk_flags);
- if (sctp_find_reasm_entry(strm, msg_id, ordered, old_data)) {
- SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on msg_id: %u\n",
- chunk_flags,
- msg_id);
-
- goto err_out;
+ if (control != NULL) {
+ if (ordered || (old_data == 0)) {
+ SCTPDBG(SCTP_DEBUG_XXX, "chunk_flags: 0x%x dup detected on msg_id: %u\n",
+ chunk_flags, msg_id);
+ snprintf(msg, sizeof(msg), "Duplicate MID=%8.8x detected.", msg_id);
+ goto err_out;
+ } else {
+ if ((tsn == control->fsn_included + 1) &&
+ (control->end_added == 0)) {
+ snprintf(msg, sizeof(msg), "Illegal message sequence, missing end for MID: %8.8x", control->fsn_included);
+ goto err_out;
+ } else {
+ control = NULL;
+ }
+ }
}
}
/* now do the tests */
OpenPOWER on IntegriCloud