sctp: fix to check the source address of COOKIE-ECHO
Subsystems (2)
PATCH v2 1/3 sctp: fix to check the source address of COOKIE-ECHO
SCTP does not check whether the source address of COOKIE-ECHO chunk is the original address of INIT chunk or part of the any address parameters saved in COOKIE in CLOSED state. So even if the COOKIE-ECHO chunk is from any address but with correct COOKIE, the COOKIE-ECHO chunk still be accepted. If the COOKIE is not from a valid address, the assoc should not be established.
Signed-off-by Wei Yongjun <[email protected]>
---
v1 -> v2
- change as vlad's advise
--- include/net/sctp/structs.h | 2 +- net/sctp/sm_make_chunk.c | 26 +++++++++++++++++++++----- net/sctp/sm_sideeffect.c | 3 +-- net/sctp/sm_statefuns.c | 14 +++++--------- 4 files changed, 28 insertions(+), 17 deletions(-)
include/net/sctp/structs.h +1 -1
@@ -1403,7 +1403,7 @@ int sctp_has_association(const union sctp_addr *laddr,int sctp_verify_init (const struct sctp_association *asoc,sctp_cid_t ,sctp_init_chunk_t *peer_init,struct sctp_chunk *chunk,struct sctp_chunk **err_chunk); -int sctp_process_init (struct sctp_association *,sctp_cid_t cid, +int sctp_process_init (struct sctp_association *,struct sctp_chunk *chunk,const union sctp_addr *peer,sctp_init_chunk_t *init,gfp_t gfp);__u32 sctp_generate_tag (const struct sctp_endpoint *);
net/sctp/sm_make_chunk.c +21 -5
@@ -2240,14 +2240,17 @@ int sctp_verify_init(const struct sctp_association *asoc,* Returns 0 on failure, else success. * FIXME: This is an association method. */ -int sctp_process_init (struct sctp_association *asoc,sctp_cid_t cid, +int sctp_process_init (struct sctp_association *asoc,struct sctp_chunk *chunk,const union sctp_addr *peer_addr,sctp_init_chunk_t *peer_init,gfp_t gfp) {union sctp_params param;struct sctp_transport *transport;struct list_head *pos, *temp; +struct sctp_af *af; +union sctp_addr addr;char *cookie; +int src_match =0 ;/* We must include the address that the INIT packet came from. * This is the only address that matters for an INIT packet.
@@ -2259,18 +2262,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,* added as the primary transport. The source address seems to * be a a better choice than any of the embedded addresses. */ -if (peer_addr) { -if (!sctp_assoc_add_peer (asoc, peer_addr, gfp,SCTP_ACTIVE )) - goto nomem; - } +if (!sctp_assoc_add_peer (asoc, peer_addr, gfp,SCTP_ACTIVE )) + goto nomem; + +if (sctp_cmp_addr_exact (sctp_source (chunk), peer_addr)) + src_match =1 ;/* Process the initialization parameters. */ sctp_walk_params(param, peer_init, init_hdr.params) { +if (!src_match && (param.p->type =SCTP_PARAM_IPV4_ADDRESS || + param.p->type =SCTP_PARAM_IPV6_ADDRESS )) { + af =sctp_get_af_specific (param_type2af (param.p->type)); + af->from_addr_param (&addr, param.addr, + chunk->sctp_hdr->source,0 ); +if (sctp_cmp_addr_exact (sctp_source (chunk), &addr)) + src_match =1 ; + }if (!sctp_process_param (asoc, param, peer_addr, gfp)) goto clean_up; } +/* source address of chunk may not match any valid address */ +if (!src_match) + goto clean_up; +/* AUTH: After processing the parameters, make sure that we * have all the required info to potentially do authentications. */
net/sctp/sm_sideeffect.c +1 -2
@@ -593,8 +593,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,* fail during INIT processing (due to malloc problems), * just return the error and stop processing the stack. */ -if (!sctp_process_init (asoc, chunk->chunk_hdr->type, -sctp_source (chunk), peer_init, gfp)) +if (!sctp_process_init (asoc, chunk,sctp_source (chunk), peer_init, gfp)) error = -ENOMEM ;else error =0 ;
net/sctp/sm_statefuns.c +5 -9
@@ -391,8 +391,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep, goto nomem_init;/* The call, sctp_process_init(), can fail on memory allocation. */ -if (!sctp_process_init (new_asoc, chunk->chunk_hdr->type, -sctp_source (chunk), +if (!sctp_process_init (new_asoc, chunk,sctp_source (chunk), (sctp_init_chunk_t *)chunk->chunk_hdr,GFP_ATOMIC )) goto nomem_init;
@@ -723,7 +722,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,*/ peer_init = &chunk->subh.cookie_hdr->c.peer_init[0 ]; -if (!sctp_process_init (new_asoc, chunk->chunk_hdr->type, +if (!sctp_process_init (new_asoc, chunk, &chunk->subh.cookie_hdr->c.peer_addr, peer_init,GFP_ATOMIC )) goto nomem_init;
@@ -1464,8 +1463,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(* Verification Tag and Peers Verification tag into a reserved * place (local tie-tag and per tie-tag) within the state cookie. */ -if (!sctp_process_init (new_asoc, chunk->chunk_hdr->type, -sctp_source (chunk), +if (!sctp_process_init (new_asoc, chunk,sctp_source (chunk), (sctp_init_chunk_t *)chunk->chunk_hdr,GFP_ATOMIC )) goto nomem;
@@ -1694,8 +1692,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,*/ peer_init = &chunk->subh.cookie_hdr->c.peer_init[0 ]; -if (!sctp_process_init (new_asoc, chunk->chunk_hdr->type, -sctp_source (chunk), peer_init, +if (!sctp_process_init (new_asoc, chunk,sctp_source (chunk), peer_init,GFP_ATOMIC )) goto nomem;
@@ -1780,8 +1777,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,* side effects--it is safe to run them here. */ peer_init = &chunk->subh.cookie_hdr->c.peer_init[0 ]; -if (!sctp_process_init (new_asoc, chunk->chunk_hdr->type, -sctp_source (chunk), peer_init, +if (!sctp_process_init (new_asoc, chunk,sctp_source (chunk), peer_init,GFP_ATOMIC )) goto nomem;
Signature · 1 line
1.6.5.2