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.c141
1 files changed, 76 insertions, 65 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 42defae1e161..0cf8a130a267 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -235,7 +235,7 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
235 if (IS_ERR(keyring)) 235 if (IS_ERR(keyring))
236 return PTR_ERR(keyring); 236 return PTR_ERR(keyring);
237 } else { 237 } else {
238 atomic_inc(&keyring->usage); 238 __key_get(keyring);
239 } 239 }
240 240
241 /* install the keyring */ 241 /* install the keyring */
@@ -319,11 +319,7 @@ void key_fsgid_changed(struct task_struct *tsk)
319 * In the case of a successful return, the possession attribute is set on the 319 * In the case of a successful return, the possession attribute is set on the
320 * returned key reference. 320 * returned key reference.
321 */ 321 */
322key_ref_t search_my_process_keyrings(struct key_type *type, 322key_ref_t search_my_process_keyrings(struct keyring_search_context *ctx)
323 const void *description,
324 key_match_func_t match,
325 bool no_state_check,
326 const struct cred *cred)
327{ 323{
328 key_ref_t key_ref, ret, err; 324 key_ref_t key_ref, ret, err;
329 325
@@ -339,10 +335,9 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
339 err = ERR_PTR(-EAGAIN); 335 err = ERR_PTR(-EAGAIN);
340 336
341 /* search the thread keyring first */ 337 /* search the thread keyring first */
342 if (cred->thread_keyring) { 338 if (ctx->cred->thread_keyring) {
343 key_ref = keyring_search_aux( 339 key_ref = keyring_search_aux(
344 make_key_ref(cred->thread_keyring, 1), 340 make_key_ref(ctx->cred->thread_keyring, 1), ctx);
345 cred, type, description, match, no_state_check);
346 if (!IS_ERR(key_ref)) 341 if (!IS_ERR(key_ref))
347 goto found; 342 goto found;
348 343
@@ -358,10 +353,9 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
358 } 353 }
359 354
360 /* search the process keyring second */ 355 /* search the process keyring second */
361 if (cred->process_keyring) { 356 if (ctx->cred->process_keyring) {
362 key_ref = keyring_search_aux( 357 key_ref = keyring_search_aux(
363 make_key_ref(cred->process_keyring, 1), 358 make_key_ref(ctx->cred->process_keyring, 1), ctx);
364 cred, type, description, match, no_state_check);
365 if (!IS_ERR(key_ref)) 359 if (!IS_ERR(key_ref))
366 goto found; 360 goto found;
367 361
@@ -379,11 +373,11 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
379 } 373 }
380 374
381 /* search the session keyring */ 375 /* search the session keyring */
382 if (cred->session_keyring) { 376 if (ctx->cred->session_keyring) {
383 rcu_read_lock(); 377 rcu_read_lock();
384 key_ref = keyring_search_aux( 378 key_ref = keyring_search_aux(
385 make_key_ref(rcu_dereference(cred->session_keyring), 1), 379 make_key_ref(rcu_dereference(ctx->cred->session_keyring), 1),
386 cred, type, description, match, no_state_check); 380 ctx);
387 rcu_read_unlock(); 381 rcu_read_unlock();
388 382
389 if (!IS_ERR(key_ref)) 383 if (!IS_ERR(key_ref))
@@ -402,10 +396,10 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
402 } 396 }
403 } 397 }
404 /* or search the user-session keyring */ 398 /* or search the user-session keyring */
405 else if (cred->user->session_keyring) { 399 else if (ctx->cred->user->session_keyring) {
406 key_ref = keyring_search_aux( 400 key_ref = keyring_search_aux(
407 make_key_ref(cred->user->session_keyring, 1), 401 make_key_ref(ctx->cred->user->session_keyring, 1),
408 cred, type, description, match, no_state_check); 402 ctx);
409 if (!IS_ERR(key_ref)) 403 if (!IS_ERR(key_ref))
410 goto found; 404 goto found;
411 405
@@ -437,18 +431,14 @@ found:
437 * 431 *
438 * Return same as search_my_process_keyrings(). 432 * Return same as search_my_process_keyrings().
439 */ 433 */
440key_ref_t search_process_keyrings(struct key_type *type, 434key_ref_t search_process_keyrings(struct keyring_search_context *ctx)
441 const void *description,
442 key_match_func_t match,
443 const struct cred *cred)
444{ 435{
445 struct request_key_auth *rka; 436 struct request_key_auth *rka;
446 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err; 437 key_ref_t key_ref, ret = ERR_PTR(-EACCES), err;
447 438
448 might_sleep(); 439 might_sleep();
449 440
450 key_ref = search_my_process_keyrings(type, description, match, 441 key_ref = search_my_process_keyrings(ctx);
451 false, cred);
452 if (!IS_ERR(key_ref)) 442 if (!IS_ERR(key_ref))
453 goto found; 443 goto found;
454 err = key_ref; 444 err = key_ref;
@@ -457,18 +447,21 @@ key_ref_t search_process_keyrings(struct key_type *type,
457 * search the keyrings of the process mentioned there 447 * search the keyrings of the process mentioned there
458 * - we don't permit access to request_key auth keys via this method 448 * - we don't permit access to request_key auth keys via this method
459 */ 449 */
460 if (cred->request_key_auth && 450 if (ctx->cred->request_key_auth &&
461 cred == current_cred() && 451 ctx->cred == current_cred() &&
462 type != &key_type_request_key_auth 452 ctx->index_key.type != &key_type_request_key_auth
463 ) { 453 ) {
454 const struct cred *cred = ctx->cred;
455
464 /* defend against the auth key being revoked */ 456 /* defend against the auth key being revoked */
465 down_read(&cred->request_key_auth->sem); 457 down_read(&cred->request_key_auth->sem);
466 458
467 if (key_validate(cred->request_key_auth) == 0) { 459 if (key_validate(ctx->cred->request_key_auth) == 0) {
468 rka = cred->request_key_auth->payload.data; 460 rka = ctx->cred->request_key_auth->payload.data;
469 461
470 key_ref = search_process_keyrings(type, description, 462 ctx->cred = rka->cred;
471 match, rka->cred); 463 key_ref = search_process_keyrings(ctx);
464 ctx->cred = cred;
472 465
473 up_read(&cred->request_key_auth->sem); 466 up_read(&cred->request_key_auth->sem);
474 467
@@ -522,19 +515,23 @@ int lookup_user_key_possessed(const struct key *key, const void *target)
522key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, 515key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
523 key_perm_t perm) 516 key_perm_t perm)
524{ 517{
518 struct keyring_search_context ctx = {
519 .match = lookup_user_key_possessed,
520 .flags = (KEYRING_SEARCH_NO_STATE_CHECK |
521 KEYRING_SEARCH_LOOKUP_DIRECT),
522 };
525 struct request_key_auth *rka; 523 struct request_key_auth *rka;
526 const struct cred *cred;
527 struct key *key; 524 struct key *key;
528 key_ref_t key_ref, skey_ref; 525 key_ref_t key_ref, skey_ref;
529 int ret; 526 int ret;
530 527
531try_again: 528try_again:
532 cred = get_current_cred(); 529 ctx.cred = get_current_cred();
533 key_ref = ERR_PTR(-ENOKEY); 530 key_ref = ERR_PTR(-ENOKEY);
534 531
535 switch (id) { 532 switch (id) {
536 case KEY_SPEC_THREAD_KEYRING: 533 case KEY_SPEC_THREAD_KEYRING:
537 if (!cred->thread_keyring) { 534 if (!ctx.cred->thread_keyring) {
538 if (!(lflags & KEY_LOOKUP_CREATE)) 535 if (!(lflags & KEY_LOOKUP_CREATE))
539 goto error; 536 goto error;
540 537
@@ -546,13 +543,13 @@ try_again:
546 goto reget_creds; 543 goto reget_creds;
547 } 544 }
548 545
549 key = cred->thread_keyring; 546 key = ctx.cred->thread_keyring;
550 atomic_inc(&key->usage); 547 __key_get(key);
551 key_ref = make_key_ref(key, 1); 548 key_ref = make_key_ref(key, 1);
552 break; 549 break;
553 550
554 case KEY_SPEC_PROCESS_KEYRING: 551 case KEY_SPEC_PROCESS_KEYRING:
555 if (!cred->process_keyring) { 552 if (!ctx.cred->process_keyring) {
556 if (!(lflags & KEY_LOOKUP_CREATE)) 553 if (!(lflags & KEY_LOOKUP_CREATE))
557 goto error; 554 goto error;
558 555
@@ -564,13 +561,13 @@ try_again:
564 goto reget_creds; 561 goto reget_creds;
565 } 562 }
566 563
567 key = cred->process_keyring; 564 key = ctx.cred->process_keyring;
568 atomic_inc(&key->usage); 565 __key_get(key);
569 key_ref = make_key_ref(key, 1); 566 key_ref = make_key_ref(key, 1);
570 break; 567 break;
571 568
572 case KEY_SPEC_SESSION_KEYRING: 569 case KEY_SPEC_SESSION_KEYRING:
573 if (!cred->session_keyring) { 570 if (!ctx.cred->session_keyring) {
574 /* always install a session keyring upon access if one 571 /* always install a session keyring upon access if one
575 * doesn't exist yet */ 572 * doesn't exist yet */
576 ret = install_user_keyrings(); 573 ret = install_user_keyrings();
@@ -580,13 +577,13 @@ try_again:
580 ret = join_session_keyring(NULL); 577 ret = join_session_keyring(NULL);
581 else 578 else
582 ret = install_session_keyring( 579 ret = install_session_keyring(
583 cred->user->session_keyring); 580 ctx.cred->user->session_keyring);
584 581
585 if (ret < 0) 582 if (ret < 0)
586 goto error; 583 goto error;
587 goto reget_creds; 584 goto reget_creds;
588 } else if (cred->session_keyring == 585 } else if (ctx.cred->session_keyring ==
589 cred->user->session_keyring && 586 ctx.cred->user->session_keyring &&
590 lflags & KEY_LOOKUP_CREATE) { 587 lflags & KEY_LOOKUP_CREATE) {
591 ret = join_session_keyring(NULL); 588 ret = join_session_keyring(NULL);
592 if (ret < 0) 589 if (ret < 0)
@@ -595,33 +592,33 @@ try_again:
595 } 592 }
596 593
597 rcu_read_lock(); 594 rcu_read_lock();
598 key = rcu_dereference(cred->session_keyring); 595 key = rcu_dereference(ctx.cred->session_keyring);
599 atomic_inc(&key->usage); 596 __key_get(key);
600 rcu_read_unlock(); 597 rcu_read_unlock();
601 key_ref = make_key_ref(key, 1); 598 key_ref = make_key_ref(key, 1);
602 break; 599 break;
603 600
604 case KEY_SPEC_USER_KEYRING: 601 case KEY_SPEC_USER_KEYRING:
605 if (!cred->user->uid_keyring) { 602 if (!ctx.cred->user->uid_keyring) {
606 ret = install_user_keyrings(); 603 ret = install_user_keyrings();
607 if (ret < 0) 604 if (ret < 0)
608 goto error; 605 goto error;
609 } 606 }
610 607
611 key = cred->user->uid_keyring; 608 key = ctx.cred->user->uid_keyring;
612 atomic_inc(&key->usage); 609 __key_get(key);
613 key_ref = make_key_ref(key, 1); 610 key_ref = make_key_ref(key, 1);
614 break; 611 break;
615 612
616 case KEY_SPEC_USER_SESSION_KEYRING: 613 case KEY_SPEC_USER_SESSION_KEYRING:
617 if (!cred->user->session_keyring) { 614 if (!ctx.cred->user->session_keyring) {
618 ret = install_user_keyrings(); 615 ret = install_user_keyrings();
619 if (ret < 0) 616 if (ret < 0)
620 goto error; 617 goto error;
621 } 618 }
622 619
623 key = cred->user->session_keyring; 620 key = ctx.cred->user->session_keyring;
624 atomic_inc(&key->usage); 621 __key_get(key);
625 key_ref = make_key_ref(key, 1); 622 key_ref = make_key_ref(key, 1);
626 break; 623 break;
627 624
@@ -631,29 +628,29 @@ try_again:
631 goto error; 628 goto error;
632 629
633 case KEY_SPEC_REQKEY_AUTH_KEY: 630 case KEY_SPEC_REQKEY_AUTH_KEY:
634 key = cred->request_key_auth; 631 key = ctx.cred->request_key_auth;
635 if (!key) 632 if (!key)
636 goto error; 633 goto error;
637 634
638 atomic_inc(&key->usage); 635 __key_get(key);
639 key_ref = make_key_ref(key, 1); 636 key_ref = make_key_ref(key, 1);
640 break; 637 break;
641 638
642 case KEY_SPEC_REQUESTOR_KEYRING: 639 case KEY_SPEC_REQUESTOR_KEYRING:
643 if (!cred->request_key_auth) 640 if (!ctx.cred->request_key_auth)
644 goto error; 641 goto error;
645 642
646 down_read(&cred->request_key_auth->sem); 643 down_read(&ctx.cred->request_key_auth->sem);
647 if (test_bit(KEY_FLAG_REVOKED, 644 if (test_bit(KEY_FLAG_REVOKED,
648 &cred->request_key_auth->flags)) { 645 &ctx.cred->request_key_auth->flags)) {
649 key_ref = ERR_PTR(-EKEYREVOKED); 646 key_ref = ERR_PTR(-EKEYREVOKED);
650 key = NULL; 647 key = NULL;
651 } else { 648 } else {
652 rka = cred->request_key_auth->payload.data; 649 rka = ctx.cred->request_key_auth->payload.data;
653 key = rka->dest_keyring; 650 key = rka->dest_keyring;
654 atomic_inc(&key->usage); 651 __key_get(key);
655 } 652 }
656 up_read(&cred->request_key_auth->sem); 653 up_read(&ctx.cred->request_key_auth->sem);
657 if (!key) 654 if (!key)
658 goto error; 655 goto error;
659 key_ref = make_key_ref(key, 1); 656 key_ref = make_key_ref(key, 1);
@@ -673,9 +670,13 @@ try_again:
673 key_ref = make_key_ref(key, 0); 670 key_ref = make_key_ref(key, 0);
674 671
675 /* check to see if we possess the key */ 672 /* check to see if we possess the key */
676 skey_ref = search_process_keyrings(key->type, key, 673 ctx.index_key.type = key->type;
677 lookup_user_key_possessed, 674 ctx.index_key.description = key->description;
678 cred); 675 ctx.index_key.desc_len = strlen(key->description);
676 ctx.match_data = key;
677 kdebug("check possessed");
678 skey_ref = search_process_keyrings(&ctx);
679 kdebug("possessed=%p", skey_ref);
679 680
680 if (!IS_ERR(skey_ref)) { 681 if (!IS_ERR(skey_ref)) {
681 key_put(key); 682 key_put(key);
@@ -715,14 +716,14 @@ try_again:
715 goto invalid_key; 716 goto invalid_key;
716 717
717 /* check the permissions */ 718 /* check the permissions */
718 ret = key_task_permission(key_ref, cred, perm); 719 ret = key_task_permission(key_ref, ctx.cred, perm);
719 if (ret < 0) 720 if (ret < 0)
720 goto invalid_key; 721 goto invalid_key;
721 722
722 key->last_used_at = current_kernel_time().tv_sec; 723 key->last_used_at = current_kernel_time().tv_sec;
723 724
724error: 725error:
725 put_cred(cred); 726 put_cred(ctx.cred);
726 return key_ref; 727 return key_ref;
727 728
728invalid_key: 729invalid_key:
@@ -733,7 +734,7 @@ invalid_key:
733 /* if we attempted to install a keyring, then it may have caused new 734 /* if we attempted to install a keyring, then it may have caused new
734 * creds to be installed */ 735 * creds to be installed */
735reget_creds: 736reget_creds:
736 put_cred(cred); 737 put_cred(ctx.cred);
737 goto try_again; 738 goto try_again;
738} 739}
739 740
@@ -856,3 +857,13 @@ void key_change_session_keyring(struct callback_head *twork)
856 857
857 commit_creds(new); 858 commit_creds(new);
858} 859}
860
861/*
862 * Make sure that root's user and user-session keyrings exist.
863 */
864static int __init init_root_keyring(void)
865{
866 return install_user_keyrings();
867}
868
869late_initcall(init_root_keyring);