Commit 0ab86310 authored by Sridhar Samudrala's avatar Sridhar Samudrala

sctp: VTAG checks for ABORT & SHUTDOWN_COMPLETE chunks (ardelle.fan)

parent d7b59481
...@@ -432,4 +432,36 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a ...@@ -432,4 +432,36 @@ static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_a
BUG(); BUG();
} }
/* Check VTAG of the packet matches the sender's own tag OR its peer's
* tag and the T bit is set in the Chunk Flags.
*/
static inline int
sctp_vtag_verify_either(const sctp_chunk_t *chunk,
const sctp_association_t *asoc)
{
/* RFC 2960 Section 8.5.1, sctpimpguide-06 Section 2.13.2
*
* B) The receiver of a ABORT shall accept the packet if the
* Verification Tag field of the packet matches its own tag OR it
* is set to its peer's tag and the T bit is set in the Chunk
* Flags. Otherwise, the receiver MUST silently discard the packet
* and take no further action.
*
* (C) The receiver of a SHUTDOWN COMPLETE shall accept the
* packet if the Verification Tag field of the packet
* matches its own tag OR it is set to its peer's tag and
* the T bit is set in the Chunk Flags. Otherwise, the
* receiver MUST silently discard the packet and take no
* further action....
*
*/
if ((ntohl(chunk->sctp_hdr->vtag) == asoc->c.my_vtag) ||
(sctp_test_T_bit(chunk) && (ntohl(chunk->sctp_hdr->vtag)
== asoc->c.peer_vtag))) {
return 1;
}
return 0;
}
#endif /* __sctp_sm_h__ */ #endif /* __sctp_sm_h__ */
...@@ -110,18 +110,7 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep, ...@@ -110,18 +110,7 @@ sctp_disposition_t sctp_sf_do_4_C(const sctp_endpoint_t *ep,
if (!chunk->singleton) if (!chunk->singleton)
return SCTP_DISPOSITION_VIOLATION; return SCTP_DISPOSITION_VIOLATION;
/* RFC 2960 8.5.1 Exceptions in Verification Tag Rules if (!sctp_vtag_verify_either(chunk, asoc))
*
* (C) The receiver of a SHUTDOWN COMPLETE shall accept the
* packet if the Verification Tag field of the packet
* matches its own tag OR it is set to its peer's tag and
* the T bit is set in the Chunk Flags. Otherwise, the
* receiver MUST silently discard the packet and take no
* further action....
*/
if ((ntohl(chunk->sctp_hdr->vtag) != asoc->c.my_vtag) &&
!(sctp_test_T_bit(chunk) ||
(ntohl(chunk->sctp_hdr->vtag) != asoc->peer.i.init_tag)))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands); return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* RFC 2960 10.2 SCTP-to-ULP /* RFC 2960 10.2 SCTP-to-ULP
...@@ -1636,6 +1625,10 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(const sctp_endpoint_t *ep, ...@@ -1636,6 +1625,10 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
sctp_chunk_t *chunk = arg;
if (!sctp_vtag_verify_either(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Stop the T5-shutdown guard timer. */ /* Stop the T5-shutdown guard timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
...@@ -1655,6 +1648,10 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const sctp_endpoint_t *ep, ...@@ -1655,6 +1648,10 @@ sctp_disposition_t sctp_sf_shutdown_sent_abort(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
sctp_chunk_t *chunk = arg;
if (!sctp_vtag_verify_either(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* Stop the T2-shutdown timer. */ /* Stop the T2-shutdown timer. */
sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
...@@ -1826,6 +1823,11 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const sctp_endpoint_t *ep, ...@@ -1826,6 +1823,11 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
sctp_chunk_t *chunk = arg;
if (!sctp_vtag_verify_either(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
/* ASSOC_FAILED will DELETE_TCB. */ /* ASSOC_FAILED will DELETE_TCB. */
sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL()); sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_NULL());
...@@ -1844,8 +1846,10 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const sctp_endpoint_t *ep, ...@@ -1844,8 +1846,10 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const sctp_endpoint_t *ep,
void *arg, void *arg,
sctp_cmd_seq_t *commands) sctp_cmd_seq_t *commands)
{ {
/* Check the verification tag. */ sctp_chunk_t *chunk = arg;
/* BUG: WRITE ME. */
if (!sctp_vtag_verify_either(chunk, asoc))
return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
SCTP_STATE(SCTP_STATE_CLOSED)); SCTP_STATE(SCTP_STATE_CLOSED));
...@@ -4218,7 +4222,7 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc, ...@@ -4218,7 +4222,7 @@ sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
/* Special case the INIT as there is no vtag yet. */ /* Special case the INIT as there is no vtag yet. */
if (SCTP_CID_INIT == chunk->chunk_hdr->type) { if (SCTP_CID_INIT == chunk->chunk_hdr->type) {
sctp_init_chunk_t *init; sctp_init_chunk_t *init;
init = (sctp_init_chunk_t *)&chunk->chunk_hdr; init = (sctp_init_chunk_t *)chunk->chunk_hdr;
vtag = ntohl(init->init_hdr.init_tag); vtag = ntohl(init->init_hdr.init_tag);
} else { } else {
vtag = ntohl(chunk->sctp_hdr->vtag); vtag = ntohl(chunk->sctp_hdr->vtag);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment