diff options
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r-- | security/keys/process_keys.c | 42 |
1 files changed, 26 insertions, 16 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index a50a91332fe1..4d9825f9962c 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -391,6 +391,8 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
391 | struct request_key_auth *rka; | 391 | struct request_key_auth *rka; |
392 | key_ref_t key_ref, ret, err; | 392 | key_ref_t key_ref, ret, err; |
393 | 393 | ||
394 | might_sleep(); | ||
395 | |||
394 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were | 396 | /* we want to return -EAGAIN or -ENOKEY if any of the keyrings were |
395 | * searchable, but we failed to find a key or we found a negative key; | 397 | * searchable, but we failed to find a key or we found a negative key; |
396 | * otherwise we want to return a sample error (probably -EACCES) if | 398 | * otherwise we want to return a sample error (probably -EACCES) if |
@@ -496,27 +498,35 @@ key_ref_t search_process_keyrings(struct key_type *type, | |||
496 | */ | 498 | */ |
497 | if (context->request_key_auth && | 499 | if (context->request_key_auth && |
498 | context == current && | 500 | context == current && |
499 | type != &key_type_request_key_auth && | 501 | type != &key_type_request_key_auth |
500 | key_validate(context->request_key_auth) == 0 | ||
501 | ) { | 502 | ) { |
502 | rka = context->request_key_auth->payload.data; | 503 | /* defend against the auth key being revoked */ |
504 | down_read(&context->request_key_auth->sem); | ||
503 | 505 | ||
504 | key_ref = search_process_keyrings(type, description, match, | 506 | if (key_validate(context->request_key_auth) == 0) { |
505 | rka->context); | 507 | rka = context->request_key_auth->payload.data; |
506 | 508 | ||
507 | if (!IS_ERR(key_ref)) | 509 | key_ref = search_process_keyrings(type, description, |
508 | goto found; | 510 | match, rka->context); |
509 | 511 | ||
510 | switch (PTR_ERR(key_ref)) { | 512 | up_read(&context->request_key_auth->sem); |
511 | case -EAGAIN: /* no key */ | 513 | |
512 | if (ret) | 514 | if (!IS_ERR(key_ref)) |
515 | goto found; | ||
516 | |||
517 | switch (PTR_ERR(key_ref)) { | ||
518 | case -EAGAIN: /* no key */ | ||
519 | if (ret) | ||
520 | break; | ||
521 | case -ENOKEY: /* negative key */ | ||
522 | ret = key_ref; | ||
513 | break; | 523 | break; |
514 | case -ENOKEY: /* negative key */ | 524 | default: |
515 | ret = key_ref; | 525 | err = key_ref; |
516 | break; | 526 | break; |
517 | default: | 527 | } |
518 | err = key_ref; | 528 | } else { |
519 | break; | 529 | up_read(&context->request_key_auth->sem); |
520 | } | 530 | } |
521 | } | 531 | } |
522 | 532 | ||