aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/sctp/constants.h4
-rw-r--r--include/net/sctp/sm.h1
-rw-r--r--include/net/sctp/structs.h8
-rw-r--r--net/sctp/associola.c10
-rw-r--r--net/sctp/endpointola.c29
-rw-r--r--net/sctp/input.c65
-rw-r--r--net/sctp/inqueue.c19
-rw-r--r--net/sctp/sm_statefuns.c218
-rw-r--r--net/sctp/sm_statetable.c33
9 files changed, 374 insertions, 13 deletions
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 777118f06dba..da8354e8e33c 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -183,7 +183,9 @@ typedef enum {
183 SCTP_IERROR_NO_DATA, 183 SCTP_IERROR_NO_DATA,
184 SCTP_IERROR_BAD_STREAM, 184 SCTP_IERROR_BAD_STREAM,
185 SCTP_IERROR_BAD_PORTS, 185 SCTP_IERROR_BAD_PORTS,
186 186 SCTP_IERROR_AUTH_BAD_HMAC,
187 SCTP_IERROR_AUTH_BAD_KEYID,
188 SCTP_IERROR_PROTO_VIOLATION,
187} sctp_ierror_t; 189} sctp_ierror_t;
188 190
189 191
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 148cdb4b9606..bf2f5ed69c15 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -143,6 +143,7 @@ sctp_state_fn_t sctp_sf_do_asconf_ack;
143sctp_state_fn_t sctp_sf_do_9_2_reshutack; 143sctp_state_fn_t sctp_sf_do_9_2_reshutack;
144sctp_state_fn_t sctp_sf_eat_fwd_tsn; 144sctp_state_fn_t sctp_sf_eat_fwd_tsn;
145sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast; 145sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
146sctp_state_fn_t sctp_sf_eat_auth;
146 147
147/* Prototypes for primitive event state functions. */ 148/* Prototypes for primitive event state functions. */
148sctp_state_fn_t sctp_sf_do_prm_asoc; 149sctp_state_fn_t sctp_sf_do_prm_asoc;
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 31841c3a7fe8..47e54f8e2b65 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -724,6 +724,13 @@ struct sctp_chunk {
724 */ 724 */
725 struct sctp_transport *transport; 725 struct sctp_transport *transport;
726 726
727 /* SCTP-AUTH: For the special case inbound processing of COOKIE-ECHO
728 * we need save a pointer to the AUTH chunk, since the SCTP-AUTH
729 * spec violates the principle premis that all chunks are processed
730 * in order.
731 */
732 struct sk_buff *auth_chunk;
733
727 __u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */ 734 __u8 rtt_in_progress; /* Is this chunk used for RTT calculation? */
728 __u8 resent; /* Has this chunk ever been retransmitted. */ 735 __u8 resent; /* Has this chunk ever been retransmitted. */
729 __u8 has_tsn; /* Does this chunk have a TSN yet? */ 736 __u8 has_tsn; /* Does this chunk have a TSN yet? */
@@ -1067,6 +1074,7 @@ void sctp_inq_init(struct sctp_inq *);
1067void sctp_inq_free(struct sctp_inq *); 1074void sctp_inq_free(struct sctp_inq *);
1068void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet); 1075void sctp_inq_push(struct sctp_inq *, struct sctp_chunk *packet);
1069struct sctp_chunk *sctp_inq_pop(struct sctp_inq *); 1076struct sctp_chunk *sctp_inq_pop(struct sctp_inq *);
1077struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *);
1070void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t); 1078void sctp_inq_set_th_handler(struct sctp_inq *, work_func_t);
1071 1079
1072/* This is the structure we use to hold outbound chunks. You push 1080/* This is the structure we use to hold outbound chunks. You push
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 3bdd8dcb76a7..03158e3665da 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1011,6 +1011,16 @@ static void sctp_assoc_bh_rcv(struct work_struct *work)
1011 state = asoc->state; 1011 state = asoc->state;
1012 subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); 1012 subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
1013 1013
1014 /* SCTP-AUTH, Section 6.3:
1015 * The receiver has a list of chunk types which it expects
1016 * to be received only after an AUTH-chunk. This list has
1017 * been sent to the peer during the association setup. It
1018 * MUST silently discard these chunks if they are not placed
1019 * after an AUTH chunk in the packet.
1020 */
1021 if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
1022 continue;
1023
1014 /* Remember where the last DATA chunk came from so we 1024 /* Remember where the last DATA chunk came from so we
1015 * know where to send the SACK. 1025 * know where to send the SACK.
1016 */ 1026 */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index c8d5023606a5..2d2d81ef4a69 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -400,6 +400,7 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
400 sctp_subtype_t subtype; 400 sctp_subtype_t subtype;
401 sctp_state_t state; 401 sctp_state_t state;
402 int error = 0; 402 int error = 0;
403 int first_time = 1; /* is this the first time through the looop */
403 404
404 if (ep->base.dead) 405 if (ep->base.dead)
405 return; 406 return;
@@ -411,6 +412,29 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
411 while (NULL != (chunk = sctp_inq_pop(inqueue))) { 412 while (NULL != (chunk = sctp_inq_pop(inqueue))) {
412 subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type); 413 subtype = SCTP_ST_CHUNK(chunk->chunk_hdr->type);
413 414
415 /* If the first chunk in the packet is AUTH, do special
416 * processing specified in Section 6.3 of SCTP-AUTH spec
417 */
418 if (first_time && (subtype.chunk == SCTP_CID_AUTH)) {
419 struct sctp_chunkhdr *next_hdr;
420
421 next_hdr = sctp_inq_peek(inqueue);
422 if (!next_hdr)
423 goto normal;
424
425 /* If the next chunk is COOKIE-ECHO, skip the AUTH
426 * chunk while saving a pointer to it so we can do
427 * Authentication later (during cookie-echo
428 * processing).
429 */
430 if (next_hdr->type == SCTP_CID_COOKIE_ECHO) {
431 chunk->auth_chunk = skb_clone(chunk->skb,
432 GFP_ATOMIC);
433 chunk->auth = 1;
434 continue;
435 }
436 }
437normal:
414 /* We might have grown an association since last we 438 /* We might have grown an association since last we
415 * looked, so try again. 439 * looked, so try again.
416 * 440 *
@@ -426,6 +450,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
426 } 450 }
427 451
428 state = asoc ? asoc->state : SCTP_STATE_CLOSED; 452 state = asoc ? asoc->state : SCTP_STATE_CLOSED;
453 if (sctp_auth_recv_cid(subtype.chunk, asoc) && !chunk->auth)
454 continue;
429 455
430 /* Remember where the last DATA chunk came from so we 456 /* Remember where the last DATA chunk came from so we
431 * know where to send the SACK. 457 * know where to send the SACK.
@@ -449,5 +475,8 @@ static void sctp_endpoint_bh_rcv(struct work_struct *work)
449 */ 475 */
450 if (!sctp_sk(sk)->ep) 476 if (!sctp_sk(sk)->ep)
451 break; 477 break;
478
479 if (first_time)
480 first_time = 0;
452 } 481 }
453} 482}
diff --git a/net/sctp/input.c b/net/sctp/input.c
index f9a0c9276e3b..86503e7fa21e 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -911,15 +911,6 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
911 911
912 ch = (sctp_chunkhdr_t *) skb->data; 912 ch = (sctp_chunkhdr_t *) skb->data;
913 913
914 /* If this is INIT/INIT-ACK look inside the chunk too. */
915 switch (ch->type) {
916 case SCTP_CID_INIT:
917 case SCTP_CID_INIT_ACK:
918 break;
919 default:
920 return NULL;
921 }
922
923 /* The code below will attempt to walk the chunk and extract 914 /* The code below will attempt to walk the chunk and extract
924 * parameter information. Before we do that, we need to verify 915 * parameter information. Before we do that, we need to verify
925 * that the chunk length doesn't cause overflow. Otherwise, we'll 916 * that the chunk length doesn't cause overflow. Otherwise, we'll
@@ -964,6 +955,60 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
964 return NULL; 955 return NULL;
965} 956}
966 957
958/* SCTP-AUTH, Section 6.3:
959* If the receiver does not find a STCB for a packet containing an AUTH
960* chunk as the first chunk and not a COOKIE-ECHO chunk as the second
961* chunk, it MUST use the chunks after the AUTH chunk to look up an existing
962* association.
963*
964* This means that any chunks that can help us identify the association need
965* to be looked at to find this assocation.
966*
967* TODO: The only chunk currently defined that can do that is ASCONF, but we
968* don't support that functionality yet.
969*/
970static struct sctp_association *__sctp_rcv_auth_lookup(struct sk_buff *skb,
971 const union sctp_addr *paddr,
972 const union sctp_addr *laddr,
973 struct sctp_transport **transportp)
974{
975 /* XXX - walk through the chunks looking for something that can
976 * help us find the association. INIT, and INIT-ACK are not permitted.
977 * That leaves ASCONF, but we don't support that yet.
978 */
979 return NULL;
980}
981
982/*
983 * There are circumstances when we need to look inside the SCTP packet
984 * for information to help us find the association. Examples
985 * include looking inside of INIT/INIT-ACK chunks or after the AUTH
986 * chunks.
987 */
988static struct sctp_association *__sctp_rcv_lookup_harder(struct sk_buff *skb,
989 const union sctp_addr *paddr,
990 const union sctp_addr *laddr,
991 struct sctp_transport **transportp)
992{
993 sctp_chunkhdr_t *ch;
994
995 ch = (sctp_chunkhdr_t *) skb->data;
996
997 /* If this is INIT/INIT-ACK look inside the chunk too. */
998 switch (ch->type) {
999 case SCTP_CID_INIT:
1000 case SCTP_CID_INIT_ACK:
1001 return __sctp_rcv_init_lookup(skb, laddr, transportp);
1002 break;
1003
1004 case SCTP_CID_AUTH:
1005 return __sctp_rcv_auth_lookup(skb, paddr, laddr, transportp);
1006 break;
1007 }
1008
1009 return NULL;
1010}
1011
967/* Lookup an association for an inbound skb. */ 1012/* Lookup an association for an inbound skb. */
968static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb, 1013static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
969 const union sctp_addr *paddr, 1014 const union sctp_addr *paddr,
@@ -979,7 +1024,7 @@ static struct sctp_association *__sctp_rcv_lookup(struct sk_buff *skb,
979 * parameters within the INIT or INIT-ACK. 1024 * parameters within the INIT or INIT-ACK.
980 */ 1025 */
981 if (!asoc) 1026 if (!asoc)
982 asoc = __sctp_rcv_init_lookup(skb, laddr, transportp); 1027 asoc = __sctp_rcv_lookup_harder(skb, paddr, laddr, transportp);
983 1028
984 return asoc; 1029 return asoc;
985} 1030}
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index e4ea7fdf36ed..f10fe7fbf24c 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -100,6 +100,25 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
100 q->immediate.func(&q->immediate); 100 q->immediate.func(&q->immediate);
101} 101}
102 102
103/* Peek at the next chunk on the inqeue. */
104struct sctp_chunkhdr *sctp_inq_peek(struct sctp_inq *queue)
105{
106 struct sctp_chunk *chunk;
107 sctp_chunkhdr_t *ch = NULL;
108
109 chunk = queue->in_progress;
110 /* If there is no more chunks in this packet, say so */
111 if (chunk->singleton ||
112 chunk->end_of_packet ||
113 chunk->pdiscard)
114 return NULL;
115
116 ch = (sctp_chunkhdr_t *)chunk->chunk_end;
117
118 return ch;
119}
120
121
103/* Extract a chunk from an SCTP inqueue. 122/* Extract a chunk from an SCTP inqueue.
104 * 123 *
105 * WARNING: If you need to put the chunk on another queue, you need to 124 * WARNING: If you need to put the chunk on another queue, you need to
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 385486360fe9..5aef4aafdfdc 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -138,6 +138,11 @@ static sctp_disposition_t sctp_sf_violation_chunk(
138 void *arg, 138 void *arg,
139 sctp_cmd_seq_t *commands); 139 sctp_cmd_seq_t *commands);
140 140
141static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
142 const struct sctp_association *asoc,
143 const sctp_subtype_t type,
144 struct sctp_chunk *chunk);
145
141/* Small helper function that checks if the chunk length 146/* Small helper function that checks if the chunk length
142 * is of the appropriate length. The 'required_length' argument 147 * is of the appropriate length. The 'required_length' argument
143 * is set to be the size of a specific chunk we are testing. 148 * is set to be the size of a specific chunk we are testing.
@@ -495,8 +500,6 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
495 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, 500 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
496 &err_chunk)) { 501 &err_chunk)) {
497 502
498 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
499
500 /* This chunk contains fatal error. It is to be discarded. 503 /* This chunk contains fatal error. It is to be discarded.
501 * Send an ABORT, with causes if there is any. 504 * Send an ABORT, with causes if there is any.
502 */ 505 */
@@ -521,6 +524,22 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
521 sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); 524 sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
522 error = SCTP_ERROR_INV_PARAM; 525 error = SCTP_ERROR_INV_PARAM;
523 } 526 }
527
528 /* SCTP-AUTH, Section 6.3:
529 * It should be noted that if the receiver wants to tear
530 * down an association in an authenticated way only, the
531 * handling of malformed packets should not result in
532 * tearing down the association.
533 *
534 * This means that if we only want to abort associations
535 * in an authenticated way (i.e AUTH+ABORT), then we
536 * can't destory this association just becuase the packet
537 * was malformed.
538 */
539 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
540 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
541
542 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
524 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED, 543 return sctp_stop_t1_and_abort(commands, error, ECONNREFUSED,
525 asoc, chunk->transport); 544 asoc, chunk->transport);
526 } 545 }
@@ -699,6 +718,36 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
699 if (error) 718 if (error)
700 goto nomem_init; 719 goto nomem_init;
701 720
721 /* SCTP-AUTH: auth_chunk pointer is only set when the cookie-echo
722 * is supposed to be authenticated and we have to do delayed
723 * authentication. We've just recreated the association using
724 * the information in the cookie and now it's much easier to
725 * do the authentication.
726 */
727 if (chunk->auth_chunk) {
728 struct sctp_chunk auth;
729 sctp_ierror_t ret;
730
731 /* set-up our fake chunk so that we can process it */
732 auth.skb = chunk->auth_chunk;
733 auth.asoc = chunk->asoc;
734 auth.sctp_hdr = chunk->sctp_hdr;
735 auth.chunk_hdr = (sctp_chunkhdr_t *)skb_push(chunk->auth_chunk,
736 sizeof(sctp_chunkhdr_t));
737 skb_pull(chunk->auth_chunk, sizeof(sctp_chunkhdr_t));
738 auth.transport = chunk->transport;
739
740 ret = sctp_sf_authenticate(ep, new_asoc, type, &auth);
741
742 /* We can now safely free the auth_chunk clone */
743 kfree_skb(chunk->auth_chunk);
744
745 if (ret != SCTP_IERROR_NO_ERROR) {
746 sctp_association_free(new_asoc);
747 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
748 }
749 }
750
702 repl = sctp_make_cookie_ack(new_asoc, chunk); 751 repl = sctp_make_cookie_ack(new_asoc, chunk);
703 if (!repl) 752 if (!repl)
704 goto nomem_init; 753 goto nomem_init;
@@ -3653,6 +3702,156 @@ gen_shutdown:
3653} 3702}
3654 3703
3655/* 3704/*
3705 * SCTP-AUTH Section 6.3 Receving authenticated chukns
3706 *
3707 * The receiver MUST use the HMAC algorithm indicated in the HMAC
3708 * Identifier field. If this algorithm was not specified by the
3709 * receiver in the HMAC-ALGO parameter in the INIT or INIT-ACK chunk
3710 * during association setup, the AUTH chunk and all chunks after it MUST
3711 * be discarded and an ERROR chunk SHOULD be sent with the error cause
3712 * defined in Section 4.1.
3713 *
3714 * If an endpoint with no shared key receives a Shared Key Identifier
3715 * other than 0, it MUST silently discard all authenticated chunks. If
3716 * the endpoint has at least one endpoint pair shared key for the peer,
3717 * it MUST use the key specified by the Shared Key Identifier if a
3718 * key has been configured for that Shared Key Identifier. If no
3719 * endpoint pair shared key has been configured for that Shared Key
3720 * Identifier, all authenticated chunks MUST be silently discarded.
3721 *
3722 * Verification Tag: 8.5 Verification Tag [Normal verification]
3723 *
3724 * The return value is the disposition of the chunk.
3725 */
3726static sctp_ierror_t sctp_sf_authenticate(const struct sctp_endpoint *ep,
3727 const struct sctp_association *asoc,
3728 const sctp_subtype_t type,
3729 struct sctp_chunk *chunk)
3730{
3731 struct sctp_authhdr *auth_hdr;
3732 struct sctp_hmac *hmac;
3733 unsigned int sig_len;
3734 __u16 key_id;
3735 __u8 *save_digest;
3736 __u8 *digest;
3737
3738 /* Pull in the auth header, so we can do some more verification */
3739 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
3740 chunk->subh.auth_hdr = auth_hdr;
3741 skb_pull(chunk->skb, sizeof(struct sctp_authhdr));
3742
3743 /* Make sure that we suport the HMAC algorithm from the auth
3744 * chunk.
3745 */
3746 if (!sctp_auth_asoc_verify_hmac_id(asoc, auth_hdr->hmac_id))
3747 return SCTP_IERROR_AUTH_BAD_HMAC;
3748
3749 /* Make sure that the provided shared key identifier has been
3750 * configured
3751 */
3752 key_id = ntohs(auth_hdr->shkey_id);
3753 if (key_id != asoc->active_key_id && !sctp_auth_get_shkey(asoc, key_id))
3754 return SCTP_IERROR_AUTH_BAD_KEYID;
3755
3756
3757 /* Make sure that the length of the signature matches what
3758 * we expect.
3759 */
3760 sig_len = ntohs(chunk->chunk_hdr->length) - sizeof(sctp_auth_chunk_t);
3761 hmac = sctp_auth_get_hmac(ntohs(auth_hdr->hmac_id));
3762 if (sig_len != hmac->hmac_len)
3763 return SCTP_IERROR_PROTO_VIOLATION;
3764
3765 /* Now that we've done validation checks, we can compute and
3766 * verify the hmac. The steps involved are:
3767 * 1. Save the digest from the chunk.
3768 * 2. Zero out the digest in the chunk.
3769 * 3. Compute the new digest
3770 * 4. Compare saved and new digests.
3771 */
3772 digest = auth_hdr->hmac;
3773 skb_pull(chunk->skb, sig_len);
3774
3775 save_digest = kmemdup(digest, sig_len, GFP_ATOMIC);
3776 if (!save_digest)
3777 goto nomem;
3778
3779 memset(digest, 0, sig_len);
3780
3781 sctp_auth_calculate_hmac(asoc, chunk->skb,
3782 (struct sctp_auth_chunk *)chunk->chunk_hdr,
3783 GFP_ATOMIC);
3784
3785 /* Discard the packet if the digests do not match */
3786 if (memcmp(save_digest, digest, sig_len)) {
3787 kfree(save_digest);
3788 return SCTP_IERROR_BAD_SIG;
3789 }
3790
3791 kfree(save_digest);
3792 chunk->auth = 1;
3793
3794 return SCTP_IERROR_NO_ERROR;
3795nomem:
3796 return SCTP_IERROR_NOMEM;
3797}
3798
3799sctp_disposition_t sctp_sf_eat_auth(const struct sctp_endpoint *ep,
3800 const struct sctp_association *asoc,
3801 const sctp_subtype_t type,
3802 void *arg,
3803 sctp_cmd_seq_t *commands)
3804{
3805 struct sctp_authhdr *auth_hdr;
3806 struct sctp_chunk *chunk = arg;
3807 struct sctp_chunk *err_chunk;
3808 sctp_ierror_t error;
3809
3810 if (!sctp_vtag_verify(chunk, asoc)) {
3811 sctp_add_cmd_sf(commands, SCTP_CMD_REPORT_BAD_TAG,
3812 SCTP_NULL());
3813 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3814 }
3815
3816 /* Make sure that the AUTH chunk has valid length. */
3817 if (!sctp_chunk_length_valid(chunk, sizeof(struct sctp_auth_chunk)))
3818 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3819 commands);
3820
3821 auth_hdr = (struct sctp_authhdr *)chunk->skb->data;
3822 error = sctp_sf_authenticate(ep, asoc, type, chunk);
3823 switch (error) {
3824 case SCTP_IERROR_AUTH_BAD_HMAC:
3825 /* Generate the ERROR chunk and discard the rest
3826 * of the packet
3827 */
3828 err_chunk = sctp_make_op_error(asoc, chunk,
3829 SCTP_ERROR_UNSUP_HMAC,
3830 &auth_hdr->hmac_id,
3831 sizeof(__u16));
3832 if (err_chunk) {
3833 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
3834 SCTP_CHUNK(err_chunk));
3835 }
3836 /* Fall Through */
3837 case SCTP_IERROR_AUTH_BAD_KEYID:
3838 case SCTP_IERROR_BAD_SIG:
3839 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
3840 break;
3841 case SCTP_IERROR_PROTO_VIOLATION:
3842 return sctp_sf_violation_chunklen(ep, asoc, type, arg,
3843 commands);
3844 break;
3845 case SCTP_IERROR_NOMEM:
3846 return SCTP_DISPOSITION_NOMEM;
3847 default:
3848 break;
3849 }
3850
3851 return SCTP_DISPOSITION_CONSUME;
3852}
3853
3854/*
3656 * Process an unknown chunk. 3855 * Process an unknown chunk.
3657 * 3856 *
3658 * Section: 3.2. Also, 2.1 in the implementor's guide. 3857 * Section: 3.2. Also, 2.1 in the implementor's guide.
@@ -3857,6 +4056,20 @@ static sctp_disposition_t sctp_sf_abort_violation(
3857 if (!abort) 4056 if (!abort)
3858 goto nomem; 4057 goto nomem;
3859 4058
4059 /* SCTP-AUTH, Section 6.3:
4060 * It should be noted that if the receiver wants to tear
4061 * down an association in an authenticated way only, the
4062 * handling of malformed packets should not result in
4063 * tearing down the association.
4064 *
4065 * This means that if we only want to abort associations
4066 * in an authenticated way (i.e AUTH+ABORT), then we
4067 * can't destory this association just becuase the packet
4068 * was malformed.
4069 */
4070 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
4071 goto discard;
4072
3860 if (asoc) { 4073 if (asoc) {
3861 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); 4074 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
3862 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4075 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
@@ -3894,6 +4107,7 @@ static sctp_disposition_t sctp_sf_abort_violation(
3894 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4107 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
3895 } 4108 }
3896 4109
4110discard:
3897 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands); 4111 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
3898 4112
3899 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4113 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index ddb0ba3974b0..a93a4bc8f68f 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -523,6 +523,34 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN
523 TYPE_SCTP_FWD_TSN, 523 TYPE_SCTP_FWD_TSN,
524}; /*state_fn_t prsctp_chunk_event_table[][] */ 524}; /*state_fn_t prsctp_chunk_event_table[][] */
525 525
526#define TYPE_SCTP_AUTH { \
527 /* SCTP_STATE_EMPTY */ \
528 TYPE_SCTP_FUNC(sctp_sf_ootb), \
529 /* SCTP_STATE_CLOSED */ \
530 TYPE_SCTP_FUNC(sctp_sf_ootb), \
531 /* SCTP_STATE_COOKIE_WAIT */ \
532 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
533 /* SCTP_STATE_COOKIE_ECHOED */ \
534 TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
535 /* SCTP_STATE_ESTABLISHED */ \
536 TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
537 /* SCTP_STATE_SHUTDOWN_PENDING */ \
538 TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
539 /* SCTP_STATE_SHUTDOWN_SENT */ \
540 TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
541 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
542 TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
543 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
544 TYPE_SCTP_FUNC(sctp_sf_eat_auth), \
545} /* TYPE_SCTP_AUTH */
546
547/* The primary index for this table is the chunk type.
548 * The secondary index for this table is the state.
549 */
550static const sctp_sm_table_entry_t auth_chunk_event_table[SCTP_NUM_AUTH_CHUNK_TYPES][SCTP_STATE_NUM_STATES] = {
551 TYPE_SCTP_AUTH,
552}; /*state_fn_t auth_chunk_event_table[][] */
553
526static const sctp_sm_table_entry_t 554static const sctp_sm_table_entry_t
527chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { 555chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
528 /* SCTP_STATE_EMPTY */ 556 /* SCTP_STATE_EMPTY */
@@ -976,5 +1004,10 @@ static const sctp_sm_table_entry_t *sctp_chunk_event_lookup(sctp_cid_t cid,
976 return &addip_chunk_event_table[1][state]; 1004 return &addip_chunk_event_table[1][state];
977 } 1005 }
978 1006
1007 if (sctp_auth_enable) {
1008 if (cid == SCTP_CID_AUTH)
1009 return &auth_chunk_event_table[0][state];
1010 }
1011
979 return &chunk_event_table_unknown[state]; 1012 return &chunk_event_table_unknown[state];
980} 1013}