aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/capability.h7
-rw-r--r--include/linux/init_task.h7
-rw-r--r--include/linux/key.h13
-rw-r--r--include/linux/kmod.h3
-rw-r--r--kernel/capability.c4
-rw-r--r--kernel/cred.c6
-rw-r--r--kernel/kmod.c100
-rw-r--r--kernel/sysctl.c6
-rw-r--r--net/dns_resolver/dns_key.c10
-rw-r--r--security/Kconfig1
-rw-r--r--security/commoncap.c13
-rw-r--r--security/keys/internal.h4
-rw-r--r--security/keys/keyctl.c6
-rw-r--r--security/keys/keyring.c37
-rw-r--r--security/keys/proc.c2
-rw-r--r--security/keys/process_keys.c12
-rw-r--r--security/keys/request_key.c3
-rw-r--r--security/keys/request_key_auth.c3
-rw-r--r--security/keys/user_defined.c4
-rw-r--r--security/tomoyo/common.c17
-rw-r--r--security/tomoyo/file.c1
-rw-r--r--security/tomoyo/memory.c1
22 files changed, 197 insertions, 63 deletions
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 16ee8b49a200..04fed72809de 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -412,7 +412,6 @@ extern const kernel_cap_t __cap_init_eff_set;
412 412
413# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) 413# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
414# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) 414# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }})
415# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }})
416# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ 415# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \
417 | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ 416 | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
418 CAP_FS_MASK_B1 } }) 417 CAP_FS_MASK_B1 } })
@@ -422,11 +421,7 @@ extern const kernel_cap_t __cap_init_eff_set;
422 421
423#endif /* _KERNEL_CAPABILITY_U32S != 2 */ 422#endif /* _KERNEL_CAPABILITY_U32S != 2 */
424 423
425#define CAP_INIT_INH_SET CAP_EMPTY_SET
426
427# define cap_clear(c) do { (c) = __cap_empty_set; } while (0) 424# define cap_clear(c) do { (c) = __cap_empty_set; } while (0)
428# define cap_set_full(c) do { (c) = __cap_full_set; } while (0)
429# define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0)
430 425
431#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) 426#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag))
432#define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) 427#define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag))
@@ -547,6 +542,8 @@ extern bool capable(int cap);
547extern bool ns_capable(struct user_namespace *ns, int cap); 542extern bool ns_capable(struct user_namespace *ns, int cap);
548extern bool task_ns_capable(struct task_struct *t, int cap); 543extern bool task_ns_capable(struct task_struct *t, int cap);
549 544
545extern const kernel_cap_t __cap_empty_set;
546
550/** 547/**
551 * nsown_capable - Check superior capability to one's own user_ns 548 * nsown_capable - Check superior capability to one's own user_ns
552 * @cap: The capability in question 549 * @cap: The capability in question
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index caa151fbebb7..1f277204de34 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -83,13 +83,6 @@ extern struct group_info init_groups;
83#define INIT_IDS 83#define INIT_IDS
84#endif 84#endif
85 85
86/*
87 * Because of the reduced scope of CAP_SETPCAP when filesystem
88 * capabilities are in effect, it is safe to allow CAP_SETPCAP to
89 * be available in the default configuration.
90 */
91# define CAP_INIT_BSET CAP_FULL_SET
92
93#ifdef CONFIG_RCU_BOOST 86#ifdef CONFIG_RCU_BOOST
94#define INIT_TASK_RCU_BOOST() \ 87#define INIT_TASK_RCU_BOOST() \
95 .rcu_boost_mutex = NULL, 88 .rcu_boost_mutex = NULL,
diff --git a/include/linux/key.h b/include/linux/key.h
index b2bb01719561..ef19b99aff98 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -276,6 +276,19 @@ static inline key_serial_t key_serial(struct key *key)
276 return key ? key->serial : 0; 276 return key ? key->serial : 0;
277} 277}
278 278
279/**
280 * key_is_instantiated - Determine if a key has been positively instantiated
281 * @key: The key to check.
282 *
283 * Return true if the specified key has been positively instantiated, false
284 * otherwise.
285 */
286static inline bool key_is_instantiated(const struct key *key)
287{
288 return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
289 !test_bit(KEY_FLAG_NEGATIVE, &key->flags);
290}
291
279#define rcu_dereference_key(KEY) \ 292#define rcu_dereference_key(KEY) \
280 (rcu_dereference_protected((KEY)->payload.rcudata, \ 293 (rcu_dereference_protected((KEY)->payload.rcudata, \
281 rwsem_is_locked(&((struct key *)(KEY))->sem))) 294 rwsem_is_locked(&((struct key *)(KEY))->sem)))
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 6efd7a78de6a..79bb98d71858 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -24,6 +24,7 @@
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/compiler.h> 25#include <linux/compiler.h>
26#include <linux/workqueue.h> 26#include <linux/workqueue.h>
27#include <linux/sysctl.h>
27 28
28#define KMOD_PATH_LEN 256 29#define KMOD_PATH_LEN 256
29 30
@@ -109,6 +110,8 @@ call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
109 NULL, NULL, NULL); 110 NULL, NULL, NULL);
110} 111}
111 112
113extern struct ctl_table usermodehelper_table[];
114
112extern void usermodehelper_init(void); 115extern void usermodehelper_init(void);
113 116
114extern int usermodehelper_disable(void); 117extern int usermodehelper_disable(void);
diff --git a/kernel/capability.c b/kernel/capability.c
index bf0c734d0c12..14ea4210a530 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -22,12 +22,8 @@
22 */ 22 */
23 23
24const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; 24const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
25const kernel_cap_t __cap_full_set = CAP_FULL_SET;
26const kernel_cap_t __cap_init_eff_set = CAP_INIT_EFF_SET;
27 25
28EXPORT_SYMBOL(__cap_empty_set); 26EXPORT_SYMBOL(__cap_empty_set);
29EXPORT_SYMBOL(__cap_full_set);
30EXPORT_SYMBOL(__cap_init_eff_set);
31 27
32int file_caps_enabled = 1; 28int file_caps_enabled = 1;
33 29
diff --git a/kernel/cred.c b/kernel/cred.c
index 5557b55048df..b982f0863ae9 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -49,10 +49,10 @@ struct cred init_cred = {
49 .magic = CRED_MAGIC, 49 .magic = CRED_MAGIC,
50#endif 50#endif
51 .securebits = SECUREBITS_DEFAULT, 51 .securebits = SECUREBITS_DEFAULT,
52 .cap_inheritable = CAP_INIT_INH_SET, 52 .cap_inheritable = CAP_EMPTY_SET,
53 .cap_permitted = CAP_FULL_SET, 53 .cap_permitted = CAP_FULL_SET,
54 .cap_effective = CAP_INIT_EFF_SET, 54 .cap_effective = CAP_FULL_SET,
55 .cap_bset = CAP_INIT_BSET, 55 .cap_bset = CAP_FULL_SET,
56 .user = INIT_USER, 56 .user = INIT_USER,
57 .group_info = &init_groups, 57 .group_info = &init_groups,
58#ifdef CONFIG_KEYS 58#ifdef CONFIG_KEYS
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 9cd0591c96a2..06fdea2819b6 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -25,6 +25,7 @@
25#include <linux/kmod.h> 25#include <linux/kmod.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/completion.h> 27#include <linux/completion.h>
28#include <linux/cred.h>
28#include <linux/file.h> 29#include <linux/file.h>
29#include <linux/fdtable.h> 30#include <linux/fdtable.h>
30#include <linux/workqueue.h> 31#include <linux/workqueue.h>
@@ -43,6 +44,13 @@ extern int max_threads;
43 44
44static struct workqueue_struct *khelper_wq; 45static struct workqueue_struct *khelper_wq;
45 46
47#define CAP_BSET (void *)1
48#define CAP_PI (void *)2
49
50static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
51static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
52static DEFINE_SPINLOCK(umh_sysctl_lock);
53
46#ifdef CONFIG_MODULES 54#ifdef CONFIG_MODULES
47 55
48/* 56/*
@@ -132,6 +140,7 @@ EXPORT_SYMBOL(__request_module);
132static int ____call_usermodehelper(void *data) 140static int ____call_usermodehelper(void *data)
133{ 141{
134 struct subprocess_info *sub_info = data; 142 struct subprocess_info *sub_info = data;
143 struct cred *new;
135 int retval; 144 int retval;
136 145
137 spin_lock_irq(&current->sighand->siglock); 146 spin_lock_irq(&current->sighand->siglock);
@@ -153,6 +162,19 @@ static int ____call_usermodehelper(void *data)
153 goto fail; 162 goto fail;
154 } 163 }
155 164
165 retval = -ENOMEM;
166 new = prepare_kernel_cred(current);
167 if (!new)
168 goto fail;
169
170 spin_lock(&umh_sysctl_lock);
171 new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset);
172 new->cap_inheritable = cap_intersect(usermodehelper_inheritable,
173 new->cap_inheritable);
174 spin_unlock(&umh_sysctl_lock);
175
176 commit_creds(new);
177
156 retval = kernel_execve(sub_info->path, 178 retval = kernel_execve(sub_info->path,
157 (const char *const *)sub_info->argv, 179 (const char *const *)sub_info->argv,
158 (const char *const *)sub_info->envp); 180 (const char *const *)sub_info->envp);
@@ -418,6 +440,84 @@ unlock:
418} 440}
419EXPORT_SYMBOL(call_usermodehelper_exec); 441EXPORT_SYMBOL(call_usermodehelper_exec);
420 442
443static int proc_cap_handler(struct ctl_table *table, int write,
444 void __user *buffer, size_t *lenp, loff_t *ppos)
445{
446 struct ctl_table t;
447 unsigned long cap_array[_KERNEL_CAPABILITY_U32S];
448 kernel_cap_t new_cap;
449 int err, i;
450
451 if (write && (!capable(CAP_SETPCAP) ||
452 !capable(CAP_SYS_MODULE)))
453 return -EPERM;
454
455 /*
456 * convert from the global kernel_cap_t to the ulong array to print to
457 * userspace if this is a read.
458 */
459 spin_lock(&umh_sysctl_lock);
460 for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) {
461 if (table->data == CAP_BSET)
462 cap_array[i] = usermodehelper_bset.cap[i];
463 else if (table->data == CAP_PI)
464 cap_array[i] = usermodehelper_inheritable.cap[i];
465 else
466 BUG();
467 }
468 spin_unlock(&umh_sysctl_lock);
469
470 t = *table;
471 t.data = &cap_array;
472
473 /*
474 * actually read or write and array of ulongs from userspace. Remember
475 * these are least significant 32 bits first
476 */
477 err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
478 if (err < 0)
479 return err;
480
481 /*
482 * convert from the sysctl array of ulongs to the kernel_cap_t
483 * internal representation
484 */
485 for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++)
486 new_cap.cap[i] = cap_array[i];
487
488 /*
489 * Drop everything not in the new_cap (but don't add things)
490 */
491 spin_lock(&umh_sysctl_lock);
492 if (write) {
493 if (table->data == CAP_BSET)
494 usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap);
495 if (table->data == CAP_PI)
496 usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap);
497 }
498 spin_unlock(&umh_sysctl_lock);
499
500 return 0;
501}
502
503struct ctl_table usermodehelper_table[] = {
504 {
505 .procname = "bset",
506 .data = CAP_BSET,
507 .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long),
508 .mode = 0600,
509 .proc_handler = proc_cap_handler,
510 },
511 {
512 .procname = "inheritable",
513 .data = CAP_PI,
514 .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long),
515 .mode = 0600,
516 .proc_handler = proc_cap_handler,
517 },
518 { }
519};
520
421void __init usermodehelper_init(void) 521void __init usermodehelper_init(void)
422{ 522{
423 khelper_wq = create_singlethread_workqueue("khelper"); 523 khelper_wq = create_singlethread_workqueue("khelper");
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c0bb32414b17..965134bed6cd 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -56,6 +56,7 @@
56#include <linux/kprobes.h> 56#include <linux/kprobes.h>
57#include <linux/pipe_fs_i.h> 57#include <linux/pipe_fs_i.h>
58#include <linux/oom.h> 58#include <linux/oom.h>
59#include <linux/kmod.h>
59 60
60#include <asm/uaccess.h> 61#include <asm/uaccess.h>
61#include <asm/processor.h> 62#include <asm/processor.h>
@@ -616,6 +617,11 @@ static struct ctl_table kern_table[] = {
616 .child = random_table, 617 .child = random_table,
617 }, 618 },
618 { 619 {
620 .procname = "usermodehelper",
621 .mode = 0555,
622 .child = usermodehelper_table,
623 },
624 {
619 .procname = "overflowuid", 625 .procname = "overflowuid",
620 .data = &overflowuid, 626 .data = &overflowuid,
621 .maxlen = sizeof(int), 627 .maxlen = sizeof(int),
diff --git a/net/dns_resolver/dns_key.c b/net/dns_resolver/dns_key.c
index cfa7a5e1c5c9..fa000d26dc60 100644
--- a/net/dns_resolver/dns_key.c
+++ b/net/dns_resolver/dns_key.c
@@ -212,10 +212,12 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m)
212 int err = key->type_data.x[0]; 212 int err = key->type_data.x[0];
213 213
214 seq_puts(m, key->description); 214 seq_puts(m, key->description);
215 if (err) 215 if (key_is_instantiated(key)) {
216 seq_printf(m, ": %d", err); 216 if (err)
217 else 217 seq_printf(m, ": %d", err);
218 seq_printf(m, ": %u", key->datalen); 218 else
219 seq_printf(m, ": %u", key->datalen);
220 }
219} 221}
220 222
221/* 223/*
diff --git a/security/Kconfig b/security/Kconfig
index 95accd442d55..e0f08b52e4ab 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -167,6 +167,7 @@ config INTEL_TXT
167config LSM_MMAP_MIN_ADDR 167config LSM_MMAP_MIN_ADDR
168 int "Low address space for LSM to protect from user allocation" 168 int "Low address space for LSM to protect from user allocation"
169 depends on SECURITY && SECURITY_SELINUX 169 depends on SECURITY && SECURITY_SELINUX
170 default 32768 if ARM
170 default 65536 171 default 65536
171 help 172 help
172 This is the portion of low virtual memory which should be protected 173 This is the portion of low virtual memory which should be protected
diff --git a/security/commoncap.c b/security/commoncap.c
index f20e984ccfb4..a93b3b733079 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -529,15 +529,10 @@ skip:
529 new->suid = new->fsuid = new->euid; 529 new->suid = new->fsuid = new->euid;
530 new->sgid = new->fsgid = new->egid; 530 new->sgid = new->fsgid = new->egid;
531 531
532 /* For init, we want to retain the capabilities set in the initial 532 if (effective)
533 * task. Thus we skip the usual capability rules 533 new->cap_effective = new->cap_permitted;
534 */ 534 else
535 if (!is_global_init(current)) { 535 cap_clear(new->cap_effective);
536 if (effective)
537 new->cap_effective = new->cap_permitted;
538 else
539 cap_clear(new->cap_effective);
540 }
541 bprm->cap_effective = effective; 536 bprm->cap_effective = effective;
542 537
543 /* 538 /*
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 07a025f81902..f375152a2500 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -109,11 +109,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
109 const struct cred *cred, 109 const struct cred *cred,
110 struct key_type *type, 110 struct key_type *type,
111 const void *description, 111 const void *description,
112 key_match_func_t match); 112 key_match_func_t match,
113 bool no_state_check);
113 114
114extern key_ref_t search_my_process_keyrings(struct key_type *type, 115extern key_ref_t search_my_process_keyrings(struct key_type *type,
115 const void *description, 116 const void *description,
116 key_match_func_t match, 117 key_match_func_t match,
118 bool no_state_check,
117 const struct cred *cred); 119 const struct cred *cred);
118extern key_ref_t search_process_keyrings(struct key_type *type, 120extern key_ref_t search_process_keyrings(struct key_type *type,
119 const void *description, 121 const void *description,
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 427fddcaeb19..eca51918c951 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -206,8 +206,14 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
206 goto error5; 206 goto error5;
207 } 207 }
208 208
209 /* wait for the key to finish being constructed */
210 ret = wait_for_key_construction(key, 1);
211 if (ret < 0)
212 goto error6;
213
209 ret = key->serial; 214 ret = key->serial;
210 215
216error6:
211 key_put(key); 217 key_put(key);
212error5: 218error5:
213 key_type_put(ktype); 219 key_type_put(ktype);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index cdd2f3f88c88..a06ffab38568 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -176,13 +176,15 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
176 else 176 else
177 seq_puts(m, "[anon]"); 177 seq_puts(m, "[anon]");
178 178
179 rcu_read_lock(); 179 if (key_is_instantiated(keyring)) {
180 klist = rcu_dereference(keyring->payload.subscriptions); 180 rcu_read_lock();
181 if (klist) 181 klist = rcu_dereference(keyring->payload.subscriptions);
182 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); 182 if (klist)
183 else 183 seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
184 seq_puts(m, ": empty"); 184 else
185 rcu_read_unlock(); 185 seq_puts(m, ": empty");
186 rcu_read_unlock();
187 }
186} 188}
187 189
188/* 190/*
@@ -271,6 +273,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
271 * @type: The type of key to search for. 273 * @type: The type of key to search for.
272 * @description: Parameter for @match. 274 * @description: Parameter for @match.
273 * @match: Function to rule on whether or not a key is the one required. 275 * @match: Function to rule on whether or not a key is the one required.
276 * @no_state_check: Don't check if a matching key is bad
274 * 277 *
275 * Search the supplied keyring tree for a key that matches the criteria given. 278 * Search the supplied keyring tree for a key that matches the criteria given.
276 * The root keyring and any linked keyrings must grant Search permission to the 279 * The root keyring and any linked keyrings must grant Search permission to the
@@ -303,7 +306,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
303 const struct cred *cred, 306 const struct cred *cred,
304 struct key_type *type, 307 struct key_type *type,
305 const void *description, 308 const void *description,
306 key_match_func_t match) 309 key_match_func_t match,
310 bool no_state_check)
307{ 311{
308 struct { 312 struct {
309 struct keyring_list *keylist; 313 struct keyring_list *keylist;
@@ -345,6 +349,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
345 kflags = keyring->flags; 349 kflags = keyring->flags;
346 if (keyring->type == type && match(keyring, description)) { 350 if (keyring->type == type && match(keyring, description)) {
347 key = keyring; 351 key = keyring;
352 if (no_state_check)
353 goto found;
348 354
349 /* check it isn't negative and hasn't expired or been 355 /* check it isn't negative and hasn't expired or been
350 * revoked */ 356 * revoked */
@@ -384,11 +390,13 @@ descend:
384 continue; 390 continue;
385 391
386 /* skip revoked keys and expired keys */ 392 /* skip revoked keys and expired keys */
387 if (kflags & (1 << KEY_FLAG_REVOKED)) 393 if (!no_state_check) {
388 continue; 394 if (kflags & (1 << KEY_FLAG_REVOKED))
395 continue;
389 396
390 if (key->expiry && now.tv_sec >= key->expiry) 397 if (key->expiry && now.tv_sec >= key->expiry)
391 continue; 398 continue;
399 }
392 400
393 /* keys that don't match */ 401 /* keys that don't match */
394 if (!match(key, description)) 402 if (!match(key, description))
@@ -399,6 +407,9 @@ descend:
399 cred, KEY_SEARCH) < 0) 407 cred, KEY_SEARCH) < 0)
400 continue; 408 continue;
401 409
410 if (no_state_check)
411 goto found;
412
402 /* we set a different error code if we pass a negative key */ 413 /* we set a different error code if we pass a negative key */
403 if (kflags & (1 << KEY_FLAG_NEGATIVE)) { 414 if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
404 err = key->type_data.reject_error; 415 err = key->type_data.reject_error;
@@ -478,7 +489,7 @@ key_ref_t keyring_search(key_ref_t keyring,
478 return ERR_PTR(-ENOKEY); 489 return ERR_PTR(-ENOKEY);
479 490
480 return keyring_search_aux(keyring, current->cred, 491 return keyring_search_aux(keyring, current->cred,
481 type, description, type->match); 492 type, description, type->match, false);
482} 493}
483EXPORT_SYMBOL(keyring_search); 494EXPORT_SYMBOL(keyring_search);
484 495
diff --git a/security/keys/proc.c b/security/keys/proc.c
index 525cf8a29cdd..49bbc97943ad 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -199,7 +199,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
199 if (key->perm & KEY_POS_VIEW) { 199 if (key->perm & KEY_POS_VIEW) {
200 skey_ref = search_my_process_keyrings(key->type, key, 200 skey_ref = search_my_process_keyrings(key->type, key,
201 lookup_user_key_possessed, 201 lookup_user_key_possessed,
202 cred); 202 true, cred);
203 if (!IS_ERR(skey_ref)) { 203 if (!IS_ERR(skey_ref)) {
204 key_ref_put(skey_ref); 204 key_ref_put(skey_ref);
205 key_ref = make_key_ref(key, 1); 205 key_ref = make_key_ref(key, 1);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 930634e45149..6c0480db8885 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -331,6 +331,7 @@ void key_fsgid_changed(struct task_struct *tsk)
331key_ref_t search_my_process_keyrings(struct key_type *type, 331key_ref_t search_my_process_keyrings(struct key_type *type,
332 const void *description, 332 const void *description,
333 key_match_func_t match, 333 key_match_func_t match,
334 bool no_state_check,
334 const struct cred *cred) 335 const struct cred *cred)
335{ 336{
336 key_ref_t key_ref, ret, err; 337 key_ref_t key_ref, ret, err;
@@ -350,7 +351,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
350 if (cred->thread_keyring) { 351 if (cred->thread_keyring) {
351 key_ref = keyring_search_aux( 352 key_ref = keyring_search_aux(
352 make_key_ref(cred->thread_keyring, 1), 353 make_key_ref(cred->thread_keyring, 1),
353 cred, type, description, match); 354 cred, type, description, match, no_state_check);
354 if (!IS_ERR(key_ref)) 355 if (!IS_ERR(key_ref))
355 goto found; 356 goto found;
356 357
@@ -371,7 +372,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
371 if (cred->tgcred->process_keyring) { 372 if (cred->tgcred->process_keyring) {
372 key_ref = keyring_search_aux( 373 key_ref = keyring_search_aux(
373 make_key_ref(cred->tgcred->process_keyring, 1), 374 make_key_ref(cred->tgcred->process_keyring, 1),
374 cred, type, description, match); 375 cred, type, description, match, no_state_check);
375 if (!IS_ERR(key_ref)) 376 if (!IS_ERR(key_ref))
376 goto found; 377 goto found;
377 378
@@ -395,7 +396,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
395 make_key_ref(rcu_dereference( 396 make_key_ref(rcu_dereference(
396 cred->tgcred->session_keyring), 397 cred->tgcred->session_keyring),
397 1), 398 1),
398 cred, type, description, match); 399 cred, type, description, match, no_state_check);
399 rcu_read_unlock(); 400 rcu_read_unlock();
400 401
401 if (!IS_ERR(key_ref)) 402 if (!IS_ERR(key_ref))
@@ -417,7 +418,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
417 else if (cred->user->session_keyring) { 418 else if (cred->user->session_keyring) {
418 key_ref = keyring_search_aux( 419 key_ref = keyring_search_aux(
419 make_key_ref(cred->user->session_keyring, 1), 420 make_key_ref(cred->user->session_keyring, 1),
420 cred, type, description, match); 421 cred, type, description, match, no_state_check);
421 if (!IS_ERR(key_ref)) 422 if (!IS_ERR(key_ref))
422 goto found; 423 goto found;
423 424
@@ -459,7 +460,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
459 460
460 might_sleep(); 461 might_sleep();
461 462
462 key_ref = search_my_process_keyrings(type, description, match, cred); 463 key_ref = search_my_process_keyrings(type, description, match,
464 false, cred);
463 if (!IS_ERR(key_ref)) 465 if (!IS_ERR(key_ref))
464 goto found; 466 goto found;
465 err = key_ref; 467 err = key_ref;
diff --git a/security/keys/request_key.c b/security/keys/request_key.c
index df3c0417ee40..b18a71745901 100644
--- a/security/keys/request_key.c
+++ b/security/keys/request_key.c
@@ -530,8 +530,7 @@ struct key *request_key_and_link(struct key_type *type,
530 dest_keyring, flags); 530 dest_keyring, flags);
531 531
532 /* search all the process keyrings for a key */ 532 /* search all the process keyrings for a key */
533 key_ref = search_process_keyrings(type, description, type->match, 533 key_ref = search_process_keyrings(type, description, type->match, cred);
534 cred);
535 534
536 if (!IS_ERR(key_ref)) { 535 if (!IS_ERR(key_ref)) {
537 key = key_ref_to_ptr(key_ref); 536 key = key_ref_to_ptr(key_ref);
diff --git a/security/keys/request_key_auth.c b/security/keys/request_key_auth.c
index 68164031a74e..f6337c9082eb 100644
--- a/security/keys/request_key_auth.c
+++ b/security/keys/request_key_auth.c
@@ -59,7 +59,8 @@ static void request_key_auth_describe(const struct key *key,
59 59
60 seq_puts(m, "key:"); 60 seq_puts(m, "key:");
61 seq_puts(m, key->description); 61 seq_puts(m, key->description);
62 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len); 62 if (key_is_instantiated(key))
63 seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
63} 64}
64 65
65/* 66/*
diff --git a/security/keys/user_defined.c b/security/keys/user_defined.c
index c6ca8662a468..63bb1aaffc0a 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -169,8 +169,8 @@ EXPORT_SYMBOL_GPL(user_destroy);
169void user_describe(const struct key *key, struct seq_file *m) 169void user_describe(const struct key *key, struct seq_file *m)
170{ 170{
171 seq_puts(m, key->description); 171 seq_puts(m, key->description);
172 172 if (key_is_instantiated(key))
173 seq_printf(m, ": %u", key->datalen); 173 seq_printf(m, ": %u", key->datalen);
174} 174}
175 175
176EXPORT_SYMBOL_GPL(user_describe); 176EXPORT_SYMBOL_GPL(user_describe);
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 7556315c1978..a0d09e56874b 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -108,10 +108,9 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head)
108 head->read_user_buf += len; 108 head->read_user_buf += len;
109 w += len; 109 w += len;
110 } 110 }
111 if (*w) { 111 head->r.w[0] = w;
112 head->r.w[0] = w; 112 if (*w)
113 return false; 113 return false;
114 }
115 /* Add '\0' for query. */ 114 /* Add '\0' for query. */
116 if (head->poll) { 115 if (head->poll) {
117 if (!head->read_user_buf_avail || 116 if (!head->read_user_buf_avail ||
@@ -459,8 +458,16 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
459 if (profile == &tomoyo_default_profile) 458 if (profile == &tomoyo_default_profile)
460 return -EINVAL; 459 return -EINVAL;
461 if (!strcmp(data, "COMMENT")) { 460 if (!strcmp(data, "COMMENT")) {
462 const struct tomoyo_path_info *old_comment = profile->comment; 461 static DEFINE_SPINLOCK(lock);
463 profile->comment = tomoyo_get_name(cp); 462 const struct tomoyo_path_info *new_comment
463 = tomoyo_get_name(cp);
464 const struct tomoyo_path_info *old_comment;
465 if (!new_comment)
466 return -ENOMEM;
467 spin_lock(&lock);
468 old_comment = profile->comment;
469 profile->comment = new_comment;
470 spin_unlock(&lock);
464 tomoyo_put_name(old_comment); 471 tomoyo_put_name(old_comment);
465 return 0; 472 return 0;
466 } 473 }
diff --git a/security/tomoyo/file.c b/security/tomoyo/file.c
index cb09f1fce910..d64e8ecb6fb3 100644
--- a/security/tomoyo/file.c
+++ b/security/tomoyo/file.c
@@ -1011,7 +1011,6 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
1011 break; 1011 break;
1012 case TOMOYO_TYPE_RMDIR: 1012 case TOMOYO_TYPE_RMDIR:
1013 case TOMOYO_TYPE_CHROOT: 1013 case TOMOYO_TYPE_CHROOT:
1014 case TOMOYO_TYPE_UMOUNT:
1015 tomoyo_add_slash(&buf); 1014 tomoyo_add_slash(&buf);
1016 break; 1015 break;
1017 } 1016 }
diff --git a/security/tomoyo/memory.c b/security/tomoyo/memory.c
index 297612669c74..42a7b1ba8cbf 100644
--- a/security/tomoyo/memory.c
+++ b/security/tomoyo/memory.c
@@ -75,6 +75,7 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
75 memset(data, 0, size); 75 memset(data, 0, size);
76 return ptr; 76 return ptr;
77 } 77 }
78 kfree(ptr);
78 return NULL; 79 return NULL;
79} 80}
80 81