aboutsummaryrefslogtreecommitdiffstats
path: root/security
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
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')
-rw-r--r--security/apparmor/domain.c4
-rw-r--r--security/apparmor/file.c12
-rw-r--r--security/apparmor/include/audit.h2
-rw-r--r--security/apparmor/include/file.h4
-rw-r--r--security/apparmor/lsm.c2
-rw-r--r--security/capability.c2
-rw-r--r--security/integrity/evm/evm_crypto.c4
-rw-r--r--security/integrity/ima/ima_audit.c5
-rw-r--r--security/integrity/ima/ima_policy.c14
-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
-rw-r--r--security/security.c2
-rw-r--r--security/selinux/selinuxfs.c6
-rw-r--r--security/selinux/ss/services.c2
-rw-r--r--security/tomoyo/audit.c23
-rw-r--r--security/tomoyo/common.c4
-rw-r--r--security/tomoyo/common.h4
-rw-r--r--security/tomoyo/condition.c20
-rw-r--r--security/tomoyo/tomoyo.c12
25 files changed, 148 insertions, 136 deletions
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index b81ea10a17a3..60f0c76a27d3 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -721,7 +721,7 @@ audit:
721 if (!permtest) 721 if (!permtest)
722 error = aa_audit_file(profile, &perms, GFP_KERNEL, 722 error = aa_audit_file(profile, &perms, GFP_KERNEL,
723 OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL, 723 OP_CHANGE_HAT, AA_MAY_CHANGEHAT, NULL,
724 target, 0, info, error); 724 target, GLOBAL_ROOT_UID, info, error);
725 725
726out: 726out:
727 aa_put_profile(hat); 727 aa_put_profile(hat);
@@ -848,7 +848,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec,
848audit: 848audit:
849 if (!permtest) 849 if (!permtest)
850 error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request, 850 error = aa_audit_file(profile, &perms, GFP_KERNEL, op, request,
851 name, hname, 0, info, error); 851 name, hname, GLOBAL_ROOT_UID, info, error);
852 852
853 aa_put_namespace(ns); 853 aa_put_namespace(ns);
854 aa_put_profile(target); 854 aa_put_profile(target);
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index cf19d4093ca4..cd21ec5b90af 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -65,7 +65,7 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
65static void file_audit_cb(struct audit_buffer *ab, void *va) 65static void file_audit_cb(struct audit_buffer *ab, void *va)
66{ 66{
67 struct common_audit_data *sa = va; 67 struct common_audit_data *sa = va;
68 uid_t fsuid = current_fsuid(); 68 kuid_t fsuid = current_fsuid();
69 69
70 if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { 70 if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
71 audit_log_format(ab, " requested_mask="); 71 audit_log_format(ab, " requested_mask=");
@@ -76,8 +76,10 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
76 audit_file_mask(ab, sa->aad->fs.denied); 76 audit_file_mask(ab, sa->aad->fs.denied);
77 } 77 }
78 if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) { 78 if (sa->aad->fs.request & AA_AUDIT_FILE_MASK) {
79 audit_log_format(ab, " fsuid=%d", fsuid); 79 audit_log_format(ab, " fsuid=%d",
80 audit_log_format(ab, " ouid=%d", sa->aad->fs.ouid); 80 from_kuid(&init_user_ns, fsuid));
81 audit_log_format(ab, " ouid=%d",
82 from_kuid(&init_user_ns, sa->aad->fs.ouid));
81 } 83 }
82 84
83 if (sa->aad->fs.target) { 85 if (sa->aad->fs.target) {
@@ -103,7 +105,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va)
103 */ 105 */
104int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, 106int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
105 gfp_t gfp, int op, u32 request, const char *name, 107 gfp_t gfp, int op, u32 request, const char *name,
106 const char *target, uid_t ouid, const char *info, int error) 108 const char *target, kuid_t ouid, const char *info, int error)
107{ 109{
108 int type = AUDIT_APPARMOR_AUTO; 110 int type = AUDIT_APPARMOR_AUTO;
109 struct common_audit_data sa; 111 struct common_audit_data sa;
@@ -201,7 +203,7 @@ static struct file_perms compute_perms(struct aa_dfa *dfa, unsigned int state,
201 */ 203 */
202 perms.kill = 0; 204 perms.kill = 0;
203 205
204 if (current_fsuid() == cond->uid) { 206 if (uid_eq(current_fsuid(), cond->uid)) {
205 perms.allow = map_old_perms(dfa_user_allow(dfa, state)); 207 perms.allow = map_old_perms(dfa_user_allow(dfa, state));
206 perms.audit = map_old_perms(dfa_user_audit(dfa, state)); 208 perms.audit = map_old_perms(dfa_user_audit(dfa, state));
207 perms.quiet = map_old_perms(dfa_user_quiet(dfa, state)); 209 perms.quiet = map_old_perms(dfa_user_quiet(dfa, state));
diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h
index 4b7e18951aea..69d8cae634e7 100644
--- a/security/apparmor/include/audit.h
+++ b/security/apparmor/include/audit.h
@@ -125,7 +125,7 @@ struct apparmor_audit_data {
125 const char *target; 125 const char *target;
126 u32 request; 126 u32 request;
127 u32 denied; 127 u32 denied;
128 uid_t ouid; 128 kuid_t ouid;
129 } fs; 129 } fs;
130 }; 130 };
131}; 131};
diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h
index f98fd4701d80..967b2deda376 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -71,7 +71,7 @@ struct path;
71 71
72/* need to make conditional which ones are being set */ 72/* need to make conditional which ones are being set */
73struct path_cond { 73struct path_cond {
74 uid_t uid; 74 kuid_t uid;
75 umode_t mode; 75 umode_t mode;
76}; 76};
77 77
@@ -146,7 +146,7 @@ static inline u16 dfa_map_xindex(u16 mask)
146 146
147int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, 147int aa_audit_file(struct aa_profile *profile, struct file_perms *perms,
148 gfp_t gfp, int op, u32 request, const char *name, 148 gfp_t gfp, int op, u32 request, const char *name,
149 const char *target, uid_t ouid, const char *info, int error); 149 const char *target, kuid_t ouid, const char *info, int error);
150 150
151/** 151/**
152 * struct aa_file_rules - components used for file rule permissions 152 * struct aa_file_rules - components used for file rule permissions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8ea39aabe948..8c2a7f6b35e2 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -352,7 +352,7 @@ static int apparmor_path_chmod(struct path *path, umode_t mode)
352 return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD); 352 return common_perm_mnt_dentry(OP_CHMOD, path->mnt, path->dentry, AA_MAY_CHMOD);
353} 353}
354 354
355static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid) 355static int apparmor_path_chown(struct path *path, kuid_t uid, kgid_t gid)
356{ 356{
357 struct path_cond cond = { path->dentry->d_inode->i_uid, 357 struct path_cond cond = { path->dentry->d_inode->i_uid,
358 path->dentry->d_inode->i_mode 358 path->dentry->d_inode->i_mode
diff --git a/security/capability.c b/security/capability.c
index 61095df8b89a..a40aac677c72 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -284,7 +284,7 @@ static int cap_path_chmod(struct path *path, umode_t mode)
284 return 0; 284 return 0;
285} 285}
286 286
287static int cap_path_chown(struct path *path, uid_t uid, gid_t gid) 287static int cap_path_chown(struct path *path, kuid_t uid, kgid_t gid)
288{ 288{
289 return 0; 289 return 0;
290} 290}
diff --git a/security/integrity/evm/evm_crypto.c b/security/integrity/evm/evm_crypto.c
index 49a464f5595b..dfb26918699c 100644
--- a/security/integrity/evm/evm_crypto.c
+++ b/security/integrity/evm/evm_crypto.c
@@ -106,8 +106,8 @@ static void hmac_add_misc(struct shash_desc *desc, struct inode *inode,
106 memset(&hmac_misc, 0, sizeof hmac_misc); 106 memset(&hmac_misc, 0, sizeof hmac_misc);
107 hmac_misc.ino = inode->i_ino; 107 hmac_misc.ino = inode->i_ino;
108 hmac_misc.generation = inode->i_generation; 108 hmac_misc.generation = inode->i_generation;
109 hmac_misc.uid = inode->i_uid; 109 hmac_misc.uid = from_kuid(&init_user_ns, inode->i_uid);
110 hmac_misc.gid = inode->i_gid; 110 hmac_misc.gid = from_kgid(&init_user_ns, inode->i_gid);
111 hmac_misc.mode = inode->i_mode; 111 hmac_misc.mode = inode->i_mode;
112 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc); 112 crypto_shash_update(desc, (const u8 *)&hmac_misc, sizeof hmac_misc);
113 crypto_shash_final(desc, digest); 113 crypto_shash_final(desc, digest);
diff --git a/security/integrity/ima/ima_audit.c b/security/integrity/ima/ima_audit.c
index 7a57f6769e9c..c586faae8fd6 100644
--- a/security/integrity/ima/ima_audit.c
+++ b/security/integrity/ima/ima_audit.c
@@ -39,8 +39,9 @@ void integrity_audit_msg(int audit_msgno, struct inode *inode,
39 39
40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno); 40 ab = audit_log_start(current->audit_context, GFP_KERNEL, audit_msgno);
41 audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u", 41 audit_log_format(ab, "pid=%d uid=%u auid=%u ses=%u",
42 current->pid, current_cred()->uid, 42 current->pid,
43 audit_get_loginuid(current), 43 from_kuid(&init_user_ns, current_cred()->uid),
44 from_kuid(&init_user_ns, audit_get_loginuid(current)),
44 audit_get_sessionid(current)); 45 audit_get_sessionid(current));
45 audit_log_task_context(ab); 46 audit_log_task_context(ab);
46 audit_log_format(ab, " op="); 47 audit_log_format(ab, " op=");
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c
index 1a9583008aae..c84df05180cb 100644
--- a/security/integrity/ima/ima_policy.c
+++ b/security/integrity/ima/ima_policy.c
@@ -39,7 +39,7 @@ struct ima_measure_rule_entry {
39 enum ima_hooks func; 39 enum ima_hooks func;
40 int mask; 40 int mask;
41 unsigned long fsmagic; 41 unsigned long fsmagic;
42 uid_t uid; 42 kuid_t uid;
43 struct { 43 struct {
44 void *rule; /* LSM file metadata specific */ 44 void *rule; /* LSM file metadata specific */
45 int type; /* audit type */ 45 int type; /* audit type */
@@ -71,7 +71,7 @@ static struct ima_measure_rule_entry default_rules[] = {
71 .flags = IMA_FUNC | IMA_MASK}, 71 .flags = IMA_FUNC | IMA_MASK},
72 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC, 72 {.action = MEASURE,.func = BPRM_CHECK,.mask = MAY_EXEC,
73 .flags = IMA_FUNC | IMA_MASK}, 73 .flags = IMA_FUNC | IMA_MASK},
74 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = 0, 74 {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID,
75 .flags = IMA_FUNC | IMA_MASK | IMA_UID}, 75 .flags = IMA_FUNC | IMA_MASK | IMA_UID},
76}; 76};
77 77
@@ -112,7 +112,7 @@ static bool ima_match_rules(struct ima_measure_rule_entry *rule,
112 if ((rule->flags & IMA_FSMAGIC) 112 if ((rule->flags & IMA_FSMAGIC)
113 && rule->fsmagic != inode->i_sb->s_magic) 113 && rule->fsmagic != inode->i_sb->s_magic)
114 return false; 114 return false;
115 if ((rule->flags & IMA_UID) && rule->uid != cred->uid) 115 if ((rule->flags & IMA_UID) && !uid_eq(rule->uid, cred->uid))
116 return false; 116 return false;
117 for (i = 0; i < MAX_LSM_RULES; i++) { 117 for (i = 0; i < MAX_LSM_RULES; i++) {
118 int rc = 0; 118 int rc = 0;
@@ -277,7 +277,7 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
277 277
278 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE); 278 ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_INTEGRITY_RULE);
279 279
280 entry->uid = -1; 280 entry->uid = INVALID_UID;
281 entry->action = UNKNOWN; 281 entry->action = UNKNOWN;
282 while ((p = strsep(&rule, " \t")) != NULL) { 282 while ((p = strsep(&rule, " \t")) != NULL) {
283 substring_t args[MAX_OPT_ARGS]; 283 substring_t args[MAX_OPT_ARGS];
@@ -361,15 +361,15 @@ static int ima_parse_rule(char *rule, struct ima_measure_rule_entry *entry)
361 case Opt_uid: 361 case Opt_uid:
362 ima_log_string(ab, "uid", args[0].from); 362 ima_log_string(ab, "uid", args[0].from);
363 363
364 if (entry->uid != -1) { 364 if (uid_valid(entry->uid)) {
365 result = -EINVAL; 365 result = -EINVAL;
366 break; 366 break;
367 } 367 }
368 368
369 result = strict_strtoul(args[0].from, 10, &lnum); 369 result = strict_strtoul(args[0].from, 10, &lnum);
370 if (!result) { 370 if (!result) {
371 entry->uid = (uid_t) lnum; 371 entry->uid = make_kuid(current_user_ns(), (uid_t)lnum);
372 if (entry->uid != lnum) 372 if (!uid_valid(entry->uid) || (((uid_t)lnum) != lnum))
373 result = -EINVAL; 373 result = -EINVAL;
374 else 374 else
375 entry->flags |= IMA_UID; 375 entry->flags |= IMA_UID;
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
diff --git a/security/security.c b/security/security.c
index 860aeb349cb3..f9a2f2ef2454 100644
--- a/security/security.c
+++ b/security/security.c
@@ -434,7 +434,7 @@ int security_path_chmod(struct path *path, umode_t mode)
434 return security_ops->path_chmod(path, mode); 434 return security_ops->path_chmod(path, mode);
435} 435}
436 436
437int security_path_chown(struct path *path, uid_t uid, gid_t gid) 437int security_path_chown(struct path *path, kuid_t uid, kgid_t gid)
438{ 438{
439 if (unlikely(IS_PRIVATE(path->dentry->d_inode))) 439 if (unlikely(IS_PRIVATE(path->dentry->d_inode)))
440 return 0; 440 return 0;
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 298e695d6822..55af8c5b57e6 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -174,7 +174,7 @@ static ssize_t sel_write_enforce(struct file *file, const char __user *buf,
174 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 174 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
175 "enforcing=%d old_enforcing=%d auid=%u ses=%u", 175 "enforcing=%d old_enforcing=%d auid=%u ses=%u",
176 new_value, selinux_enforcing, 176 new_value, selinux_enforcing,
177 audit_get_loginuid(current), 177 from_kuid(&init_user_ns, audit_get_loginuid(current)),
178 audit_get_sessionid(current)); 178 audit_get_sessionid(current));
179 selinux_enforcing = new_value; 179 selinux_enforcing = new_value;
180 if (selinux_enforcing) 180 if (selinux_enforcing)
@@ -305,7 +305,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf,
305 goto out; 305 goto out;
306 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS, 306 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
307 "selinux=0 auid=%u ses=%u", 307 "selinux=0 auid=%u ses=%u",
308 audit_get_loginuid(current), 308 from_kuid(&init_user_ns, audit_get_loginuid(current)),
309 audit_get_sessionid(current)); 309 audit_get_sessionid(current));
310 } 310 }
311 311
@@ -551,7 +551,7 @@ static ssize_t sel_write_load(struct file *file, const char __user *buf,
551out1: 551out1:
552 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD, 552 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
553 "policy loaded auid=%u ses=%u", 553 "policy loaded auid=%u ses=%u",
554 audit_get_loginuid(current), 554 from_kuid(&init_user_ns, audit_get_loginuid(current)),
555 audit_get_sessionid(current)); 555 audit_get_sessionid(current));
556out: 556out:
557 mutex_unlock(&sel_mutex); 557 mutex_unlock(&sel_mutex);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 4321b8fc8863..b4feecc3fe01 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -2440,7 +2440,7 @@ int security_set_bools(int len, int *values)
2440 sym_name(&policydb, SYM_BOOLS, i), 2440 sym_name(&policydb, SYM_BOOLS, i),
2441 !!values[i], 2441 !!values[i],
2442 policydb.bool_val_to_struct[i]->state, 2442 policydb.bool_val_to_struct[i]->state,
2443 audit_get_loginuid(current), 2443 from_kuid(&init_user_ns, audit_get_loginuid(current)),
2444 audit_get_sessionid(current)); 2444 audit_get_sessionid(current));
2445 } 2445 }
2446 if (values[i]) 2446 if (values[i])
diff --git a/security/tomoyo/audit.c b/security/tomoyo/audit.c
index 7ef9fa3e37e0..c1b00375c9ad 100644
--- a/security/tomoyo/audit.c
+++ b/security/tomoyo/audit.c
@@ -168,9 +168,14 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r)
168 stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile, 168 stamp.day, stamp.hour, stamp.min, stamp.sec, r->profile,
169 tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid, 169 tomoyo_mode[r->mode], tomoyo_yesno(r->granted), gpid,
170 tomoyo_sys_getpid(), tomoyo_sys_getppid(), 170 tomoyo_sys_getpid(), tomoyo_sys_getppid(),
171 current_uid(), current_gid(), current_euid(), 171 from_kuid(&init_user_ns, current_uid()),
172 current_egid(), current_suid(), current_sgid(), 172 from_kgid(&init_user_ns, current_gid()),
173 current_fsuid(), current_fsgid()); 173 from_kuid(&init_user_ns, current_euid()),
174 from_kgid(&init_user_ns, current_egid()),
175 from_kuid(&init_user_ns, current_suid()),
176 from_kgid(&init_user_ns, current_sgid()),
177 from_kuid(&init_user_ns, current_fsuid()),
178 from_kgid(&init_user_ns, current_fsgid()));
174 if (!obj) 179 if (!obj)
175 goto no_obj_info; 180 goto no_obj_info;
176 if (!obj->validate_done) { 181 if (!obj->validate_done) {
@@ -191,15 +196,19 @@ static char *tomoyo_print_header(struct tomoyo_request_info *r)
191 tomoyo_buffer_len - 1 - pos, 196 tomoyo_buffer_len - 1 - pos,
192 " path%u.parent={ uid=%u gid=%u " 197 " path%u.parent={ uid=%u gid=%u "
193 "ino=%lu perm=0%o }", (i >> 1) + 1, 198 "ino=%lu perm=0%o }", (i >> 1) + 1,
194 stat->uid, stat->gid, (unsigned long) 199 from_kuid(&init_user_ns, stat->uid),
195 stat->ino, stat->mode & S_IALLUGO); 200 from_kgid(&init_user_ns, stat->gid),
201 (unsigned long)stat->ino,
202 stat->mode & S_IALLUGO);
196 continue; 203 continue;
197 } 204 }
198 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos, 205 pos += snprintf(buffer + pos, tomoyo_buffer_len - 1 - pos,
199 " path%u={ uid=%u gid=%u ino=%lu major=%u" 206 " path%u={ uid=%u gid=%u ino=%lu major=%u"
200 " minor=%u perm=0%o type=%s", (i >> 1) + 1, 207 " minor=%u perm=0%o type=%s", (i >> 1) + 1,
201 stat->uid, stat->gid, (unsigned long) 208 from_kuid(&init_user_ns, stat->uid),
202 stat->ino, MAJOR(dev), MINOR(dev), 209 from_kgid(&init_user_ns, stat->gid),
210 (unsigned long)stat->ino,
211 MAJOR(dev), MINOR(dev),
203 mode & S_IALLUGO, tomoyo_filetype(mode)); 212 mode & S_IALLUGO, tomoyo_filetype(mode));
204 if (S_ISCHR(mode) || S_ISBLK(mode)) { 213 if (S_ISCHR(mode) || S_ISBLK(mode)) {
205 dev = stat->rdev; 214 dev = stat->rdev;
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 2e0f12c62938..f89a0333b813 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -925,7 +925,9 @@ static bool tomoyo_manager(void)
925 925
926 if (!tomoyo_policy_loaded) 926 if (!tomoyo_policy_loaded)
927 return true; 927 return true;
928 if (!tomoyo_manage_by_non_root && (task->cred->uid || task->cred->euid)) 928 if (!tomoyo_manage_by_non_root &&
929 (!uid_eq(task->cred->uid, GLOBAL_ROOT_UID) ||
930 !uid_eq(task->cred->euid, GLOBAL_ROOT_UID)))
929 return false; 931 return false;
930 exe = tomoyo_get_exe(); 932 exe = tomoyo_get_exe();
931 if (!exe) 933 if (!exe)
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h
index 75e4dc1c02a0..af010b62d544 100644
--- a/security/tomoyo/common.h
+++ b/security/tomoyo/common.h
@@ -561,8 +561,8 @@ struct tomoyo_address_group {
561 561
562/* Subset of "struct stat". Used by conditional ACL and audit logs. */ 562/* Subset of "struct stat". Used by conditional ACL and audit logs. */
563struct tomoyo_mini_stat { 563struct tomoyo_mini_stat {
564 uid_t uid; 564 kuid_t uid;
565 gid_t gid; 565 kgid_t gid;
566 ino_t ino; 566 ino_t ino;
567 umode_t mode; 567 umode_t mode;
568 dev_t dev; 568 dev_t dev;
diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c
index 986330b8c73e..63681e8be628 100644
--- a/security/tomoyo/condition.c
+++ b/security/tomoyo/condition.c
@@ -813,28 +813,28 @@ bool tomoyo_condition(struct tomoyo_request_info *r,
813 unsigned long value = 0; 813 unsigned long value = 0;
814 switch (index) { 814 switch (index) {
815 case TOMOYO_TASK_UID: 815 case TOMOYO_TASK_UID:
816 value = current_uid(); 816 value = from_kuid(&init_user_ns, current_uid());
817 break; 817 break;
818 case TOMOYO_TASK_EUID: 818 case TOMOYO_TASK_EUID:
819 value = current_euid(); 819 value = from_kuid(&init_user_ns, current_euid());
820 break; 820 break;
821 case TOMOYO_TASK_SUID: 821 case TOMOYO_TASK_SUID:
822 value = current_suid(); 822 value = from_kuid(&init_user_ns, current_suid());
823 break; 823 break;
824 case TOMOYO_TASK_FSUID: 824 case TOMOYO_TASK_FSUID:
825 value = current_fsuid(); 825 value = from_kuid(&init_user_ns, current_fsuid());
826 break; 826 break;
827 case TOMOYO_TASK_GID: 827 case TOMOYO_TASK_GID:
828 value = current_gid(); 828 value = from_kgid(&init_user_ns, current_gid());
829 break; 829 break;
830 case TOMOYO_TASK_EGID: 830 case TOMOYO_TASK_EGID:
831 value = current_egid(); 831 value = from_kgid(&init_user_ns, current_egid());
832 break; 832 break;
833 case TOMOYO_TASK_SGID: 833 case TOMOYO_TASK_SGID:
834 value = current_sgid(); 834 value = from_kgid(&init_user_ns, current_sgid());
835 break; 835 break;
836 case TOMOYO_TASK_FSGID: 836 case TOMOYO_TASK_FSGID:
837 value = current_fsgid(); 837 value = from_kgid(&init_user_ns, current_fsgid());
838 break; 838 break;
839 case TOMOYO_TASK_PID: 839 case TOMOYO_TASK_PID:
840 value = tomoyo_sys_getpid(); 840 value = tomoyo_sys_getpid();
@@ -970,13 +970,13 @@ bool tomoyo_condition(struct tomoyo_request_info *r,
970 case TOMOYO_PATH2_UID: 970 case TOMOYO_PATH2_UID:
971 case TOMOYO_PATH1_PARENT_UID: 971 case TOMOYO_PATH1_PARENT_UID:
972 case TOMOYO_PATH2_PARENT_UID: 972 case TOMOYO_PATH2_PARENT_UID:
973 value = stat->uid; 973 value = from_kuid(&init_user_ns, stat->uid);
974 break; 974 break;
975 case TOMOYO_PATH1_GID: 975 case TOMOYO_PATH1_GID:
976 case TOMOYO_PATH2_GID: 976 case TOMOYO_PATH2_GID:
977 case TOMOYO_PATH1_PARENT_GID: 977 case TOMOYO_PATH1_PARENT_GID:
978 case TOMOYO_PATH2_PARENT_GID: 978 case TOMOYO_PATH2_PARENT_GID:
979 value = stat->gid; 979 value = from_kgid(&init_user_ns, stat->gid);
980 break; 980 break;
981 case TOMOYO_PATH1_INO: 981 case TOMOYO_PATH1_INO:
982 case TOMOYO_PATH2_INO: 982 case TOMOYO_PATH2_INO:
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index c2d04a50f76a..d88eb3a046ed 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -373,13 +373,15 @@ static int tomoyo_path_chmod(struct path *path, umode_t mode)
373 * 373 *
374 * Returns 0 on success, negative value otherwise. 374 * Returns 0 on success, negative value otherwise.
375 */ 375 */
376static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) 376static int tomoyo_path_chown(struct path *path, kuid_t uid, kgid_t gid)
377{ 377{
378 int error = 0; 378 int error = 0;
379 if (uid != (uid_t) -1) 379 if (uid_valid(uid))
380 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path, uid); 380 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
381 if (!error && gid != (gid_t) -1) 381 from_kuid(&init_user_ns, uid));
382 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path, gid); 382 if (!error && gid_valid(gid))
383 error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
384 from_kgid(&init_user_ns, gid));
383 return error; 385 return error;
384} 386}
385 387