diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/domain.c | 4 | ||||
-rw-r--r-- | security/apparmor/file.c | 12 | ||||
-rw-r--r-- | security/apparmor/include/audit.h | 2 | ||||
-rw-r--r-- | security/apparmor/include/file.h | 4 | ||||
-rw-r--r-- | security/apparmor/lsm.c | 2 | ||||
-rw-r--r-- | security/capability.c | 2 | ||||
-rw-r--r-- | security/integrity/evm/evm_crypto.c | 4 | ||||
-rw-r--r-- | security/integrity/ima/ima_audit.c | 5 | ||||
-rw-r--r-- | security/integrity/ima/ima_policy.c | 14 | ||||
-rw-r--r-- | security/keys/internal.h | 6 | ||||
-rw-r--r-- | security/keys/key.c | 23 | ||||
-rw-r--r-- | security/keys/keyctl.c | 50 | ||||
-rw-r--r-- | security/keys/keyring.c | 4 | ||||
-rw-r--r-- | security/keys/permission.c | 14 | ||||
-rw-r--r-- | security/keys/proc.c | 44 | ||||
-rw-r--r-- | security/keys/process_keys.c | 15 | ||||
-rw-r--r-- | security/keys/request_key.c | 6 | ||||
-rw-r--r-- | security/security.c | 2 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 6 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 2 | ||||
-rw-r--r-- | security/tomoyo/audit.c | 23 | ||||
-rw-r--r-- | security/tomoyo/common.c | 4 | ||||
-rw-r--r-- | security/tomoyo/common.h | 4 | ||||
-rw-r--r-- | security/tomoyo/condition.c | 20 | ||||
-rw-r--r-- | security/tomoyo/tomoyo.c | 12 |
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 | ||
726 | out: | 726 | out: |
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, | |||
848 | audit: | 848 | audit: |
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) | |||
65 | static void file_audit_cb(struct audit_buffer *ab, void *va) | 65 | static 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 | */ |
104 | int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, | 106 | int 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 */ |
73 | struct path_cond { | 73 | struct 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 | ||
147 | int aa_audit_file(struct aa_profile *profile, struct file_perms *perms, | 147 | int 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 | ||
355 | static int apparmor_path_chown(struct path *path, uid_t uid, gid_t gid) | 355 | static 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 | ||
287 | static int cap_path_chown(struct path *path, uid_t uid, gid_t gid) | 287 | static 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; | |||
62 | extern spinlock_t key_user_lock; | 61 | extern spinlock_t key_user_lock; |
63 | extern struct key_user root_key_user; | 62 | extern struct key_user root_key_user; |
64 | 63 | ||
65 | extern struct key_user *key_user_lookup(uid_t uid, | 64 | extern struct key_user *key_user_lookup(kuid_t uid); |
66 | struct user_namespace *user_ns); | ||
67 | extern void key_user_put(struct key_user *user); | 65 | extern 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 | ||
24 | struct kmem_cache *key_jar; | 23 | struct 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 | */ |
55 | struct key_user *key_user_lookup(uid_t uid, struct user_namespace *user_ns) | 54 | struct 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 | */ |
231 | struct key *key_alloc(struct key_type *type, const char *desc, | 224 | struct 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 | */ |
769 | long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | 769 | long keyctl_chown_key(key_serial_t id, uid_t user, gid_t group) |
770 | { | 770 | { |
771 | struct key_user *newowner, *zapowner = NULL; | 771 | struct key_user *newowner, *zapowner = NULL; |
772 | struct key *key; | 772 | struct key *key; |
773 | key_ref_t key_ref; | 773 | key_ref_t key_ref; |
774 | long ret; | 774 | long ret; |
775 | kuid_t uid; | ||
776 | kgid_t gid; | ||
777 | |||
778 | uid = make_kuid(current_user_ns(), user); | ||
779 | gid = make_kgid(current_user_ns(), group); | ||
780 | ret = -EINVAL; | ||
781 | if ((user != (uid_t) -1) && !uid_valid(uid)) | ||
782 | goto error; | ||
783 | if ((group != (gid_t) -1) && !gid_valid(gid)) | ||
784 | goto error; | ||
775 | 785 | ||
776 | ret = 0; | 786 | ret = 0; |
777 | if (uid == (uid_t) -1 && gid == (gid_t) -1) | 787 | if (user == (uid_t) -1 && group == (gid_t) -1) |
778 | goto error; | 788 | goto error; |
779 | 789 | ||
780 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, | 790 | key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, |
@@ -792,27 +802,27 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
792 | 802 | ||
793 | if (!capable(CAP_SYS_ADMIN)) { | 803 | if (!capable(CAP_SYS_ADMIN)) { |
794 | /* only the sysadmin can chown a key to some other UID */ | 804 | /* only the sysadmin can chown a key to some other UID */ |
795 | if (uid != (uid_t) -1 && key->uid != uid) | 805 | if (user != (uid_t) -1 && !uid_eq(key->uid, uid)) |
796 | goto error_put; | 806 | goto error_put; |
797 | 807 | ||
798 | /* only the sysadmin can set the key's GID to a group other | 808 | /* only the sysadmin can set the key's GID to a group other |
799 | * than one of those that the current process subscribes to */ | 809 | * than one of those that the current process subscribes to */ |
800 | if (gid != (gid_t) -1 && gid != key->gid && !in_group_p(gid)) | 810 | if (group != (gid_t) -1 && !gid_eq(gid, key->gid) && !in_group_p(gid)) |
801 | goto error_put; | 811 | goto error_put; |
802 | } | 812 | } |
803 | 813 | ||
804 | /* change the UID */ | 814 | /* change the UID */ |
805 | if (uid != (uid_t) -1 && uid != key->uid) { | 815 | if (user != (uid_t) -1 && !uid_eq(uid, key->uid)) { |
806 | ret = -ENOMEM; | 816 | ret = -ENOMEM; |
807 | newowner = key_user_lookup(uid, current_user_ns()); | 817 | newowner = key_user_lookup(uid); |
808 | if (!newowner) | 818 | if (!newowner) |
809 | goto error_put; | 819 | goto error_put; |
810 | 820 | ||
811 | /* transfer the quota burden to the new user */ | 821 | /* transfer the quota burden to the new user */ |
812 | if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { | 822 | if (test_bit(KEY_FLAG_IN_QUOTA, &key->flags)) { |
813 | unsigned maxkeys = (uid == 0) ? | 823 | unsigned maxkeys = uid_eq(uid, GLOBAL_ROOT_UID) ? |
814 | key_quota_root_maxkeys : key_quota_maxkeys; | 824 | key_quota_root_maxkeys : key_quota_maxkeys; |
815 | unsigned maxbytes = (uid == 0) ? | 825 | unsigned maxbytes = uid_eq(uid, GLOBAL_ROOT_UID) ? |
816 | key_quota_root_maxbytes : key_quota_maxbytes; | 826 | key_quota_root_maxbytes : key_quota_maxbytes; |
817 | 827 | ||
818 | spin_lock(&newowner->lock); | 828 | spin_lock(&newowner->lock); |
@@ -846,7 +856,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) | |||
846 | } | 856 | } |
847 | 857 | ||
848 | /* change the GID */ | 858 | /* change the GID */ |
849 | if (gid != (gid_t) -1) | 859 | if (group != (gid_t) -1) |
850 | key->gid = gid; | 860 | key->gid = gid; |
851 | 861 | ||
852 | ret = 0; | 862 | ret = 0; |
@@ -897,7 +907,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) | |||
897 | down_write(&key->sem); | 907 | down_write(&key->sem); |
898 | 908 | ||
899 | /* if we're not the sysadmin, we can only change a key that we own */ | 909 | /* if we're not the sysadmin, we can only change a key that we own */ |
900 | if (capable(CAP_SYS_ADMIN) || key->uid == current_fsuid()) { | 910 | if (capable(CAP_SYS_ADMIN) || uid_eq(key->uid, current_fsuid())) { |
901 | key->perm = perm; | 911 | key->perm = perm; |
902 | ret = 0; | 912 | ret = 0; |
903 | } | 913 | } |
@@ -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 | */ |
259 | struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, | 259 | struct 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 | ||
64 | use_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 | ||
91 | static struct rb_node *key_serial_next(struct rb_node *n) | 91 | static 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 | ||
110 | static struct key *find_ge_key(key_serial_t id) | 110 | static 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 | ||
273 | static struct rb_node *__key_user_next(struct rb_node *n) | 273 | static 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 | ||
284 | static struct rb_node *key_user_next(struct rb_node *n) | 284 | static 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 | ||
289 | static struct rb_node *key_user_first(struct rb_root *r) | 289 | static 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) | |||
321 | static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) | 321 | static 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 | ||
327 | static void proc_key_users_stop(struct seq_file *p, void *v) | 327 | static 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 | ||
437 | int security_path_chown(struct path *path, uid_t uid, gid_t gid) | 437 | int 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, | |||
551 | out1: | 551 | out1: |
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)); |
556 | out: | 556 | out: |
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. */ |
563 | struct tomoyo_mini_stat { | 563 | struct 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 | */ |
376 | static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid) | 376 | static 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 | ||