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.c69
1 files changed, 63 insertions, 6 deletions
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 276d27882ce8..5c23afb31ece 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -17,6 +17,7 @@
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/mutex.h> 19#include <linux/mutex.h>
20#include <linux/security.h>
20#include <linux/user_namespace.h> 21#include <linux/user_namespace.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include "internal.h" 23#include "internal.h"
@@ -487,7 +488,7 @@ static int lookup_user_key_possessed(const struct key *key, const void *target)
487 * - don't create special keyrings unless so requested 488 * - don't create special keyrings unless so requested
488 * - partially constructed keys aren't found unless requested 489 * - partially constructed keys aren't found unless requested
489 */ 490 */
490key_ref_t lookup_user_key(key_serial_t id, int create, int partial, 491key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
491 key_perm_t perm) 492 key_perm_t perm)
492{ 493{
493 struct request_key_auth *rka; 494 struct request_key_auth *rka;
@@ -503,7 +504,7 @@ try_again:
503 switch (id) { 504 switch (id) {
504 case KEY_SPEC_THREAD_KEYRING: 505 case KEY_SPEC_THREAD_KEYRING:
505 if (!cred->thread_keyring) { 506 if (!cred->thread_keyring) {
506 if (!create) 507 if (!(lflags & KEY_LOOKUP_CREATE))
507 goto error; 508 goto error;
508 509
509 ret = install_thread_keyring(); 510 ret = install_thread_keyring();
@@ -521,7 +522,7 @@ try_again:
521 522
522 case KEY_SPEC_PROCESS_KEYRING: 523 case KEY_SPEC_PROCESS_KEYRING:
523 if (!cred->tgcred->process_keyring) { 524 if (!cred->tgcred->process_keyring) {
524 if (!create) 525 if (!(lflags & KEY_LOOKUP_CREATE))
525 goto error; 526 goto error;
526 527
527 ret = install_process_keyring(); 528 ret = install_process_keyring();
@@ -642,7 +643,14 @@ try_again:
642 break; 643 break;
643 } 644 }
644 645
645 if (!partial) { 646 /* unlink does not use the nominated key in any way, so can skip all
647 * the permission checks as it is only concerned with the keyring */
648 if (lflags & KEY_LOOKUP_FOR_UNLINK) {
649 ret = 0;
650 goto error;
651 }
652
653 if (!(lflags & KEY_LOOKUP_PARTIAL)) {
646 ret = wait_for_key_construction(key, true); 654 ret = wait_for_key_construction(key, true);
647 switch (ret) { 655 switch (ret) {
648 case -ERESTARTSYS: 656 case -ERESTARTSYS:
@@ -660,7 +668,8 @@ try_again:
660 } 668 }
661 669
662 ret = -EIO; 670 ret = -EIO;
663 if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) 671 if (!(lflags & KEY_LOOKUP_PARTIAL) &&
672 !test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
664 goto invalid_key; 673 goto invalid_key;
665 674
666 /* check the permissions */ 675 /* check the permissions */
@@ -702,7 +711,7 @@ long join_session_keyring(const char *name)
702 /* only permit this if there's a single thread in the thread group - 711 /* only permit this if there's a single thread in the thread group -
703 * this avoids us having to adjust the creds on all threads and risking 712 * this avoids us having to adjust the creds on all threads and risking
704 * ENOMEM */ 713 * ENOMEM */
705 if (!is_single_threaded(current)) 714 if (!current_is_single_threaded())
706 return -EMLINK; 715 return -EMLINK;
707 716
708 new = prepare_creds(); 717 new = prepare_creds();
@@ -760,3 +769,51 @@ error:
760 abort_creds(new); 769 abort_creds(new);
761 return ret; 770 return ret;
762} 771}
772
773/*
774 * Replace a process's session keyring when that process resumes userspace on
775 * behalf of one of its children
776 */
777void key_replace_session_keyring(void)
778{
779 const struct cred *old;
780 struct cred *new;
781
782 if (!current->replacement_session_keyring)
783 return;
784
785 write_lock_irq(&tasklist_lock);
786 new = current->replacement_session_keyring;
787 current->replacement_session_keyring = NULL;
788 write_unlock_irq(&tasklist_lock);
789
790 if (!new)
791 return;
792
793 old = current_cred();
794 new-> uid = old-> uid;
795 new-> euid = old-> euid;
796 new-> suid = old-> suid;
797 new->fsuid = old->fsuid;
798 new-> gid = old-> gid;
799 new-> egid = old-> egid;
800 new-> sgid = old-> sgid;
801 new->fsgid = old->fsgid;
802 new->user = get_uid(old->user);
803 new->group_info = get_group_info(old->group_info);
804
805 new->securebits = old->securebits;
806 new->cap_inheritable = old->cap_inheritable;
807 new->cap_permitted = old->cap_permitted;
808 new->cap_effective = old->cap_effective;
809 new->cap_bset = old->cap_bset;
810
811 new->jit_keyring = old->jit_keyring;
812 new->thread_keyring = key_get(old->thread_keyring);
813 new->tgcred->tgid = old->tgcred->tgid;
814 new->tgcred->process_keyring = key_get(old->tgcred->process_keyring);
815
816 security_transfer_creds(new, old);
817
818 commit_creds(new);
819}