aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/process_keys.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/process_keys.c')
-rw-r--r--security/keys/process_keys.c42
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