@@ -171,7 +171,7 @@ sctp_disposition_t sctp_sf_do_4_C(const struct sctp_endpoint *ep,
171
171
* Verification Tag field to Tag_A, and also provide its own
172
172
* Verification Tag (Tag_Z) in the Initiate Tag field.
173
173
*
174
- * Verification Tag: No checking.
174
+ * Verification Tag: Must be 0.
175
175
*
176
176
* Inputs
177
177
* (endpoint, asoc, chunk)
@@ -219,6 +219,12 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
219
219
(sk -> sk_ack_backlog >= sk -> sk_max_ack_backlog )))
220
220
return sctp_sf_tabort_8_4_8 (ep , asoc , type , arg , commands );
221
221
222
+ /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
223
+ * Tag.
224
+ */
225
+ if (chunk -> sctp_hdr -> vtag != 0 )
226
+ return sctp_sf_tabort_8_4_8 (ep , asoc , type , arg , commands );
227
+
222
228
/* Verify the INIT chunk before processing it. */
223
229
err_chunk = NULL ;
224
230
if (!sctp_verify_init (asoc , chunk -> chunk_hdr -> type ,
@@ -377,6 +383,9 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
377
383
if (!chunk -> singleton )
378
384
return SCTP_DISPOSITION_VIOLATION ;
379
385
386
+ if (!sctp_vtag_verify (chunk , asoc ))
387
+ return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
388
+
380
389
/* Grab the INIT header. */
381
390
chunk -> subh .init_hdr = (sctp_inithdr_t * ) chunk -> skb -> data ;
382
391
@@ -659,8 +668,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
659
668
const sctp_subtype_t type , void * arg ,
660
669
sctp_cmd_seq_t * commands )
661
670
{
671
+ struct sctp_chunk * chunk = arg ;
662
672
struct sctp_ulpevent * ev ;
663
673
674
+ if (!sctp_vtag_verify (chunk , asoc ))
675
+ return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
676
+
664
677
/* RFC 2960 5.1 Normal Establishment of an Association
665
678
*
666
679
* E) Upon reception of the COOKIE ACK, endpoint "A" will move
@@ -807,13 +820,7 @@ sctp_disposition_t sctp_sf_beat_8_3(const struct sctp_endpoint *ep,
807
820
struct sctp_chunk * reply ;
808
821
size_t paylen = 0 ;
809
822
810
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
811
- * that the value in the Verification Tag field of the
812
- * received SCTP packet matches its own Tag. If the received
813
- * Verification Tag value does not match the receiver's own
814
- * tag value, the receiver shall silently discard the packet...
815
- */
816
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
823
+ if (!sctp_vtag_verify (chunk , asoc ))
817
824
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
818
825
819
826
/* 8.3 The receiver of the HEARTBEAT should immediately
@@ -876,11 +883,7 @@ sctp_disposition_t sctp_sf_backbeat_8_3(const struct sctp_endpoint *ep,
876
883
sctp_sender_hb_info_t * hbinfo ;
877
884
unsigned long max_interval ;
878
885
879
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
880
- * that the value in the Verification Tag field of the
881
- * received SCTP packet matches its own Tag. ...
882
- */
883
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
886
+ if (!sctp_vtag_verify (chunk , asoc ))
884
887
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
885
888
886
889
hbinfo = (sctp_sender_hb_info_t * ) chunk -> skb -> data ;
@@ -1130,6 +1133,12 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1130
1133
if (!chunk -> singleton )
1131
1134
return SCTP_DISPOSITION_VIOLATION ;
1132
1135
1136
+ /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
1137
+ * Tag.
1138
+ */
1139
+ if (chunk -> sctp_hdr -> vtag != 0 )
1140
+ return sctp_sf_tabort_8_4_8 (ep , asoc , type , arg , commands );
1141
+
1133
1142
/* Grab the INIT header. */
1134
1143
chunk -> subh .init_hdr = (sctp_inithdr_t * ) chunk -> skb -> data ;
1135
1144
@@ -1386,6 +1395,8 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1386
1395
sctp_init_chunk_t * peer_init ;
1387
1396
struct sctp_ulpevent * ev ;
1388
1397
struct sctp_chunk * repl ;
1398
+ struct sctp_chunk * err ;
1399
+ sctp_disposition_t disposition ;
1389
1400
1390
1401
/* new_asoc is a brand-new association, so these are not yet
1391
1402
* side effects--it is safe to run them here.
@@ -1405,6 +1416,29 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1405
1416
return SCTP_DISPOSITION_CONSUME ;
1406
1417
}
1407
1418
1419
+ /* If the endpoint is in the SHUTDOWN-ACK-SENT state and recognizes
1420
+ * the peer has restarted (Action A), it MUST NOT setup a new
1421
+ * association but instead resend the SHUTDOWN ACK and send an ERROR
1422
+ * chunk with a "Cookie Received while Shutting Down" error cause to
1423
+ * its peer.
1424
+ */
1425
+ if (sctp_state (asoc , SHUTDOWN_ACK_SENT )) {
1426
+ disposition = sctp_sf_do_9_2_reshutack (ep , asoc ,
1427
+ SCTP_ST_CHUNK (chunk -> chunk_hdr -> type ),
1428
+ chunk , commands );
1429
+ if (SCTP_DISPOSITION_NOMEM == disposition )
1430
+ goto nomem ;
1431
+
1432
+ err = sctp_make_op_error (asoc , chunk ,
1433
+ SCTP_ERROR_COOKIE_IN_SHUTDOWN ,
1434
+ NULL , 0 );
1435
+ if (err )
1436
+ sctp_add_cmd_sf (commands , SCTP_CMD_REPLY ,
1437
+ SCTP_CHUNK (err ));
1438
+
1439
+ return SCTP_DISPOSITION_CONSUME ;
1440
+ }
1441
+
1408
1442
/* For now, fail any unsent/unacked data. Consider the optional
1409
1443
* choice of resending of this data.
1410
1444
*/
@@ -1883,6 +1917,9 @@ sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
1883
1917
1884
1918
sctp_addto_chunk (reply , sizeof (bht ), & bht );
1885
1919
1920
+ /* Clear peer's init_tag cached in assoc as we are sending a new INIT */
1921
+ sctp_add_cmd_sf (commands , SCTP_CMD_CLEAR_INIT_TAG , SCTP_NULL ());
1922
+
1886
1923
/* Cast away the const modifier, as we want to just
1887
1924
* rerun it through as a sideffect.
1888
1925
*/
@@ -2071,13 +2108,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
2071
2108
skb_pull (chunk -> skb , sizeof (sctp_shutdownhdr_t ));
2072
2109
chunk -> subh .shutdown_hdr = sdh ;
2073
2110
2074
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
2075
- * that the value in the Verification Tag field of the
2076
- * received SCTP packet matches its own Tag. If the received
2077
- * Verification Tag value does not match the receiver's own
2078
- * tag value, the receiver shall silently discard the packet...
2079
- */
2080
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
2111
+ if (!sctp_vtag_verify (chunk , asoc ))
2081
2112
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
2082
2113
2083
2114
/* Upon the reception of the SHUTDOWN, the peer endpoint shall
@@ -2190,13 +2221,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
2190
2221
sctp_cwrhdr_t * cwr ;
2191
2222
struct sctp_chunk * chunk = arg ;
2192
2223
2193
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
2194
- * that the value in the Verification Tag field of the
2195
- * received SCTP packet matches its own Tag. If the received
2196
- * Verification Tag value does not match the receiver's own
2197
- * tag value, the receiver shall silently discard the packet...
2198
- */
2199
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
2224
+ if (!sctp_vtag_verify (chunk , asoc ))
2200
2225
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
2201
2226
2202
2227
cwr = (sctp_cwrhdr_t * ) chunk -> skb -> data ;
@@ -2246,13 +2271,7 @@ sctp_disposition_t sctp_sf_do_ecne(const struct sctp_endpoint *ep,
2246
2271
sctp_ecnehdr_t * ecne ;
2247
2272
struct sctp_chunk * chunk = arg ;
2248
2273
2249
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
2250
- * that the value in the Verification Tag field of the
2251
- * received SCTP packet matches its own Tag. If the received
2252
- * Verification Tag value does not match the receiver's own
2253
- * tag value, the receiver shall silently discard the packet...
2254
- */
2255
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
2274
+ if (!sctp_vtag_verify (chunk , asoc ))
2256
2275
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
2257
2276
2258
2277
ecne = (sctp_ecnehdr_t * ) chunk -> skb -> data ;
@@ -2309,13 +2328,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const struct sctp_endpoint *ep,
2309
2328
int tmp ;
2310
2329
__u32 tsn ;
2311
2330
2312
- /* RFC 2960 8.5 Verification Tag
2313
- *
2314
- * When receiving an SCTP packet, the endpoint MUST ensure
2315
- * that the value in the Verification Tag field of the
2316
- * received SCTP packet matches its own Tag.
2317
- */
2318
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag ) {
2331
+ if (!sctp_vtag_verify (chunk , asoc )) {
2319
2332
sctp_add_cmd_sf (commands , SCTP_CMD_REPORT_BAD_TAG ,
2320
2333
SCTP_NULL ());
2321
2334
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
@@ -2569,13 +2582,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(const struct sctp_endpoint *ep,
2569
2582
int tmp ;
2570
2583
__u32 tsn ;
2571
2584
2572
- /* RFC 2960 8.5 Verification Tag
2573
- *
2574
- * When receiving an SCTP packet, the endpoint MUST ensure
2575
- * that the value in the Verification Tag field of the
2576
- * received SCTP packet matches its own Tag.
2577
- */
2578
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag ) {
2585
+ if (!sctp_vtag_verify (chunk , asoc )) {
2579
2586
sctp_add_cmd_sf (commands , SCTP_CMD_REPORT_BAD_TAG ,
2580
2587
SCTP_NULL ());
2581
2588
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
@@ -2745,11 +2752,7 @@ sctp_disposition_t sctp_sf_eat_sack_6_2(const struct sctp_endpoint *ep,
2745
2752
sctp_sackhdr_t * sackh ;
2746
2753
__u32 ctsn ;
2747
2754
2748
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
2749
- * that the value in the Verification Tag field of the
2750
- * received SCTP packet matches its own Tag. ...
2751
- */
2752
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
2755
+ if (!sctp_vtag_verify (chunk , asoc ))
2753
2756
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
2754
2757
2755
2758
/* Pull the SACK chunk from the data buffer */
@@ -2895,6 +2898,9 @@ sctp_disposition_t sctp_sf_do_9_2_final(const struct sctp_endpoint *ep,
2895
2898
struct sctp_chunk * reply ;
2896
2899
struct sctp_ulpevent * ev ;
2897
2900
2901
+ if (!sctp_vtag_verify (chunk , asoc ))
2902
+ return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
2903
+
2898
2904
/* 10.2 H) SHUTDOWN COMPLETE notification
2899
2905
*
2900
2906
* When SCTP completes the shutdown procedures (section 9.2) this
@@ -3229,13 +3235,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn(const struct sctp_endpoint *ep,
3229
3235
__u16 len ;
3230
3236
__u32 tsn ;
3231
3237
3232
- /* RFC 2960 8.5 Verification Tag
3233
- *
3234
- * When receiving an SCTP packet, the endpoint MUST ensure
3235
- * that the value in the Verification Tag field of the
3236
- * received SCTP packet matches its own Tag.
3237
- */
3238
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag ) {
3238
+ if (!sctp_vtag_verify (chunk , asoc )) {
3239
3239
sctp_add_cmd_sf (commands , SCTP_CMD_REPORT_BAD_TAG ,
3240
3240
SCTP_NULL ());
3241
3241
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
@@ -3293,13 +3293,7 @@ sctp_disposition_t sctp_sf_eat_fwd_tsn_fast(
3293
3293
__u16 len ;
3294
3294
__u32 tsn ;
3295
3295
3296
- /* RFC 2960 8.5 Verification Tag
3297
- *
3298
- * When receiving an SCTP packet, the endpoint MUST ensure
3299
- * that the value in the Verification Tag field of the
3300
- * received SCTP packet matches its own Tag.
3301
- */
3302
- if (ntohl (chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag ) {
3296
+ if (!sctp_vtag_verify (chunk , asoc )) {
3303
3297
sctp_add_cmd_sf (commands , SCTP_CMD_REPORT_BAD_TAG ,
3304
3298
SCTP_NULL ());
3305
3299
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
@@ -3376,13 +3370,7 @@ sctp_disposition_t sctp_sf_unk_chunk(const struct sctp_endpoint *ep,
3376
3370
3377
3371
SCTP_DEBUG_PRINTK ("Processing the unknown chunk id %d.\n" , type .chunk );
3378
3372
3379
- /* 8.5 When receiving an SCTP packet, the endpoint MUST ensure
3380
- * that the value in the Verification Tag field of the
3381
- * received SCTP packet matches its own Tag. If the received
3382
- * Verification Tag value does not match the receiver's own
3383
- * tag value, the receiver shall silently discard the packet.
3384
- */
3385
- if (ntohl (unk_chunk -> sctp_hdr -> vtag ) != asoc -> c .my_vtag )
3373
+ if (!sctp_vtag_verify (unk_chunk , asoc ))
3386
3374
return sctp_sf_pdiscard (ep , asoc , type , arg , commands );
3387
3375
3388
3376
switch (type .chunk & SCTP_CID_ACTION_MASK ) {
0 commit comments