aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 14:11:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-02 14:11:09 -0400
commit437589a74b6a590d175f86cf9f7b2efcee7765e7 (patch)
tree37bf8635b1356d80ef002b00e84f3faf3d555a63 /security/keys
parent68d47a137c3bef754923bccf73fb639c9b0bbd5e (diff)
parent72235465864d84cedb2d9f26f8e1de824ee20339 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull user namespace changes from Eric Biederman: "This is a mostly modest set of changes to enable basic user namespace support. This allows the code to code to compile with user namespaces enabled and removes the assumption there is only the initial user namespace. Everything is converted except for the most complex of the filesystems: autofs4, 9p, afs, ceph, cifs, coda, fuse, gfs2, ncpfs, nfs, ocfs2 and xfs as those patches need a bit more review. The strategy is to push kuid_t and kgid_t values are far down into subsystems and filesystems as reasonable. Leaving the make_kuid and from_kuid operations to happen at the edge of userspace, as the values come off the disk, and as the values come in from the network. Letting compile type incompatible compile errors (present when user namespaces are enabled) guide me to find the issues. The most tricky areas have been the places where we had an implicit union of uid and gid values and were storing them in an unsigned int. Those places were converted into explicit unions. I made certain to handle those places with simple trivial patches. Out of that work I discovered we have generic interfaces for storing quota by projid. I had never heard of the project identifiers before. Adding full user namespace support for project identifiers accounts for most of the code size growth in my git tree. Ultimately there will be work to relax privlige checks from "capable(FOO)" to "ns_capable(user_ns, FOO)" where it is safe allowing root in a user names to do those things that today we only forbid to non-root users because it will confuse suid root applications. While I was pushing kuid_t and kgid_t changes deep into the audit code I made a few other cleanups. I capitalized on the fact we process netlink messages in the context of the message sender. I removed usage of NETLINK_CRED, and started directly using current->tty. Some of these patches have also made it into maintainer trees, with no problems from identical code from different trees showing up in linux-next. After reading through all of this code I feel like I might be able to win a game of kernel trivial pursuit." Fix up some fairly trivial conflicts in netfilter uid/git logging code. * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: (107 commits) userns: Convert the ufs filesystem to use kuid/kgid where appropriate userns: Convert the udf filesystem to use kuid/kgid where appropriate userns: Convert ubifs to use kuid/kgid userns: Convert squashfs to use kuid/kgid where appropriate userns: Convert reiserfs to use kuid and kgid where appropriate userns: Convert jfs to use kuid/kgid where appropriate userns: Convert jffs2 to use kuid and kgid where appropriate userns: Convert hpfs to use kuid and kgid where appropriate userns: Convert btrfs to use kuid/kgid where appropriate userns: Convert bfs to use kuid/kgid where appropriate userns: Convert affs to use kuid/kgid wherwe appropriate userns: On alpha modify linux_to_osf_stat to use convert from kuids and kgids userns: On ia64 deal with current_uid and current_gid being kuid and kgid userns: On ppc convert current_uid from a kuid before printing. userns: Convert s390 getting uid and gid system calls to use kuid and kgid userns: Convert s390 hypfs to use kuid and kgid where appropriate userns: Convert binder ipc to use kuids userns: Teach security_path_chown to take kuids and kgids userns: Add user namespace support to IMA userns: Convert EVM to deal with kuids and kgids in it's hmac computation ...
Diffstat (limited to 'security/keys')
-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
8 files changed, 79 insertions, 83 deletions
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 3cbe3529c418..a30e92734905 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 6cfc6478863e..305ecb76519c 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 }
@@ -1506,18 +1516,18 @@ long keyctl_session_to_parent(void)
1506 1516
1507 /* the parent must have the same effective ownership and mustn't be 1517 /* the parent must have the same effective ownership and mustn't be
1508 * SUID/SGID */ 1518 * SUID/SGID */
1509 if (pcred->uid != mycred->euid || 1519 if (!uid_eq(pcred->uid, mycred->euid) ||
1510 pcred->euid != mycred->euid || 1520 !uid_eq(pcred->euid, mycred->euid) ||
1511 pcred->suid != mycred->euid || 1521 !uid_eq(pcred->suid, mycred->euid) ||
1512 pcred->gid != mycred->egid || 1522 !gid_eq(pcred->gid, mycred->egid) ||
1513 pcred->egid != mycred->egid || 1523 !gid_eq(pcred->egid, mycred->egid) ||
1514 pcred->sgid != mycred->egid) 1524 !gid_eq(pcred->sgid, mycred->egid))
1515 goto unlock; 1525 goto unlock;
1516 1526
1517 /* the keyrings must have the same UID */ 1527 /* the keyrings must have the same UID */
1518 if ((pcred->tgcred->session_keyring && 1528 if ((pcred->tgcred->session_keyring &&
1519 pcred->tgcred->session_keyring->uid != mycred->euid) || 1529 !uid_eq(pcred->tgcred->session_keyring->uid, mycred->euid)) ||
1520 mycred->tgcred->session_keyring->uid != mycred->euid) 1530 !uid_eq(mycred->tgcred->session_keyring->uid, mycred->euid))
1521 goto unlock; 1531 goto unlock;
1522 1532
1523 /* cancel an already pending keyring replacement */ 1533 /* 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