diff options
-rw-r--r-- | include/net/sctp/structs.h | 4 | ||||
-rw-r--r-- | net/sctp/auth.c | 17 | ||||
-rw-r--r-- | net/sctp/endpointola.c | 3 | ||||
-rw-r--r-- | net/sctp/sm_make_chunk.c | 32 | ||||
-rw-r--r-- | net/sctp/sm_statefuns.c | 6 | ||||
-rw-r--r-- | net/sctp/socket.c | 54 | ||||
-rw-r--r-- | net/sctp/sysctl.c | 36 |
7 files changed, 92 insertions, 60 deletions
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index d992ca3145fe..0dfcc92600e8 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -1241,6 +1241,7 @@ struct sctp_endpoint { | |||
1241 | /* SCTP-AUTH: endpoint shared keys */ | 1241 | /* SCTP-AUTH: endpoint shared keys */ |
1242 | struct list_head endpoint_shared_keys; | 1242 | struct list_head endpoint_shared_keys; |
1243 | __u16 active_key_id; | 1243 | __u16 active_key_id; |
1244 | __u8 auth_enable; | ||
1244 | }; | 1245 | }; |
1245 | 1246 | ||
1246 | /* Recover the outter endpoint structure. */ | 1247 | /* Recover the outter endpoint structure. */ |
@@ -1269,7 +1270,8 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *, | |||
1269 | int sctp_has_association(struct net *net, const union sctp_addr *laddr, | 1270 | int sctp_has_association(struct net *net, const union sctp_addr *laddr, |
1270 | const union sctp_addr *paddr); | 1271 | const union sctp_addr *paddr); |
1271 | 1272 | ||
1272 | int sctp_verify_init(struct net *net, const struct sctp_association *asoc, | 1273 | int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, |
1274 | const struct sctp_association *asoc, | ||
1273 | sctp_cid_t, sctp_init_chunk_t *peer_init, | 1275 | sctp_cid_t, sctp_init_chunk_t *peer_init, |
1274 | struct sctp_chunk *chunk, struct sctp_chunk **err_chunk); | 1276 | struct sctp_chunk *chunk, struct sctp_chunk **err_chunk); |
1275 | int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk, | 1277 | int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk, |
diff --git a/net/sctp/auth.c b/net/sctp/auth.c index 683c7d1b1306..0e8529113dc5 100644 --- a/net/sctp/auth.c +++ b/net/sctp/auth.c | |||
@@ -386,14 +386,13 @@ nomem: | |||
386 | */ | 386 | */ |
387 | int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) | 387 | int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) |
388 | { | 388 | { |
389 | struct net *net = sock_net(asoc->base.sk); | ||
390 | struct sctp_auth_bytes *secret; | 389 | struct sctp_auth_bytes *secret; |
391 | struct sctp_shared_key *ep_key; | 390 | struct sctp_shared_key *ep_key; |
392 | 391 | ||
393 | /* If we don't support AUTH, or peer is not capable | 392 | /* If we don't support AUTH, or peer is not capable |
394 | * we don't need to do anything. | 393 | * we don't need to do anything. |
395 | */ | 394 | */ |
396 | if (!net->sctp.auth_enable || !asoc->peer.auth_capable) | 395 | if (!asoc->ep->auth_enable || !asoc->peer.auth_capable) |
397 | return 0; | 396 | return 0; |
398 | 397 | ||
399 | /* If the key_id is non-zero and we couldn't find an | 398 | /* If the key_id is non-zero and we couldn't find an |
@@ -440,16 +439,16 @@ struct sctp_shared_key *sctp_auth_get_shkey( | |||
440 | */ | 439 | */ |
441 | int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) | 440 | int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) |
442 | { | 441 | { |
443 | struct net *net = sock_net(ep->base.sk); | ||
444 | struct crypto_hash *tfm = NULL; | 442 | struct crypto_hash *tfm = NULL; |
445 | __u16 id; | 443 | __u16 id; |
446 | 444 | ||
447 | /* if the transforms are already allocted, we are done */ | 445 | /* If AUTH extension is disabled, we are done */ |
448 | if (!net->sctp.auth_enable) { | 446 | if (!ep->auth_enable) { |
449 | ep->auth_hmacs = NULL; | 447 | ep->auth_hmacs = NULL; |
450 | return 0; | 448 | return 0; |
451 | } | 449 | } |
452 | 450 | ||
451 | /* If the transforms are already allocated, we are done */ | ||
453 | if (ep->auth_hmacs) | 452 | if (ep->auth_hmacs) |
454 | return 0; | 453 | return 0; |
455 | 454 | ||
@@ -665,12 +664,10 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param) | |||
665 | /* Check if peer requested that this chunk is authenticated */ | 664 | /* Check if peer requested that this chunk is authenticated */ |
666 | int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) | 665 | int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) |
667 | { | 666 | { |
668 | struct net *net; | ||
669 | if (!asoc) | 667 | if (!asoc) |
670 | return 0; | 668 | return 0; |
671 | 669 | ||
672 | net = sock_net(asoc->base.sk); | 670 | if (!asoc->ep->auth_enable || !asoc->peer.auth_capable) |
673 | if (!net->sctp.auth_enable || !asoc->peer.auth_capable) | ||
674 | return 0; | 671 | return 0; |
675 | 672 | ||
676 | return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); | 673 | return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); |
@@ -679,12 +676,10 @@ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) | |||
679 | /* Check if we requested that peer authenticate this chunk. */ | 676 | /* Check if we requested that peer authenticate this chunk. */ |
680 | int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc) | 677 | int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc) |
681 | { | 678 | { |
682 | struct net *net; | ||
683 | if (!asoc) | 679 | if (!asoc) |
684 | return 0; | 680 | return 0; |
685 | 681 | ||
686 | net = sock_net(asoc->base.sk); | 682 | if (!asoc->ep->auth_enable) |
687 | if (!net->sctp.auth_enable) | ||
688 | return 0; | 683 | return 0; |
689 | 684 | ||
690 | return __sctp_auth_cid(chunk, | 685 | return __sctp_auth_cid(chunk, |
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 8e5fdea05216..3d9f429858dc 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c | |||
@@ -68,7 +68,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, | |||
68 | if (!ep->digest) | 68 | if (!ep->digest) |
69 | return NULL; | 69 | return NULL; |
70 | 70 | ||
71 | if (net->sctp.auth_enable) { | 71 | ep->auth_enable = net->sctp.auth_enable; |
72 | if (ep->auth_enable) { | ||
72 | /* Allocate space for HMACS and CHUNKS authentication | 73 | /* Allocate space for HMACS and CHUNKS authentication |
73 | * variables. There are arrays that we encode directly | 74 | * variables. There are arrays that we encode directly |
74 | * into parameters to make the rest of the operations easier. | 75 | * into parameters to make the rest of the operations easier. |
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 3a1767ef3201..fee5552ddf92 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c | |||
@@ -219,6 +219,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
219 | gfp_t gfp, int vparam_len) | 219 | gfp_t gfp, int vparam_len) |
220 | { | 220 | { |
221 | struct net *net = sock_net(asoc->base.sk); | 221 | struct net *net = sock_net(asoc->base.sk); |
222 | struct sctp_endpoint *ep = asoc->ep; | ||
222 | sctp_inithdr_t init; | 223 | sctp_inithdr_t init; |
223 | union sctp_params addrs; | 224 | union sctp_params addrs; |
224 | size_t chunksize; | 225 | size_t chunksize; |
@@ -278,7 +279,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
278 | chunksize += vparam_len; | 279 | chunksize += vparam_len; |
279 | 280 | ||
280 | /* Account for AUTH related parameters */ | 281 | /* Account for AUTH related parameters */ |
281 | if (net->sctp.auth_enable) { | 282 | if (ep->auth_enable) { |
282 | /* Add random parameter length*/ | 283 | /* Add random parameter length*/ |
283 | chunksize += sizeof(asoc->c.auth_random); | 284 | chunksize += sizeof(asoc->c.auth_random); |
284 | 285 | ||
@@ -363,7 +364,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, | |||
363 | } | 364 | } |
364 | 365 | ||
365 | /* Add SCTP-AUTH chunks to the parameter list */ | 366 | /* Add SCTP-AUTH chunks to the parameter list */ |
366 | if (net->sctp.auth_enable) { | 367 | if (ep->auth_enable) { |
367 | sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), | 368 | sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), |
368 | asoc->c.auth_random); | 369 | asoc->c.auth_random); |
369 | if (auth_hmacs) | 370 | if (auth_hmacs) |
@@ -2010,7 +2011,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc, | |||
2010 | /* if the peer reports AUTH, assume that he | 2011 | /* if the peer reports AUTH, assume that he |
2011 | * supports AUTH. | 2012 | * supports AUTH. |
2012 | */ | 2013 | */ |
2013 | if (net->sctp.auth_enable) | 2014 | if (asoc->ep->auth_enable) |
2014 | asoc->peer.auth_capable = 1; | 2015 | asoc->peer.auth_capable = 1; |
2015 | break; | 2016 | break; |
2016 | case SCTP_CID_ASCONF: | 2017 | case SCTP_CID_ASCONF: |
@@ -2102,6 +2103,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc, | |||
2102 | * SCTP_IERROR_NO_ERROR - continue with the chunk | 2103 | * SCTP_IERROR_NO_ERROR - continue with the chunk |
2103 | */ | 2104 | */ |
2104 | static sctp_ierror_t sctp_verify_param(struct net *net, | 2105 | static sctp_ierror_t sctp_verify_param(struct net *net, |
2106 | const struct sctp_endpoint *ep, | ||
2105 | const struct sctp_association *asoc, | 2107 | const struct sctp_association *asoc, |
2106 | union sctp_params param, | 2108 | union sctp_params param, |
2107 | sctp_cid_t cid, | 2109 | sctp_cid_t cid, |
@@ -2152,7 +2154,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, | |||
2152 | goto fallthrough; | 2154 | goto fallthrough; |
2153 | 2155 | ||
2154 | case SCTP_PARAM_RANDOM: | 2156 | case SCTP_PARAM_RANDOM: |
2155 | if (!net->sctp.auth_enable) | 2157 | if (!ep->auth_enable) |
2156 | goto fallthrough; | 2158 | goto fallthrough; |
2157 | 2159 | ||
2158 | /* SCTP-AUTH: Secion 6.1 | 2160 | /* SCTP-AUTH: Secion 6.1 |
@@ -2169,7 +2171,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, | |||
2169 | break; | 2171 | break; |
2170 | 2172 | ||
2171 | case SCTP_PARAM_CHUNKS: | 2173 | case SCTP_PARAM_CHUNKS: |
2172 | if (!net->sctp.auth_enable) | 2174 | if (!ep->auth_enable) |
2173 | goto fallthrough; | 2175 | goto fallthrough; |
2174 | 2176 | ||
2175 | /* SCTP-AUTH: Section 3.2 | 2177 | /* SCTP-AUTH: Section 3.2 |
@@ -2185,7 +2187,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, | |||
2185 | break; | 2187 | break; |
2186 | 2188 | ||
2187 | case SCTP_PARAM_HMAC_ALGO: | 2189 | case SCTP_PARAM_HMAC_ALGO: |
2188 | if (!net->sctp.auth_enable) | 2190 | if (!ep->auth_enable) |
2189 | goto fallthrough; | 2191 | goto fallthrough; |
2190 | 2192 | ||
2191 | hmacs = (struct sctp_hmac_algo_param *)param.p; | 2193 | hmacs = (struct sctp_hmac_algo_param *)param.p; |
@@ -2220,10 +2222,9 @@ fallthrough: | |||
2220 | } | 2222 | } |
2221 | 2223 | ||
2222 | /* Verify the INIT packet before we process it. */ | 2224 | /* Verify the INIT packet before we process it. */ |
2223 | int sctp_verify_init(struct net *net, const struct sctp_association *asoc, | 2225 | int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep, |
2224 | sctp_cid_t cid, | 2226 | const struct sctp_association *asoc, sctp_cid_t cid, |
2225 | sctp_init_chunk_t *peer_init, | 2227 | sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk, |
2226 | struct sctp_chunk *chunk, | ||
2227 | struct sctp_chunk **errp) | 2228 | struct sctp_chunk **errp) |
2228 | { | 2229 | { |
2229 | union sctp_params param; | 2230 | union sctp_params param; |
@@ -2264,8 +2265,8 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc, | |||
2264 | 2265 | ||
2265 | /* Verify all the variable length parameters */ | 2266 | /* Verify all the variable length parameters */ |
2266 | sctp_walk_params(param, peer_init, init_hdr.params) { | 2267 | sctp_walk_params(param, peer_init, init_hdr.params) { |
2267 | 2268 | result = sctp_verify_param(net, ep, asoc, param, cid, | |
2268 | result = sctp_verify_param(net, asoc, param, cid, chunk, errp); | 2269 | chunk, errp); |
2269 | switch (result) { | 2270 | switch (result) { |
2270 | case SCTP_IERROR_ABORT: | 2271 | case SCTP_IERROR_ABORT: |
2271 | case SCTP_IERROR_NOMEM: | 2272 | case SCTP_IERROR_NOMEM: |
@@ -2497,6 +2498,7 @@ static int sctp_process_param(struct sctp_association *asoc, | |||
2497 | struct sctp_af *af; | 2498 | struct sctp_af *af; |
2498 | union sctp_addr_param *addr_param; | 2499 | union sctp_addr_param *addr_param; |
2499 | struct sctp_transport *t; | 2500 | struct sctp_transport *t; |
2501 | struct sctp_endpoint *ep = asoc->ep; | ||
2500 | 2502 | ||
2501 | /* We maintain all INIT parameters in network byte order all the | 2503 | /* We maintain all INIT parameters in network byte order all the |
2502 | * time. This allows us to not worry about whether the parameters | 2504 | * time. This allows us to not worry about whether the parameters |
@@ -2636,7 +2638,7 @@ do_addr_param: | |||
2636 | goto fall_through; | 2638 | goto fall_through; |
2637 | 2639 | ||
2638 | case SCTP_PARAM_RANDOM: | 2640 | case SCTP_PARAM_RANDOM: |
2639 | if (!net->sctp.auth_enable) | 2641 | if (!ep->auth_enable) |
2640 | goto fall_through; | 2642 | goto fall_through; |
2641 | 2643 | ||
2642 | /* Save peer's random parameter */ | 2644 | /* Save peer's random parameter */ |
@@ -2649,7 +2651,7 @@ do_addr_param: | |||
2649 | break; | 2651 | break; |
2650 | 2652 | ||
2651 | case SCTP_PARAM_HMAC_ALGO: | 2653 | case SCTP_PARAM_HMAC_ALGO: |
2652 | if (!net->sctp.auth_enable) | 2654 | if (!ep->auth_enable) |
2653 | goto fall_through; | 2655 | goto fall_through; |
2654 | 2656 | ||
2655 | /* Save peer's HMAC list */ | 2657 | /* Save peer's HMAC list */ |
@@ -2665,7 +2667,7 @@ do_addr_param: | |||
2665 | break; | 2667 | break; |
2666 | 2668 | ||
2667 | case SCTP_PARAM_CHUNKS: | 2669 | case SCTP_PARAM_CHUNKS: |
2668 | if (!net->sctp.auth_enable) | 2670 | if (!ep->auth_enable) |
2669 | goto fall_through; | 2671 | goto fall_through; |
2670 | 2672 | ||
2671 | asoc->peer.peer_chunks = kmemdup(param.p, | 2673 | asoc->peer.peer_chunks = kmemdup(param.p, |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index ae9fbeba40b0..5170a1ff95a1 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -357,7 +357,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net, | |||
357 | 357 | ||
358 | /* Verify the INIT chunk before processing it. */ | 358 | /* Verify the INIT chunk before processing it. */ |
359 | err_chunk = NULL; | 359 | err_chunk = NULL; |
360 | if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, | 360 | if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, |
361 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, | 361 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, |
362 | &err_chunk)) { | 362 | &err_chunk)) { |
363 | /* This chunk contains fatal error. It is to be discarded. | 363 | /* This chunk contains fatal error. It is to be discarded. |
@@ -524,7 +524,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net, | |||
524 | 524 | ||
525 | /* Verify the INIT chunk before processing it. */ | 525 | /* Verify the INIT chunk before processing it. */ |
526 | err_chunk = NULL; | 526 | err_chunk = NULL; |
527 | if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, | 527 | if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, |
528 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, | 528 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, |
529 | &err_chunk)) { | 529 | &err_chunk)) { |
530 | 530 | ||
@@ -1430,7 +1430,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init( | |||
1430 | 1430 | ||
1431 | /* Verify the INIT chunk before processing it. */ | 1431 | /* Verify the INIT chunk before processing it. */ |
1432 | err_chunk = NULL; | 1432 | err_chunk = NULL; |
1433 | if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, | 1433 | if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type, |
1434 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, | 1434 | (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, |
1435 | &err_chunk)) { | 1435 | &err_chunk)) { |
1436 | /* This chunk contains fatal error. It is to be discarded. | 1436 | /* This chunk contains fatal error. It is to be discarded. |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index ff20e2dbbbc7..fee06b99a4da 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -3321,10 +3321,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3321 | char __user *optval, | 3321 | char __user *optval, |
3322 | unsigned int optlen) | 3322 | unsigned int optlen) |
3323 | { | 3323 | { |
3324 | struct net *net = sock_net(sk); | 3324 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3325 | struct sctp_authchunk val; | 3325 | struct sctp_authchunk val; |
3326 | 3326 | ||
3327 | if (!net->sctp.auth_enable) | 3327 | if (!ep->auth_enable) |
3328 | return -EACCES; | 3328 | return -EACCES; |
3329 | 3329 | ||
3330 | if (optlen != sizeof(struct sctp_authchunk)) | 3330 | if (optlen != sizeof(struct sctp_authchunk)) |
@@ -3341,7 +3341,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk, | |||
3341 | } | 3341 | } |
3342 | 3342 | ||
3343 | /* add this chunk id to the endpoint */ | 3343 | /* add this chunk id to the endpoint */ |
3344 | return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk); | 3344 | return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk); |
3345 | } | 3345 | } |
3346 | 3346 | ||
3347 | /* | 3347 | /* |
@@ -3354,12 +3354,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3354 | char __user *optval, | 3354 | char __user *optval, |
3355 | unsigned int optlen) | 3355 | unsigned int optlen) |
3356 | { | 3356 | { |
3357 | struct net *net = sock_net(sk); | 3357 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3358 | struct sctp_hmacalgo *hmacs; | 3358 | struct sctp_hmacalgo *hmacs; |
3359 | u32 idents; | 3359 | u32 idents; |
3360 | int err; | 3360 | int err; |
3361 | 3361 | ||
3362 | if (!net->sctp.auth_enable) | 3362 | if (!ep->auth_enable) |
3363 | return -EACCES; | 3363 | return -EACCES; |
3364 | 3364 | ||
3365 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3365 | if (optlen < sizeof(struct sctp_hmacalgo)) |
@@ -3376,7 +3376,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3376 | goto out; | 3376 | goto out; |
3377 | } | 3377 | } |
3378 | 3378 | ||
3379 | err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs); | 3379 | err = sctp_auth_ep_set_hmacs(ep, hmacs); |
3380 | out: | 3380 | out: |
3381 | kfree(hmacs); | 3381 | kfree(hmacs); |
3382 | return err; | 3382 | return err; |
@@ -3392,12 +3392,12 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3392 | char __user *optval, | 3392 | char __user *optval, |
3393 | unsigned int optlen) | 3393 | unsigned int optlen) |
3394 | { | 3394 | { |
3395 | struct net *net = sock_net(sk); | 3395 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3396 | struct sctp_authkey *authkey; | 3396 | struct sctp_authkey *authkey; |
3397 | struct sctp_association *asoc; | 3397 | struct sctp_association *asoc; |
3398 | int ret; | 3398 | int ret; |
3399 | 3399 | ||
3400 | if (!net->sctp.auth_enable) | 3400 | if (!ep->auth_enable) |
3401 | return -EACCES; | 3401 | return -EACCES; |
3402 | 3402 | ||
3403 | if (optlen <= sizeof(struct sctp_authkey)) | 3403 | if (optlen <= sizeof(struct sctp_authkey)) |
@@ -3418,7 +3418,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3418 | goto out; | 3418 | goto out; |
3419 | } | 3419 | } |
3420 | 3420 | ||
3421 | ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); | 3421 | ret = sctp_auth_set_key(ep, asoc, authkey); |
3422 | out: | 3422 | out: |
3423 | kzfree(authkey); | 3423 | kzfree(authkey); |
3424 | return ret; | 3424 | return ret; |
@@ -3434,11 +3434,11 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3434 | char __user *optval, | 3434 | char __user *optval, |
3435 | unsigned int optlen) | 3435 | unsigned int optlen) |
3436 | { | 3436 | { |
3437 | struct net *net = sock_net(sk); | 3437 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3438 | struct sctp_authkeyid val; | 3438 | struct sctp_authkeyid val; |
3439 | struct sctp_association *asoc; | 3439 | struct sctp_association *asoc; |
3440 | 3440 | ||
3441 | if (!net->sctp.auth_enable) | 3441 | if (!ep->auth_enable) |
3442 | return -EACCES; | 3442 | return -EACCES; |
3443 | 3443 | ||
3444 | if (optlen != sizeof(struct sctp_authkeyid)) | 3444 | if (optlen != sizeof(struct sctp_authkeyid)) |
@@ -3450,8 +3450,7 @@ static int sctp_setsockopt_active_key(struct sock *sk, | |||
3450 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) | 3450 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) |
3451 | return -EINVAL; | 3451 | return -EINVAL; |
3452 | 3452 | ||
3453 | return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc, | 3453 | return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber); |
3454 | val.scact_keynumber); | ||
3455 | } | 3454 | } |
3456 | 3455 | ||
3457 | /* | 3456 | /* |
@@ -3463,11 +3462,11 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3463 | char __user *optval, | 3462 | char __user *optval, |
3464 | unsigned int optlen) | 3463 | unsigned int optlen) |
3465 | { | 3464 | { |
3466 | struct net *net = sock_net(sk); | 3465 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
3467 | struct sctp_authkeyid val; | 3466 | struct sctp_authkeyid val; |
3468 | struct sctp_association *asoc; | 3467 | struct sctp_association *asoc; |
3469 | 3468 | ||
3470 | if (!net->sctp.auth_enable) | 3469 | if (!ep->auth_enable) |
3471 | return -EACCES; | 3470 | return -EACCES; |
3472 | 3471 | ||
3473 | if (optlen != sizeof(struct sctp_authkeyid)) | 3472 | if (optlen != sizeof(struct sctp_authkeyid)) |
@@ -3479,8 +3478,7 @@ static int sctp_setsockopt_del_key(struct sock *sk, | |||
3479 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) | 3478 | if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) |
3480 | return -EINVAL; | 3479 | return -EINVAL; |
3481 | 3480 | ||
3482 | return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc, | 3481 | return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber); |
3483 | val.scact_keynumber); | ||
3484 | 3482 | ||
3485 | } | 3483 | } |
3486 | 3484 | ||
@@ -5387,16 +5385,16 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5387 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | 5385 | static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, |
5388 | char __user *optval, int __user *optlen) | 5386 | char __user *optval, int __user *optlen) |
5389 | { | 5387 | { |
5390 | struct net *net = sock_net(sk); | 5388 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5391 | struct sctp_hmacalgo __user *p = (void __user *)optval; | 5389 | struct sctp_hmacalgo __user *p = (void __user *)optval; |
5392 | struct sctp_hmac_algo_param *hmacs; | 5390 | struct sctp_hmac_algo_param *hmacs; |
5393 | __u16 data_len = 0; | 5391 | __u16 data_len = 0; |
5394 | u32 num_idents; | 5392 | u32 num_idents; |
5395 | 5393 | ||
5396 | if (!net->sctp.auth_enable) | 5394 | if (!ep->auth_enable) |
5397 | return -EACCES; | 5395 | return -EACCES; |
5398 | 5396 | ||
5399 | hmacs = sctp_sk(sk)->ep->auth_hmacs_list; | 5397 | hmacs = ep->auth_hmacs_list; |
5400 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); | 5398 | data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); |
5401 | 5399 | ||
5402 | if (len < sizeof(struct sctp_hmacalgo) + data_len) | 5400 | if (len < sizeof(struct sctp_hmacalgo) + data_len) |
@@ -5417,11 +5415,11 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, | |||
5417 | static int sctp_getsockopt_active_key(struct sock *sk, int len, | 5415 | static int sctp_getsockopt_active_key(struct sock *sk, int len, |
5418 | char __user *optval, int __user *optlen) | 5416 | char __user *optval, int __user *optlen) |
5419 | { | 5417 | { |
5420 | struct net *net = sock_net(sk); | 5418 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5421 | struct sctp_authkeyid val; | 5419 | struct sctp_authkeyid val; |
5422 | struct sctp_association *asoc; | 5420 | struct sctp_association *asoc; |
5423 | 5421 | ||
5424 | if (!net->sctp.auth_enable) | 5422 | if (!ep->auth_enable) |
5425 | return -EACCES; | 5423 | return -EACCES; |
5426 | 5424 | ||
5427 | if (len < sizeof(struct sctp_authkeyid)) | 5425 | if (len < sizeof(struct sctp_authkeyid)) |
@@ -5436,7 +5434,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5436 | if (asoc) | 5434 | if (asoc) |
5437 | val.scact_keynumber = asoc->active_key_id; | 5435 | val.scact_keynumber = asoc->active_key_id; |
5438 | else | 5436 | else |
5439 | val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; | 5437 | val.scact_keynumber = ep->active_key_id; |
5440 | 5438 | ||
5441 | len = sizeof(struct sctp_authkeyid); | 5439 | len = sizeof(struct sctp_authkeyid); |
5442 | if (put_user(len, optlen)) | 5440 | if (put_user(len, optlen)) |
@@ -5450,7 +5448,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
5450 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | 5448 | static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, |
5451 | char __user *optval, int __user *optlen) | 5449 | char __user *optval, int __user *optlen) |
5452 | { | 5450 | { |
5453 | struct net *net = sock_net(sk); | 5451 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5454 | struct sctp_authchunks __user *p = (void __user *)optval; | 5452 | struct sctp_authchunks __user *p = (void __user *)optval; |
5455 | struct sctp_authchunks val; | 5453 | struct sctp_authchunks val; |
5456 | struct sctp_association *asoc; | 5454 | struct sctp_association *asoc; |
@@ -5458,7 +5456,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
5458 | u32 num_chunks = 0; | 5456 | u32 num_chunks = 0; |
5459 | char __user *to; | 5457 | char __user *to; |
5460 | 5458 | ||
5461 | if (!net->sctp.auth_enable) | 5459 | if (!ep->auth_enable) |
5462 | return -EACCES; | 5460 | return -EACCES; |
5463 | 5461 | ||
5464 | if (len < sizeof(struct sctp_authchunks)) | 5462 | if (len < sizeof(struct sctp_authchunks)) |
@@ -5495,7 +5493,7 @@ num: | |||
5495 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | 5493 | static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, |
5496 | char __user *optval, int __user *optlen) | 5494 | char __user *optval, int __user *optlen) |
5497 | { | 5495 | { |
5498 | struct net *net = sock_net(sk); | 5496 | struct sctp_endpoint *ep = sctp_sk(sk)->ep; |
5499 | struct sctp_authchunks __user *p = (void __user *)optval; | 5497 | struct sctp_authchunks __user *p = (void __user *)optval; |
5500 | struct sctp_authchunks val; | 5498 | struct sctp_authchunks val; |
5501 | struct sctp_association *asoc; | 5499 | struct sctp_association *asoc; |
@@ -5503,7 +5501,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5503 | u32 num_chunks = 0; | 5501 | u32 num_chunks = 0; |
5504 | char __user *to; | 5502 | char __user *to; |
5505 | 5503 | ||
5506 | if (!net->sctp.auth_enable) | 5504 | if (!ep->auth_enable) |
5507 | return -EACCES; | 5505 | return -EACCES; |
5508 | 5506 | ||
5509 | if (len < sizeof(struct sctp_authchunks)) | 5507 | if (len < sizeof(struct sctp_authchunks)) |
@@ -5520,7 +5518,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
5520 | if (asoc) | 5518 | if (asoc) |
5521 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; | 5519 | ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; |
5522 | else | 5520 | else |
5523 | ch = sctp_sk(sk)->ep->auth_chunk_list; | 5521 | ch = ep->auth_chunk_list; |
5524 | 5522 | ||
5525 | if (!ch) | 5523 | if (!ch) |
5526 | goto num; | 5524 | goto num; |
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 35c8923b5554..c82fdc1eab7c 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c | |||
@@ -64,6 +64,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, | |||
64 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | 64 | static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, |
65 | void __user *buffer, size_t *lenp, | 65 | void __user *buffer, size_t *lenp, |
66 | loff_t *ppos); | 66 | loff_t *ppos); |
67 | static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | ||
68 | void __user *buffer, size_t *lenp, | ||
69 | loff_t *ppos); | ||
67 | 70 | ||
68 | static struct ctl_table sctp_table[] = { | 71 | static struct ctl_table sctp_table[] = { |
69 | { | 72 | { |
@@ -266,7 +269,7 @@ static struct ctl_table sctp_net_table[] = { | |||
266 | .data = &init_net.sctp.auth_enable, | 269 | .data = &init_net.sctp.auth_enable, |
267 | .maxlen = sizeof(int), | 270 | .maxlen = sizeof(int), |
268 | .mode = 0644, | 271 | .mode = 0644, |
269 | .proc_handler = proc_dointvec, | 272 | .proc_handler = proc_sctp_do_auth, |
270 | }, | 273 | }, |
271 | { | 274 | { |
272 | .procname = "addr_scope_policy", | 275 | .procname = "addr_scope_policy", |
@@ -400,6 +403,37 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, | |||
400 | return ret; | 403 | return ret; |
401 | } | 404 | } |
402 | 405 | ||
406 | static int proc_sctp_do_auth(struct ctl_table *ctl, int write, | ||
407 | void __user *buffer, size_t *lenp, | ||
408 | loff_t *ppos) | ||
409 | { | ||
410 | struct net *net = current->nsproxy->net_ns; | ||
411 | struct ctl_table tbl; | ||
412 | int new_value, ret; | ||
413 | |||
414 | memset(&tbl, 0, sizeof(struct ctl_table)); | ||
415 | tbl.maxlen = sizeof(unsigned int); | ||
416 | |||
417 | if (write) | ||
418 | tbl.data = &new_value; | ||
419 | else | ||
420 | tbl.data = &net->sctp.auth_enable; | ||
421 | |||
422 | ret = proc_dointvec(&tbl, write, buffer, lenp, ppos); | ||
423 | |||
424 | if (write) { | ||
425 | struct sock *sk = net->sctp.ctl_sock; | ||
426 | |||
427 | net->sctp.auth_enable = new_value; | ||
428 | /* Update the value in the control socket */ | ||
429 | lock_sock(sk); | ||
430 | sctp_sk(sk)->ep->auth_enable = new_value; | ||
431 | release_sock(sk); | ||
432 | } | ||
433 | |||
434 | return ret; | ||
435 | } | ||
436 | |||
403 | int sctp_sysctl_net_register(struct net *net) | 437 | int sctp_sysctl_net_register(struct net *net) |
404 | { | 438 | { |
405 | struct ctl_table *table = sctp_net_table; | 439 | struct ctl_table *table = sctp_net_table; |