aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/sm_statefuns.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/sm_statefuns.c')
-rw-r--r--net/sctp/sm_statefuns.c163
1 files changed, 130 insertions, 33 deletions
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 5e7fb0f54b88..caed19d90d06 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -90,6 +90,11 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
90 const sctp_subtype_t type, 90 const sctp_subtype_t type,
91 void *arg, 91 void *arg,
92 sctp_cmd_seq_t *commands); 92 sctp_cmd_seq_t *commands);
93static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
94 const struct sctp_association *asoc,
95 const sctp_subtype_t type,
96 void *arg,
97 sctp_cmd_seq_t *commands);
93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); 98static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
94 99
95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 100static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
@@ -98,6 +103,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
98 struct sctp_transport *transport); 103 struct sctp_transport *transport);
99 104
100static sctp_disposition_t sctp_sf_abort_violation( 105static sctp_disposition_t sctp_sf_abort_violation(
106 const struct sctp_endpoint *ep,
101 const struct sctp_association *asoc, 107 const struct sctp_association *asoc,
102 void *arg, 108 void *arg,
103 sctp_cmd_seq_t *commands, 109 sctp_cmd_seq_t *commands,
@@ -118,6 +124,13 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
118 void *arg, 124 void *arg,
119 sctp_cmd_seq_t *commands); 125 sctp_cmd_seq_t *commands);
120 126
127static sctp_disposition_t sctp_sf_violation_chunk(
128 const struct sctp_endpoint *ep,
129 const struct sctp_association *asoc,
130 const sctp_subtype_t type,
131 void *arg,
132 sctp_cmd_seq_t *commands);
133
121/* Small helper function that checks if the chunk length 134/* Small helper function that checks if the chunk length
122 * is of the appropriate length. The 'required_length' argument 135 * is of the appropriate length. The 'required_length' argument
123 * is set to be the size of a specific chunk we are testing. 136 * is set to be the size of a specific chunk we are testing.
@@ -181,16 +194,21 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
181 struct sctp_chunk *chunk = arg; 194 struct sctp_chunk *chunk = arg;
182 struct sctp_ulpevent *ev; 195 struct sctp_ulpevent *ev;
183 196
197 if (!sctp_vtag_verify_either(chunk, asoc))
198 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
199
184 /* RFC 2960 6.10 Bundling 200 /* RFC 2960 6.10 Bundling
185 * 201 *
186 * An endpoint MUST NOT bundle INIT, INIT ACK or 202 * An endpoint MUST NOT bundle INIT, INIT ACK or
187 * SHUTDOWN COMPLETE with any other chunks. 203 * SHUTDOWN COMPLETE with any other chunks.
188 */ 204 */
189 if (!chunk->singleton) 205 if (!chunk->singleton)
190 return SCTP_DISPOSITION_VIOLATION; 206 return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
191 207
192 if (!sctp_vtag_verify_either(chunk, asoc)) 208 /* Make sure that the SHUTDOWN_COMPLETE chunk has a valid length. */
193 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 209 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
210 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
211 commands);
194 212
195 /* RFC 2960 10.2 SCTP-to-ULP 213 /* RFC 2960 10.2 SCTP-to-ULP
196 * 214 *
@@ -450,17 +468,17 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
450 if (!sctp_vtag_verify(chunk, asoc)) 468 if (!sctp_vtag_verify(chunk, asoc))
451 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 469 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
452 470
453 /* Make sure that the INIT-ACK chunk has a valid length */
454 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
455 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
456 commands);
457 /* 6.10 Bundling 471 /* 6.10 Bundling
458 * An endpoint MUST NOT bundle INIT, INIT ACK or 472 * An endpoint MUST NOT bundle INIT, INIT ACK or
459 * SHUTDOWN COMPLETE with any other chunks. 473 * SHUTDOWN COMPLETE with any other chunks.
460 */ 474 */
461 if (!chunk->singleton) 475 if (!chunk->singleton)
462 return SCTP_DISPOSITION_VIOLATION; 476 return sctp_sf_violation_chunk(ep, asoc, type, arg, commands);
463 477
478 /* Make sure that the INIT-ACK chunk has a valid length */
479 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_initack_chunk_t)))
480 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
481 commands);
464 /* Grab the INIT header. */ 482 /* Grab the INIT header. */
465 chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data; 483 chunk->subh.init_hdr = (sctp_inithdr_t *) chunk->skb->data;
466 484
@@ -585,7 +603,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
585 * control endpoint, respond with an ABORT. 603 * control endpoint, respond with an ABORT.
586 */ 604 */
587 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) 605 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep)
588 return sctp_sf_ootb(ep, asoc, type, arg, commands); 606 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
589 607
590 /* Make sure that the COOKIE_ECHO chunk has a valid length. 608 /* Make sure that the COOKIE_ECHO chunk has a valid length.
591 * In this case, we check that we have enough for at least a 609 * In this case, we check that we have enough for at least a
@@ -2496,6 +2514,11 @@ sctp_disposition_t sctp_sf_do_9_2_reshutack(const struct sctp_endpoint *ep,
2496 struct sctp_chunk *chunk = (struct sctp_chunk *) arg; 2514 struct sctp_chunk *chunk = (struct sctp_chunk *) arg;
2497 struct sctp_chunk *reply; 2515 struct sctp_chunk *reply;
2498 2516
2517 /* Make sure that the chunk has a valid length */
2518 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
2519 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
2520 commands);
2521
2499 /* Since we are not going to really process this INIT, there 2522 /* Since we are not going to really process this INIT, there
2500 * is no point in verifying chunk boundries. Just generate 2523 * is no point in verifying chunk boundries. Just generate
2501 * the SHUTDOWN ACK. 2524 * the SHUTDOWN ACK.
@@ -2929,7 +2952,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2929 * 2952 *
2930 * The return value is the disposition of the chunk. 2953 * The return value is the disposition of the chunk.
2931*/ 2954*/
2932sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep, 2955static sctp_disposition_t sctp_sf_tabort_8_4_8(const struct sctp_endpoint *ep,
2933 const struct sctp_association *asoc, 2956 const struct sctp_association *asoc,
2934 const sctp_subtype_t type, 2957 const sctp_subtype_t type,
2935 void *arg, 2958 void *arg,
@@ -3126,14 +3149,14 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3126 3149
3127 ch = (sctp_chunkhdr_t *) chunk->chunk_hdr; 3150 ch = (sctp_chunkhdr_t *) chunk->chunk_hdr;
3128 do { 3151 do {
3129 /* Break out if chunk length is less then minimal. */ 3152 /* Report violation if the chunk is less then minimal */
3130 if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t)) 3153 if (ntohs(ch->length) < sizeof(sctp_chunkhdr_t))
3131 break; 3154 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3132 3155 commands);
3133 ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
3134 if (ch_end > skb_tail_pointer(skb))
3135 break;
3136 3156
3157 /* Now that we know we at least have a chunk header,
3158 * do things that are type appropriate.
3159 */
3137 if (SCTP_CID_SHUTDOWN_ACK == ch->type) 3160 if (SCTP_CID_SHUTDOWN_ACK == ch->type)
3138 ootb_shut_ack = 1; 3161 ootb_shut_ack = 1;
3139 3162
@@ -3145,6 +3168,12 @@ sctp_disposition_t sctp_sf_ootb(const struct sctp_endpoint *ep,
3145 if (SCTP_CID_ABORT == ch->type) 3168 if (SCTP_CID_ABORT == ch->type)
3146 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 3169 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3147 3170
3171 /* Report violation if chunk len overflows */
3172 ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
3173 if (ch_end > skb_tail_pointer(skb))
3174 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3175 commands);
3176
3148 ch = (sctp_chunkhdr_t *) ch_end; 3177 ch = (sctp_chunkhdr_t *) ch_end;
3149 } while (ch_end < skb_tail_pointer(skb)); 3178 } while (ch_end < skb_tail_pointer(skb));
3150 3179
@@ -3244,6 +3273,13 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
3244 void *arg, 3273 void *arg,
3245 sctp_cmd_seq_t *commands) 3274 sctp_cmd_seq_t *commands)
3246{ 3275{
3276 struct sctp_chunk *chunk = arg;
3277
3278 /* Make sure that the SHUTDOWN_ACK chunk has a valid length. */
3279 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3280 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3281 commands);
3282
3247 /* Although we do have an association in this case, it corresponds 3283 /* Although we do have an association in this case, it corresponds
3248 * to a restarted association. So the packet is treated as an OOTB 3284 * to a restarted association. So the packet is treated as an OOTB
3249 * packet and the state function that handles OOTB SHUTDOWN_ACK is 3285 * packet and the state function that handles OOTB SHUTDOWN_ACK is
@@ -3658,6 +3694,16 @@ sctp_disposition_t sctp_sf_discard_chunk(const struct sctp_endpoint *ep,
3658 void *arg, 3694 void *arg,
3659 sctp_cmd_seq_t *commands) 3695 sctp_cmd_seq_t *commands)
3660{ 3696{
3697 struct sctp_chunk *chunk = arg;
3698
3699 /* Make sure that the chunk has a valid length.
3700 * Since we don't know the chunk type, we use a general
3701 * chunkhdr structure to make a comparison.
3702 */
3703 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3704 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3705 commands);
3706
3661 SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk); 3707 SCTP_DEBUG_PRINTK("Chunk %d is discarded\n", type.chunk);
3662 return SCTP_DISPOSITION_DISCARD; 3708 return SCTP_DISPOSITION_DISCARD;
3663} 3709}
@@ -3713,6 +3759,13 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
3713 void *arg, 3759 void *arg,
3714 sctp_cmd_seq_t *commands) 3760 sctp_cmd_seq_t *commands)
3715{ 3761{
3762 struct sctp_chunk *chunk = arg;
3763
3764 /* Make sure that the chunk has a valid length. */
3765 if (!sctp_chunk_length_valid(chunk, sizeof(sctp_chunkhdr_t)))
3766 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3767 commands);
3768
3716 return SCTP_DISPOSITION_VIOLATION; 3769 return SCTP_DISPOSITION_VIOLATION;
3717} 3770}
3718 3771
@@ -3720,12 +3773,14 @@ sctp_disposition_t sctp_sf_violation(const struct sctp_endpoint *ep,
3720 * Common function to handle a protocol violation. 3773 * Common function to handle a protocol violation.
3721 */ 3774 */
3722static sctp_disposition_t sctp_sf_abort_violation( 3775static sctp_disposition_t sctp_sf_abort_violation(
3776 const struct sctp_endpoint *ep,
3723 const struct sctp_association *asoc, 3777 const struct sctp_association *asoc,
3724 void *arg, 3778 void *arg,
3725 sctp_cmd_seq_t *commands, 3779 sctp_cmd_seq_t *commands,
3726 const __u8 *payload, 3780 const __u8 *payload,
3727 const size_t paylen) 3781 const size_t paylen)
3728{ 3782{
3783 struct sctp_packet *packet = NULL;
3729 struct sctp_chunk *chunk = arg; 3784 struct sctp_chunk *chunk = arg;
3730 struct sctp_chunk *abort = NULL; 3785 struct sctp_chunk *abort = NULL;
3731 3786
@@ -3734,30 +3789,51 @@ static sctp_disposition_t sctp_sf_abort_violation(
3734 if (!abort) 3789 if (!abort)
3735 goto nomem; 3790 goto nomem;
3736 3791
3737 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 3792 if (asoc) {
3738 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 3793 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
3794 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3739 3795
3740 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) { 3796 if (asoc->state <= SCTP_STATE_COOKIE_ECHOED) {
3741 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 3797 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
3742 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); 3798 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
3743 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3799 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3744 SCTP_ERROR(ECONNREFUSED)); 3800 SCTP_ERROR(ECONNREFUSED));
3745 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 3801 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
3746 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); 3802 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
3803 } else {
3804 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3805 SCTP_ERROR(ECONNABORTED));
3806 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3807 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
3808 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3809 }
3747 } else { 3810 } else {
3748 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3811 packet = sctp_ootb_pkt_new(asoc, chunk);
3749 SCTP_ERROR(ECONNABORTED)); 3812
3750 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3813 if (!packet)
3751 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION)); 3814 goto nomem_pkt;
3752 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 3815
3816 if (sctp_test_T_bit(abort))
3817 packet->vtag = ntohl(chunk->sctp_hdr->vtag);
3818
3819 abort->skb->sk = ep->base.sk;
3820
3821 sctp_packet_append_chunk(packet, abort);
3822
3823 sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
3824 SCTP_PACKET(packet));
3825
3826 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3753 } 3827 }
3754 3828
3755 sctp_add_cmd_sf(commands, SCTP_CMD_DISCARD_PACKET, SCTP_NULL()); 3829 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
3756 3830
3757 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 3831 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
3758 3832
3759 return SCTP_DISPOSITION_ABORT; 3833 return SCTP_DISPOSITION_ABORT;
3760 3834
3835nomem_pkt:
3836 sctp_chunk_free(abort);
3761nomem: 3837nomem:
3762 return SCTP_DISPOSITION_NOMEM; 3838 return SCTP_DISPOSITION_NOMEM;
3763} 3839}
@@ -3790,7 +3866,7 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
3790{ 3866{
3791 char err_str[]="The following chunk had invalid length:"; 3867 char err_str[]="The following chunk had invalid length:";
3792 3868
3793 return sctp_sf_abort_violation(asoc, arg, commands, err_str, 3869 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3794 sizeof(err_str)); 3870 sizeof(err_str));
3795} 3871}
3796 3872
@@ -3809,10 +3885,31 @@ static sctp_disposition_t sctp_sf_violation_ctsn(
3809{ 3885{
3810 char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:"; 3886 char err_str[]="The cumulative tsn ack beyond the max tsn currently sent:";
3811 3887
3812 return sctp_sf_abort_violation(asoc, arg, commands, err_str, 3888 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3813 sizeof(err_str)); 3889 sizeof(err_str));
3814} 3890}
3815 3891
3892/* Handle protocol violation of an invalid chunk bundling. For example,
3893 * when we have an association and we recieve bundled INIT-ACK, or
3894 * SHUDOWN-COMPLETE, our peer is clearly violationg the "MUST NOT bundle"
3895 * statement from the specs. Additinally, there might be an attacker
3896 * on the path and we may not want to continue this communication.
3897 */
3898static sctp_disposition_t sctp_sf_violation_chunk(
3899 const struct sctp_endpoint *ep,
3900 const struct sctp_association *asoc,
3901 const sctp_subtype_t type,
3902 void *arg,
3903 sctp_cmd_seq_t *commands)
3904{
3905 char err_str[]="The following chunk violates protocol:";
3906
3907 if (!asoc)
3908 return sctp_sf_violation(ep, asoc, type, arg, commands);
3909
3910 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str,
3911 sizeof(err_str));
3912}
3816/*************************************************************************** 3913/***************************************************************************
3817 * These are the state functions for handling primitive (Section 10) events. 3914 * These are the state functions for handling primitive (Section 10) events.
3818 ***************************************************************************/ 3915 ***************************************************************************/