aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/keyctl.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2012-02-08 10:53:04 -0500
committerEric W. Biederman <ebiederm@xmission.com>2012-09-13 21:28:02 -0400
commit9a56c2db49e7349c7963f0ce66c1ef578d44ebd3 (patch)
treede29b56483bb00efabca3ba35c7001cab2aab7be /security/keys/keyctl.c
parent5fce5e0bbd44263c36f58ad1113b599d06ed1978 (diff)
userns: Convert security/keys to the new userns infrastructure
- Replace key_user ->user_ns equality checks with kuid_has_mapping checks. - Use from_kuid to generate key descriptions - Use kuid_t and kgid_t and the associated helpers instead of uid_t and gid_t - Avoid potential problems with file descriptor passing by displaying keys in the user namespace of the opener of key status proc files. Cc: linux-security-module@vger.kernel.org Cc: keyrings@linux-nfs.org Cc: David Howells <dhowells@redhat.com> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Diffstat (limited to 'security/keys/keyctl.c')
-rw-r--r--security/keys/keyctl.c50
1 files changed, 30 insertions, 20 deletions
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 3364fbf46807..1ecc0f79906e 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -569,8 +569,8 @@ okay:
569 ret = snprintf(tmpbuf, PAGE_SIZE - 1, 569 ret = snprintf(tmpbuf, PAGE_SIZE - 1,
570 "%s;%d;%d;%08x;%s", 570 "%s;%d;%d;%08x;%s",
571 key->type->name, 571 key->type->name,
572 key->uid, 572 from_kuid_munged(current_user_ns(), key->uid),
573 key->gid, 573 from_kgid_munged(current_user_ns(), key->gid),
574 key->perm, 574 key->perm,
575 key->description ?: ""); 575 key->description ?: "");
576 576
@@ -766,15 +766,25 @@ error:
766 * 766 *
767 * If successful, 0 will be returned. 767 * If successful, 0 will be returned.
768 */ 768 */
769long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) 769long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group)
770{ 770{
771 struct key_user *newowner, *zapowner = NULL; 771 struct key_user *newowner, *zapowner = NULL;
772 struct key *key; 772 struct key *key;
773 key_ref_t key_ref; 773 key_ref_t key_ref;
774 long ret; 774 long ret;
775 kuid_t uid;
776 kgid_t gid;
777
778 uid = make_kuid(current_user_ns(), user);
779 gid = make_kgid(current_user_ns(), group);
780 ret = -EINVAL;
781 if ((user != (uid_t) -1) && !uid_valid(uid))
782 goto error;
783 if ((group != (gid_t) -1) && !gid_valid(gid))
784 goto error;
775 785
776 ret = 0; 786 ret = 0;
777 if (uid == (uid_t) -1 && gid == (gid_t) -1) 787 if (user == (uid_t) -1 && group == (gid_t) -1)
778 goto error; 788 goto error;
779 789
780 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, 790 key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL,
@@ -792,27 +802,27 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
792 802
793 if (!capable(CAP_SYS_ADMIN)) { 803 if (!capable(CAP_SYS_ADMIN)) {
794 /* only the sysadmin can chown a key to some other UID */ 804 /* only the sysadmin can chown a key to some other UID */
795 if (uid != (uid_t) -1 && key->uid != uid) 805 if (user != (uid_t) -1 && !uid_eq(key->uid, uid))
796 goto error_put; 806 goto error_put;
797 807
798 /* only the sysadmin can set the key's GID to a group other 808 /* only the sysadmin can set the key's GID to a group other
799 * than one of those that the current process subscribes to */ 809 * than one of those that the current process subscribes to */
800 if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid)) 810 if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid))
801 goto error_put; 811 goto error_put;
802 } 812 }
803 813
804 /* change the UID */ 814 /* change the UID */
805 if (uid != (uid_t) -1 && uid != key->uid) { 815 if (user != (uid_t) -1 && !uid_eq(uid, key->uid)) {
806 ret = -ENOMEM; 816 ret = -ENOMEM;
807 newowner = key_user_lookup(uid, current_user_ns()); 817 newowner = key_user_lookup(uid);
808 if (!newowner) 818 if (!newowner)
809 goto error_put; 819 goto error_put;
810 820
811 /* transfer the quota burden to the new user */ 821 /* transfer the quota burden to the new user */
812 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 822 if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
813 unsigned maxkeys = (uid == 0) ? 823 unsigned maxkeys = uid_eq(uid, GLOBAL_ROOT_UID) ?
814 key_quota_root_maxkeys : key_quota_maxkeys; 824 key_quota_root_maxkeys : key_quota_maxkeys;
815 unsigned maxbytes = (uid == 0) ? 825 unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
816 key_quota_root_maxbytes : key_quota_maxbytes; 826 key_quota_root_maxbytes : key_quota_maxbytes;
817 827
818 spin_lock(&newowner->lock); 828 spin_lock(&newowner->lock);
@@ -846,7 +856,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid)
846 } 856 }
847 857
848 /* change the GID */ 858 /* change the GID */
849 if (gid != (gid_t) -1) 859 if (group != (gid_t) -1)
850 key->gid = gid; 860 key->gid = gid;
851 861
852 ret = 0; 862 ret = 0;
@@ -897,7 +907,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm)
897 down_write(&key->sem); 907 down_write(&key->sem);
898 908
899 /* if we're not the sysadmin, we can only change a key that we own */ 909 /* if we're not the sysadmin, we can only change a key that we own */
900 if (capable(CAP_SYS_ADMIN) || key->uid == current_fsuid()) { 910 if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) {
901 key->perm = perm; 911 key->perm = perm;
902 ret = 0; 912 ret = 0;
903 } 913 }
@@ -1507,18 +1517,18 @@ long keyctl_session_to_parent(void)
1507 1517
1508 /* the parent must have the same effective ownership and mustn't be 1518 /* the parent must have the same effective ownership and mustn't be
1509 * SUID/SGID */ 1519 * SUID/SGID */
1510 if (pcred->uid != mycred->euid || 1520 if (!uid_eq(pcred->uid, mycred->euid) ||
1511 pcred->euid != mycred->euid || 1521 !uid_eq(pcred->euid, mycred->euid) ||
1512 pcred->suid != mycred->euid || 1522 !uid_eq(pcred->suid, mycred->euid) ||
1513 pcred->gid != mycred->egid || 1523 !gid_eq(pcred->gid, mycred->egid) ||
1514 pcred->egid != mycred->egid || 1524 !gid_eq(pcred->egid, mycred->egid) ||
1515 pcred->sgid != mycred->egid) 1525 !gid_eq(pcred->sgid, mycred->egid))
1516 goto unlock; 1526 goto unlock;
1517 1527
1518 /* the keyrings must have the same UID */ 1528 /* the keyrings must have the same UID */
1519 if ((pcred->tgcred->session_keyring && 1529 if ((pcred->tgcred->session_keyring &&
1520 pcred->tgcred->session_keyring->uid != mycred->euid) || 1530 !uid_eq(pcred->tgcred->session_keyring->uid, mycred->euid)) ||
1521 mycred->tgcred->session_keyring->uid != mycred->euid) 1531 !uid_eq(mycred->tgcred->session_keyring->uid, mycred->euid))
1522 goto unlock; 1532 goto unlock;
1523 1533
1524 /* cancel an already pending keyring replacement */ 1534 /* cancel an already pending keyring replacement */