aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--include/linux/key.h9
-rw-r--r--init/Kconfig1
-rw-r--r--security/keys/internal.h6
-rw-r--r--security/keys/key.c23
-rw-r--r--security/keys/keyctl.c50
-rw-r--r--security/keys/keyring.c4
-rw-r--r--security/keys/permission.c14
-rw-r--r--security/keys/proc.c44
-rw-r--r--security/keys/process_keys.c15
-rw-r--r--security/keys/request_key.c6
10 files changed, 84 insertions, 88 deletions
diff --git a/include/linux/key.h b/include/linux/key.h
index cef3b315ba7c..2393b1c040b6 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -24,6 +24,7 @@
24#include <linux/atomic.h> 24#include <linux/atomic.h>
25 25
26#ifdef __KERNEL__ 26#ifdef __KERNEL__
27#include <linux/uidgid.h>
27 28
28/* key handle serial number */ 29/* key handle serial number */
29typedef int32_t key_serial_t; 30typedef int32_t key_serial_t;
@@ -137,8 +138,8 @@ struct key {
137 time_t revoked_at; /* time at which key was revoked */ 138 time_t revoked_at; /* time at which key was revoked */
138 }; 139 };
139 time_t last_used_at; /* last time used for LRU keyring discard */ 140 time_t last_used_at; /* last time used for LRU keyring discard */
140 uid_t uid; 141 kuid_t uid;
141 gid_t gid; 142 kgid_t gid;
142 key_perm_t perm; /* access permissions */ 143 key_perm_t perm; /* access permissions */
143 unsigned short quotalen; /* length added to quota */ 144 unsigned short quotalen; /* length added to quota */
144 unsigned short datalen; /* payload data length 145 unsigned short datalen; /* payload data length
@@ -193,7 +194,7 @@ struct key {
193 194
194extern struct key *key_alloc(struct key_type *type, 195extern struct key *key_alloc(struct key_type *type,
195 const char *desc, 196 const char *desc,
196 uid_t uid, gid_t gid, 197 kuid_t uid, kgid_t gid,
197 const struct cred *cred, 198 const struct cred *cred,
198 key_perm_t perm, 199 key_perm_t perm,
199 unsigned long flags); 200 unsigned long flags);
@@ -262,7 +263,7 @@ extern int key_link(struct key *keyring,
262extern int key_unlink(struct key *keyring, 263extern int key_unlink(struct key *keyring,
263 struct key *key); 264 struct key *key);
264 265
265extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 266extern struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
266 const struct cred *cred, 267 const struct cred *cred,
267 unsigned long flags, 268 unsigned long flags,
268 struct key *dest); 269 struct key *dest);
diff --git a/init/Kconfig b/init/Kconfig
index 6db6e751c5f3..8dce71122709 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -927,7 +927,6 @@ config UIDGID_CONVERTED
927 # Features 927 # Features
928 depends on IMA = n 928 depends on IMA = n
929 depends on EVM = n 929 depends on EVM = n
930 depends on KEYS = n
931 depends on AUDIT = n 930 depends on AUDIT = n
932 depends on AUDITSYSCALL = n 931 depends on AUDITSYSCALL = n
933 depends on TASKSTATS = n 932 depends on TASKSTATS = n
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 22ff05269e3d..8bbefc3b55d4 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -52,8 +52,7 @@ struct key_user {
52 atomic_t usage; /* for accessing qnkeys & qnbytes */ 52 atomic_t usage; /* for accessing qnkeys & qnbytes */
53 atomic_t nkeys; /* number of keys */ 53 atomic_t nkeys; /* number of keys */
54 atomic_t nikeys; /* number of instantiated keys */ 54 atomic_t nikeys; /* number of instantiated keys */
55 uid_t uid; 55 kuid_t uid;
56 struct user_namespace *user_ns;
57 int qnkeys; /* number of keys allocated to this user */ 56 int qnkeys; /* number of keys allocated to this user */
58 int qnbytes; /* number of bytes allocated to this user */ 57 int qnbytes; /* number of bytes allocated to this user */
59}; 58};
@@ -62,8 +61,7 @@ extern struct rb_root key_user_tree;
62extern spinlock_t key_user_lock; 61extern spinlock_t key_user_lock;
63extern struct key_user root_key_user; 62extern struct key_user root_key_user;
64 63
65extern struct key_user *key_user_lookup(uid_t uid, 64extern struct key_user *key_user_lookup(kuid_t uid);
66 struct user_namespace *user_ns);
67extern void key_user_put(struct key_user *user); 65extern void key_user_put(struct key_user *user);
68 66
69/* 67/*
diff --git a/security/keys/key.c b/security/keys/key.c
index 50d96d4e06f2..4289c5ba2710 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -18,7 +18,6 @@
18#include <linux/workqueue.h> 18#include <linux/workqueue.h>
19#include <linux/random.h> 19#include <linux/random.h>
20#include <linux/err.h> 20#include <linux/err.h>
21#include <linux/user_namespace.h>
22#include "internal.h" 21#include "internal.h"
23 22
24struct kmem_cache *key_jar; 23struct kmem_cache *key_jar;
@@ -52,7 +51,7 @@ void __key_check(const struct key *key)
52 * Get the key quota record for a user, allocating a new record if one doesn't 51 * Get the key quota record for a user, allocating a new record if one doesn't
53 * already exist. 52 * already exist.
54 */ 53 */
55struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) 54struct key_user *key_user_lookup(kuid_t uid)
56{ 55{
57 struct key_user *candidate = NULL, *user; 56 struct key_user *candidate = NULL, *user;
58 struct rb_node *parent = NULL; 57 struct rb_node *parent = NULL;
@@ -67,13 +66,9 @@ try_again:
67 parent = *p; 66 parent = *p;
68 user = rb_entry(parent, struct key_user, node); 67 user = rb_entry(parent, struct key_user, node);
69 68
70 if (uid < user->uid) 69 if (uid_lt(uid, user->uid))
71 p = &(*p)->rb_left; 70 p = &(*p)->rb_left;
72 else if (uid > user->uid) 71 else if (uid_gt(uid, user->uid))
73 p = &(*p)->rb_right;
74 else if (user_ns < user->user_ns)
75 p = &(*p)->rb_left;
76 else if (user_ns > user->user_ns)
77 p = &(*p)->rb_right; 72 p = &(*p)->rb_right;
78 else 73 else
79 goto found; 74 goto found;
@@ -102,7 +97,6 @@ try_again:
102 atomic_set(&candidate->nkeys, 0); 97 atomic_set(&candidate->nkeys, 0);
103 atomic_set(&candidate->nikeys, 0); 98 atomic_set(&candidate->nikeys, 0);
104 candidate->uid = uid; 99 candidate->uid = uid;
105 candidate->user_ns = get_user_ns(user_ns);
106 candidate->qnkeys = 0; 100 candidate->qnkeys = 0;
107 candidate->qnbytes = 0; 101 candidate->qnbytes = 0;
108 spin_lock_init(&candidate->lock); 102 spin_lock_init(&candidate->lock);
@@ -131,7 +125,6 @@ void key_user_put(struct key_user *user)
131 if (atomic_dec_and_lock(&user->usage, &key_user_lock)) { 125 if (atomic_dec_and_lock(&user->usage, &key_user_lock)) {
132 rb_erase(&user->node, &key_user_tree); 126 rb_erase(&user->node, &key_user_tree);
133 spin_unlock(&key_user_lock); 127 spin_unlock(&key_user_lock);
134 put_user_ns(user->user_ns);
135 128
136 kfree(user); 129 kfree(user);
137 } 130 }
@@ -229,7 +222,7 @@ serial_exists:
229 * key_alloc() calls don't race with module unloading. 222 * key_alloc() calls don't race with module unloading.
230 */ 223 */
231struct key *key_alloc(struct key_type *type, const char *desc, 224struct key *key_alloc(struct key_type *type, const char *desc,
232 uid_t uid, gid_t gid, const struct cred *cred, 225 kuid_t uid, kgid_t gid, const struct cred *cred,
233 key_perm_t perm, unsigned long flags) 226 key_perm_t perm, unsigned long flags)
234{ 227{
235 struct key_user *user = NULL; 228 struct key_user *user = NULL;
@@ -253,16 +246,16 @@ struct key *key_alloc(struct key_type *type, const char *desc,
253 quotalen = desclen + type->def_datalen; 246 quotalen = desclen + type->def_datalen;
254 247
255 /* get hold of the key tracking for this user */ 248 /* get hold of the key tracking for this user */
256 user = key_user_lookup(uid, cred->user_ns); 249 user = key_user_lookup(uid);
257 if (!user) 250 if (!user)
258 goto no_memory_1; 251 goto no_memory_1;
259 252
260 /* check that the user's quota permits allocation of another key and 253 /* check that the user's quota permits allocation of another key and
261 * its description */ 254 * its description */
262 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) { 255 if (!(flags & KEY_ALLOC_NOT_IN_QUOTA)) {
263 unsigned maxkeys = (uid == 0) ? 256 unsigned maxkeys = uid_eq(uid, GLOBAL_ROOT_UID) ?
264 key_quota_root_maxkeys : key_quota_maxkeys; 257 key_quota_root_maxkeys : key_quota_maxkeys;
265 unsigned maxbytes = (uid == 0) ? 258 unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ?
266 key_quota_root_maxbytes : key_quota_maxbytes; 259 key_quota_root_maxbytes : key_quota_maxbytes;
267 260
268 spin_lock(&user->lock); 261 spin_lock(&user->lock);
@@ -380,7 +373,7 @@ int key_payload_reserve(struct key *key, size_t datalen)
380 373
381 /* contemplate the quota adjustment */ 374 /* contemplate the quota adjustment */
382 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { 375 if (delta != 0 && test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) {
383 unsigned maxbytes = (key->user->uid == 0) ? 376 unsigned maxbytes = uid_eq(key->user->uid, GLOBAL_ROOT_UID) ?
384 key_quota_root_maxbytes : key_quota_maxbytes; 377 key_quota_root_maxbytes : key_quota_maxbytes;
385 378
386 spin_lock(&key->user->lock); 379 spin_lock(&key->user->lock);
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 */
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index 81e7852d281d..a5f5c4b6edc5 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -256,7 +256,7 @@ error:
256/* 256/*
257 * Allocate a keyring and link into the destination keyring. 257 * Allocate a keyring and link into the destination keyring.
258 */ 258 */
259struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, 259struct key *keyring_alloc(const char *description, kuid_t uid, kgid_t gid,
260 const struct cred *cred, unsigned long flags, 260 const struct cred *cred, unsigned long flags,
261 struct key *dest) 261 struct key *dest)
262{ 262{
@@ -612,7 +612,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
612 &keyring_name_hash[bucket], 612 &keyring_name_hash[bucket],
613 type_data.link 613 type_data.link
614 ) { 614 ) {
615 if (keyring->user->user_ns != current_user_ns()) 615 if (!kuid_has_mapping(current_user_ns(), keyring->user->uid))
616 continue; 616 continue;
617 617
618 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) 618 if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 0b4d019e027d..efcc0c855a0d 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -36,33 +36,27 @@ int key_task_permission(const key_ref_t key_ref, const struct cred *cred,
36 36
37 key = key_ref_to_ptr(key_ref); 37 key = key_ref_to_ptr(key_ref);
38 38
39 if (key->user->user_ns != cred->user_ns)
40 goto use_other_perms;
41
42 /* use the second 8-bits of permissions for keys the caller owns */ 39 /* use the second 8-bits of permissions for keys the caller owns */
43 if (key->uid == cred->fsuid) { 40 if (uid_eq(key->uid, cred->fsuid)) {
44 kperm = key->perm >> 16; 41 kperm = key->perm >> 16;
45 goto use_these_perms; 42 goto use_these_perms;
46 } 43 }
47 44
48 /* use the third 8-bits of permissions for keys the caller has a group 45 /* use the third 8-bits of permissions for keys the caller has a group
49 * membership in common with */ 46 * membership in common with */
50 if (key->gid != -1 && key->perm & KEY_GRP_ALL) { 47 if (gid_valid(key->gid) && key->perm & KEY_GRP_ALL) {
51 if (key->gid == cred->fsgid) { 48 if (gid_eq(key->gid, cred->fsgid)) {
52 kperm = key->perm >> 8; 49 kperm = key->perm >> 8;
53 goto use_these_perms; 50 goto use_these_perms;
54 } 51 }
55 52
56 ret = groups_search(cred->group_info, 53 ret = groups_search(cred->group_info, key->gid);
57 make_kgid(current_user_ns(), key->gid));
58 if (ret) { 54 if (ret) {
59 kperm = key->perm >> 8; 55 kperm = key->perm >> 8;
60 goto use_these_perms; 56 goto use_these_perms;
61 } 57 }
62 } 58 }
63 59
64use_other_perms:
65
66 /* otherwise use the least-significant 8-bits */ 60 /* otherwise use the least-significant 8-bits */
67 kperm = key->perm; 61 kperm = key->perm;
68 62
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 30d1ddfd9cef..217b6855e815 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -88,14 +88,14 @@ __initcall(key_proc_init);
88 */ 88 */
89#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS 89#ifdef CONFIG_KEYS_DEBUG_PROC_KEYS
90 90
91static struct rb_node *key_serial_next(struct rb_node *n) 91static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n)
92{ 92{
93 struct user_namespace *user_ns = current_user_ns(); 93 struct user_namespace *user_ns = seq_user_ns(p);
94 94
95 n = rb_next(n); 95 n = rb_next(n);
96 while (n) { 96 while (n) {
97 struct key *key = rb_entry(n, struct key, serial_node); 97 struct key *key = rb_entry(n, struct key, serial_node);
98 if (key->user->user_ns == user_ns) 98 if (kuid_has_mapping(user_ns, key->user->uid))
99 break; 99 break;
100 n = rb_next(n); 100 n = rb_next(n);
101 } 101 }
@@ -107,9 +107,9 @@ static int proc_keys_open(struct inode *inode, struct file *file)
107 return seq_open(file, &proc_keys_ops); 107 return seq_open(file, &proc_keys_ops);
108} 108}
109 109
110static struct key *find_ge_key(key_serial_t id) 110static struct key *find_ge_key(struct seq_file *p, key_serial_t id)
111{ 111{
112 struct user_namespace *user_ns = current_user_ns(); 112 struct user_namespace *user_ns = seq_user_ns(p);
113 struct rb_node *n = key_serial_tree.rb_node; 113 struct rb_node *n = key_serial_tree.rb_node;
114 struct key *minkey = NULL; 114 struct key *minkey = NULL;
115 115
@@ -132,7 +132,7 @@ static struct key *find_ge_key(key_serial_t id)
132 return NULL; 132 return NULL;
133 133
134 for (;;) { 134 for (;;) {
135 if (minkey->user->user_ns == user_ns) 135 if (kuid_has_mapping(user_ns, minkey->user->uid))
136 return minkey; 136 return minkey;
137 n = rb_next(&minkey->serial_node); 137 n = rb_next(&minkey->serial_node);
138 if (!n) 138 if (!n)
@@ -151,7 +151,7 @@ static void *proc_keys_start(struct seq_file *p, loff_t *_pos)
151 151
152 if (*_pos > INT_MAX) 152 if (*_pos > INT_MAX)
153 return NULL; 153 return NULL;
154 key = find_ge_key(pos); 154 key = find_ge_key(p, pos);
155 if (!key) 155 if (!key)
156 return NULL; 156 return NULL;
157 *_pos = key->serial; 157 *_pos = key->serial;
@@ -168,7 +168,7 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos)
168{ 168{
169 struct rb_node *n; 169 struct rb_node *n;
170 170
171 n = key_serial_next(v); 171 n = key_serial_next(p, v);
172 if (n) 172 if (n)
173 *_pos = key_node_serial(n); 173 *_pos = key_node_serial(n);
174 return n; 174 return n;
@@ -254,8 +254,8 @@ static int proc_keys_show(struct seq_file *m, void *v)
254 atomic_read(&key->usage), 254 atomic_read(&key->usage),
255 xbuf, 255 xbuf,
256 key->perm, 256 key->perm,
257 key->uid, 257 from_kuid_munged(seq_user_ns(m), key->uid),
258 key->gid, 258 from_kgid_munged(seq_user_ns(m), key->gid),
259 key->type->name); 259 key->type->name);
260 260
261#undef showflag 261#undef showflag
@@ -270,26 +270,26 @@ static int proc_keys_show(struct seq_file *m, void *v)
270 270
271#endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */ 271#endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */
272 272
273static struct rb_node *__key_user_next(struct rb_node *n) 273static struct rb_node *__key_user_next(struct user_namespace *user_ns, struct rb_node *n)
274{ 274{
275 while (n) { 275 while (n) {
276 struct key_user *user = rb_entry(n, struct key_user, node); 276 struct key_user *user = rb_entry(n, struct key_user, node);
277 if (user->user_ns == current_user_ns()) 277 if (kuid_has_mapping(user_ns, user->uid))
278 break; 278 break;
279 n = rb_next(n); 279 n = rb_next(n);
280 } 280 }
281 return n; 281 return n;
282} 282}
283 283
284static struct rb_node *key_user_next(struct rb_node *n) 284static struct rb_node *key_user_next(struct user_namespace *user_ns, struct rb_node *n)
285{ 285{
286 return __key_user_next(rb_next(n)); 286 return __key_user_next(user_ns, rb_next(n));
287} 287}
288 288
289static struct rb_node *key_user_first(struct rb_root *r) 289static struct rb_node *key_user_first(struct user_namespace *user_ns, struct rb_root *r)
290{ 290{
291 struct rb_node *n = rb_first(r); 291 struct rb_node *n = rb_first(r);
292 return __key_user_next(n); 292 return __key_user_next(user_ns, n);
293} 293}
294 294
295/* 295/*
@@ -309,10 +309,10 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos)
309 309
310 spin_lock(&key_user_lock); 310 spin_lock(&key_user_lock);
311 311
312 _p = key_user_first(&key_user_tree); 312 _p = key_user_first(seq_user_ns(p), &key_user_tree);
313 while (pos > 0 && _p) { 313 while (pos > 0 && _p) {
314 pos--; 314 pos--;
315 _p = key_user_next(_p); 315 _p = key_user_next(seq_user_ns(p), _p);
316 } 316 }
317 317
318 return _p; 318 return _p;
@@ -321,7 +321,7 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos)
321static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) 321static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos)
322{ 322{
323 (*_pos)++; 323 (*_pos)++;
324 return key_user_next((struct rb_node *)v); 324 return key_user_next(seq_user_ns(p), (struct rb_node *)v);
325} 325}
326 326
327static void proc_key_users_stop(struct seq_file *p, void *v) 327static void proc_key_users_stop(struct seq_file *p, void *v)
@@ -334,13 +334,13 @@ static int proc_key_users_show(struct seq_file *m, void *v)
334{ 334{
335 struct rb_node *_p = v; 335 struct rb_node *_p = v;
336 struct key_user *user = rb_entry(_p, struct key_user, node); 336 struct key_user *user = rb_entry(_p, struct key_user, node);
337 unsigned maxkeys = (user->uid == 0) ? 337 unsigned maxkeys = uid_eq(user->uid, GLOBAL_ROOT_UID) ?
338 key_quota_root_maxkeys : key_quota_maxkeys; 338 key_quota_root_maxkeys : key_quota_maxkeys;
339 unsigned maxbytes = (user->uid == 0) ? 339 unsigned maxbytes = uid_eq(user->uid, GLOBAL_ROOT_UID) ?
340 key_quota_root_maxbytes : key_quota_maxbytes; 340 key_quota_root_maxbytes : key_quota_maxbytes;
341 341
342 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n", 342 seq_printf(m, "%5u: %5d %d/%d %d/%d %d/%d\n",
343 user->uid, 343 from_kuid_munged(seq_user_ns(m), user->uid),
344 atomic_read(&user->usage), 344 atomic_read(&user->usage),
345 atomic_read(&user->nkeys), 345 atomic_read(&user->nkeys),
346 atomic_read(&user->nikeys), 346 atomic_read(&user->nikeys),
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 54339cfd6734..a58f712605d8 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -34,8 +34,7 @@ struct key_user root_key_user = {
34 .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock), 34 .lock = __SPIN_LOCK_UNLOCKED(root_key_user.lock),
35 .nkeys = ATOMIC_INIT(2), 35 .nkeys = ATOMIC_INIT(2),
36 .nikeys = ATOMIC_INIT(2), 36 .nikeys = ATOMIC_INIT(2),
37 .uid = 0, 37 .uid = GLOBAL_ROOT_UID,
38 .user_ns = &init_user_ns,
39}; 38};
40 39
41/* 40/*
@@ -48,11 +47,13 @@ int install_user_keyrings(void)
48 struct key *uid_keyring, *session_keyring; 47 struct key *uid_keyring, *session_keyring;
49 char buf[20]; 48 char buf[20];
50 int ret; 49 int ret;
50 uid_t uid;
51 51
52 cred = current_cred(); 52 cred = current_cred();
53 user = cred->user; 53 user = cred->user;
54 uid = from_kuid(cred->user_ns, user->uid);
54 55
55 kenter("%p{%u}", user, user->uid); 56 kenter("%p{%u}", user, uid);
56 57
57 if (user->uid_keyring) { 58 if (user->uid_keyring) {
58 kleave(" = 0 [exist]"); 59 kleave(" = 0 [exist]");
@@ -67,11 +68,11 @@ int install_user_keyrings(void)
67 * - there may be one in existence already as it may have been 68 * - there may be one in existence already as it may have been
68 * pinned by a session, but the user_struct pointing to it 69 * pinned by a session, but the user_struct pointing to it
69 * may have been destroyed by setuid */ 70 * may have been destroyed by setuid */
70 sprintf(buf, "_uid.%u", user->uid); 71 sprintf(buf, "_uid.%u", uid);
71 72
72 uid_keyring = find_keyring_by_name(buf, true); 73 uid_keyring = find_keyring_by_name(buf, true);
73 if (IS_ERR(uid_keyring)) { 74 if (IS_ERR(uid_keyring)) {
74 uid_keyring = keyring_alloc(buf, user->uid, (gid_t) -1, 75 uid_keyring = keyring_alloc(buf, user->uid, INVALID_GID,
75 cred, KEY_ALLOC_IN_QUOTA, 76 cred, KEY_ALLOC_IN_QUOTA,
76 NULL); 77 NULL);
77 if (IS_ERR(uid_keyring)) { 78 if (IS_ERR(uid_keyring)) {
@@ -82,12 +83,12 @@ int install_user_keyrings(void)
82 83
83 /* get a default session keyring (which might also exist 84 /* get a default session keyring (which might also exist
84 * already) */ 85 * already) */
85 sprintf(buf, "_uid_ses.%u", user->uid); 86 sprintf(buf, "_uid_ses.%u", uid);
86 87
87 session_keyring = find_keyring_by_name(buf, true); 88 session_keyring = find_keyring_by_name(buf, true);
88 if (IS_ERR(session_keyring)) { 89 if (IS_ERR(session_keyring)) {
89 session_keyring = 90 session_keyring =
90 keyring_alloc(buf, user->uid, (gid_t) -1, 91 keyring_alloc(buf, user->uid, INVALID_GID,
91 cred, KEY_ALLOC_IN_QUOTA, NULL); 92 cred, KEY_ALLOC_IN_QUOTA, NULL);
92 if (IS_ERR(session_keyring)) { 93 if (IS_ERR(session_keyring)) {
93 ret = PTR_ERR(session_keyring); 94 ret = PTR_ERR(session_keyring);
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index 000e75017520..66e21184b559 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -139,8 +139,8 @@ static int call_sbin_request_key(struct key_construction *cons,
139 goto error_link; 139 goto error_link;
140 140
141 /* record the UID and GID */ 141 /* record the UID and GID */
142 sprintf(uid_str, "%d", cred->fsuid); 142 sprintf(uid_str, "%d", from_kuid(&init_user_ns, cred->fsuid));
143 sprintf(gid_str, "%d", cred->fsgid); 143 sprintf(gid_str, "%d", from_kgid(&init_user_ns, cred->fsgid));
144 144
145 /* we say which key is under construction */ 145 /* we say which key is under construction */
146 sprintf(key_str, "%d", key->serial); 146 sprintf(key_str, "%d", key->serial);
@@ -442,7 +442,7 @@ static struct key *construct_key_and_link(struct key_type *type,
442 442
443 kenter(""); 443 kenter("");
444 444
445 user = key_user_lookup(current_fsuid(), current_user_ns()); 445 user = key_user_lookup(current_fsuid());
446 if (!user) 446 if (!user)
447 return ERR_PTR(-ENOMEM); 447 return ERR_PTR(-ENOMEM);
448 448