aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2011-04-19 17:30:51 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-20 04:51:05 -0400
commitde6becdc0844ff92b38ffd9f0c4db1d3de02835f (patch)
treef52df91a347ece7e4efc09ca2974e8e38f38a3f8 /net/sctp
parent85c5ed4e44a262344ce43b4bf23204107923ca95 (diff)
sctp: fix to check the source address of COOKIE-ECHO chunk
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 <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/sm_make_chunk.c26
-rw-r--r--net/sctp/sm_sideeffect.c3
-rw-r--r--net/sctp/sm_statefuns.c14
3 files changed, 27 insertions, 16 deletions
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index f87ccb11a520..a7b65e9e44b3 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -2242,14 +2242,17 @@ int sctp_verify_init(const struct sctp_association *asoc,
2242 * Returns 0 on failure, else success. 2242 * Returns 0 on failure, else success.
2243 * FIXME: This is an association method. 2243 * FIXME: This is an association method.
2244 */ 2244 */
2245int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid, 2245int sctp_process_init(struct sctp_association *asoc, struct sctp_chunk *chunk,
2246 const union sctp_addr *peer_addr, 2246 const union sctp_addr *peer_addr,
2247 sctp_init_chunk_t *peer_init, gfp_t gfp) 2247 sctp_init_chunk_t *peer_init, gfp_t gfp)
2248{ 2248{
2249 union sctp_params param; 2249 union sctp_params param;
2250 struct sctp_transport *transport; 2250 struct sctp_transport *transport;
2251 struct list_head *pos, *temp; 2251 struct list_head *pos, *temp;
2252 struct sctp_af *af;
2253 union sctp_addr addr;
2252 char *cookie; 2254 char *cookie;
2255 int src_match = 0;
2253 2256
2254 /* We must include the address that the INIT packet came from. 2257 /* We must include the address that the INIT packet came from.
2255 * This is the only address that matters for an INIT packet. 2258 * This is the only address that matters for an INIT packet.
@@ -2261,18 +2264,31 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
2261 * added as the primary transport. The source address seems to 2264 * added as the primary transport. The source address seems to
2262 * be a a better choice than any of the embedded addresses. 2265 * be a a better choice than any of the embedded addresses.
2263 */ 2266 */
2264 if (peer_addr) { 2267 if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
2265 if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) 2268 goto nomem;
2266 goto nomem; 2269
2267 } 2270 if (sctp_cmp_addr_exact(sctp_source(chunk), peer_addr))
2271 src_match = 1;
2268 2272
2269 /* Process the initialization parameters. */ 2273 /* Process the initialization parameters. */
2270 sctp_walk_params(param, peer_init, init_hdr.params) { 2274 sctp_walk_params(param, peer_init, init_hdr.params) {
2275 if (!src_match && (param.p->type == SCTP_PARAM_IPV4_ADDRESS ||
2276 param.p->type == SCTP_PARAM_IPV6_ADDRESS)) {
2277 af = sctp_get_af_specific(param_type2af(param.p->type));
2278 af->from_addr_param(&addr, param.addr,
2279 chunk->sctp_hdr->source, 0);
2280 if (sctp_cmp_addr_exact(sctp_source(chunk), &addr))
2281 src_match = 1;
2282 }
2271 2283
2272 if (!sctp_process_param(asoc, param, peer_addr, gfp)) 2284 if (!sctp_process_param(asoc, param, peer_addr, gfp))
2273 goto clean_up; 2285 goto clean_up;
2274 } 2286 }
2275 2287
2288 /* source address of chunk may not match any valid address */
2289 if (!src_match)
2290 goto clean_up;
2291
2276 /* AUTH: After processing the parameters, make sure that we 2292 /* AUTH: After processing the parameters, make sure that we
2277 * have all the required info to potentially do authentications. 2293 * have all the required info to potentially do authentications.
2278 */ 2294 */
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 3b80fe24dabf..d612ca1ca6c0 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -595,8 +595,7 @@ static int sctp_cmd_process_init(sctp_cmd_seq_t *commands,
595 * fail during INIT processing (due to malloc problems), 595 * fail during INIT processing (due to malloc problems),
596 * just return the error and stop processing the stack. 596 * just return the error and stop processing the stack.
597 */ 597 */
598 if (!sctp_process_init(asoc, chunk->chunk_hdr->type, 598 if (!sctp_process_init(asoc, chunk, sctp_source(chunk), peer_init, gfp))
599 sctp_source(chunk), peer_init, gfp))
600 error = -ENOMEM; 599 error = -ENOMEM;
601 else 600 else
602 error = 0; 601 error = 0;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ad3b43bb75cc..ab949320468d 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -393,8 +393,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
393 goto nomem_init; 393 goto nomem_init;
394 394
395 /* The call, sctp_process_init(), can fail on memory allocation. */ 395 /* The call, sctp_process_init(), can fail on memory allocation. */
396 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, 396 if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
397 sctp_source(chunk),
398 (sctp_init_chunk_t *)chunk->chunk_hdr, 397 (sctp_init_chunk_t *)chunk->chunk_hdr,
399 GFP_ATOMIC)) 398 GFP_ATOMIC))
400 goto nomem_init; 399 goto nomem_init;
@@ -725,7 +724,7 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
725 */ 724 */
726 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; 725 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
727 726
728 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, 727 if (!sctp_process_init(new_asoc, chunk,
729 &chunk->subh.cookie_hdr->c.peer_addr, 728 &chunk->subh.cookie_hdr->c.peer_addr,
730 peer_init, GFP_ATOMIC)) 729 peer_init, GFP_ATOMIC))
731 goto nomem_init; 730 goto nomem_init;
@@ -1464,8 +1463,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1464 * Verification Tag and Peers Verification tag into a reserved 1463 * Verification Tag and Peers Verification tag into a reserved
1465 * place (local tie-tag and per tie-tag) within the state cookie. 1464 * place (local tie-tag and per tie-tag) within the state cookie.
1466 */ 1465 */
1467 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, 1466 if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk),
1468 sctp_source(chunk),
1469 (sctp_init_chunk_t *)chunk->chunk_hdr, 1467 (sctp_init_chunk_t *)chunk->chunk_hdr,
1470 GFP_ATOMIC)) 1468 GFP_ATOMIC))
1471 goto nomem; 1469 goto nomem;
@@ -1694,8 +1692,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_a(const struct sctp_endpoint *ep,
1694 */ 1692 */
1695 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; 1693 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
1696 1694
1697 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, 1695 if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
1698 sctp_source(chunk), peer_init,
1699 GFP_ATOMIC)) 1696 GFP_ATOMIC))
1700 goto nomem; 1697 goto nomem;
1701 1698
@@ -1780,8 +1777,7 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
1780 * side effects--it is safe to run them here. 1777 * side effects--it is safe to run them here.
1781 */ 1778 */
1782 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0]; 1779 peer_init = &chunk->subh.cookie_hdr->c.peer_init[0];
1783 if (!sctp_process_init(new_asoc, chunk->chunk_hdr->type, 1780 if (!sctp_process_init(new_asoc, chunk, sctp_source(chunk), peer_init,
1784 sctp_source(chunk), peer_init,
1785 GFP_ATOMIC)) 1781 GFP_ATOMIC))
1786 goto nomem; 1782 goto nomem;
1787 1783