diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-02-08 10:53:04 -0500 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2012-09-13 21:28:02 -0400 |
commit | 9a56c2db49e7349c7963f0ce66c1ef578d44ebd3 (patch) | |
tree | de29b56483bb00efabca3ba35c7001cab2aab7be /security/keys/keyctl.c | |
parent | 5fce5e0bbd44263c36f58ad1113b599d06ed1978 (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.c | 50 |
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 | */ |
769 | long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | 769 | long 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 */ |