Commit 434d42cfd05a7cc452457a81d2029540cba12150
Exists in
master
and in
41 other branches
Merge branch 'next' into for-linus
Showing 25 changed files Side-by-side Diff
- fs/binfmt_flat.c
- include/linux/capability.h
- include/linux/init_task.h
- include/linux/key.h
- include/linux/kmod.h
- kernel/capability.c
- kernel/cred.c
- kernel/kmod.c
- kernel/sysctl.c
- net/dns_resolver/dns_key.c
- security/Kconfig
- security/commoncap.c
- security/keys/internal.h
- security/keys/keyctl.c
- security/keys/keyring.c
- security/keys/proc.c
- security/keys/process_keys.c
- security/keys/request_key.c
- security/keys/request_key_auth.c
- security/keys/user_defined.c
- security/tomoyo/common.c
- security/tomoyo/file.c
- security/tomoyo/memory.c
- security/tomoyo/mount.c
- security/tomoyo/util.c
fs/binfmt_flat.c
... | ... | @@ -820,6 +820,8 @@ |
820 | 820 | int res; |
821 | 821 | char buf[16]; |
822 | 822 | |
823 | + memset(&bprm, 0, sizeof(bprm)); | |
824 | + | |
823 | 825 | /* Create the file name */ |
824 | 826 | sprintf(buf, "/lib/lib%d.so", id); |
825 | 827 | |
... | ... | @@ -834,6 +836,12 @@ |
834 | 836 | res = -ENOMEM; |
835 | 837 | if (!bprm.cred) |
836 | 838 | goto out; |
839 | + | |
840 | + /* We don't really care about recalculating credentials at this point | |
841 | + * as we're past the point of no return and are dealing with shared | |
842 | + * libraries. | |
843 | + */ | |
844 | + bprm.cred_prepared = 1; | |
837 | 845 | |
838 | 846 | res = prepare_binprm(&bprm); |
839 | 847 |
include/linux/capability.h
... | ... | @@ -417,7 +417,6 @@ |
417 | 417 | |
418 | 418 | # define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) |
419 | 419 | # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) |
420 | -# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) | |
421 | 420 | # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ |
422 | 421 | | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ |
423 | 422 | CAP_FS_MASK_B1 } }) |
424 | 423 | |
... | ... | @@ -427,11 +426,7 @@ |
427 | 426 | |
428 | 427 | #endif /* _KERNEL_CAPABILITY_U32S != 2 */ |
429 | 428 | |
430 | -#define CAP_INIT_INH_SET CAP_EMPTY_SET | |
431 | - | |
432 | 429 | # define cap_clear(c) do { (c) = __cap_empty_set; } while (0) |
433 | -# define cap_set_full(c) do { (c) = __cap_full_set; } while (0) | |
434 | -# define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0) | |
435 | 430 | |
436 | 431 | #define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) |
437 | 432 | #define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag)) |
include/linux/init_task.h
... | ... | @@ -83,13 +83,6 @@ |
83 | 83 | #define INIT_IDS |
84 | 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 | 86 | #ifdef CONFIG_RCU_BOOST |
94 | 87 | #define INIT_TASK_RCU_BOOST() \ |
95 | 88 | .rcu_boost_mutex = NULL, |
include/linux/key.h
... | ... | @@ -276,6 +276,19 @@ |
276 | 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 | + */ | |
286 | +static 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 | 292 | #define rcu_dereference_key(KEY) \ |
280 | 293 | (rcu_dereference_protected((KEY)->payload.rcudata, \ |
281 | 294 | rwsem_is_locked(&((struct key *)(KEY))->sem))) |
include/linux/kmod.h
... | ... | @@ -24,6 +24,7 @@ |
24 | 24 | #include <linux/errno.h> |
25 | 25 | #include <linux/compiler.h> |
26 | 26 | #include <linux/workqueue.h> |
27 | +#include <linux/sysctl.h> | |
27 | 28 | |
28 | 29 | #define KMOD_PATH_LEN 256 |
29 | 30 | |
... | ... | @@ -108,6 +109,8 @@ |
108 | 109 | return call_usermodehelper_fns(path, argv, envp, wait, |
109 | 110 | NULL, NULL, NULL); |
110 | 111 | } |
112 | + | |
113 | +extern struct ctl_table usermodehelper_table[]; | |
111 | 114 | |
112 | 115 | extern void usermodehelper_init(void); |
113 | 116 |
kernel/capability.c
... | ... | @@ -22,12 +22,8 @@ |
22 | 22 | */ |
23 | 23 | |
24 | 24 | const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET; |
25 | -const kernel_cap_t __cap_full_set = CAP_FULL_SET; | |
26 | -const kernel_cap_t __cap_init_eff_set = CAP_INIT_EFF_SET; | |
27 | 25 | |
28 | 26 | EXPORT_SYMBOL(__cap_empty_set); |
29 | -EXPORT_SYMBOL(__cap_full_set); | |
30 | -EXPORT_SYMBOL(__cap_init_eff_set); | |
31 | 27 | |
32 | 28 | int file_caps_enabled = 1; |
33 | 29 |
kernel/cred.c
... | ... | @@ -49,10 +49,10 @@ |
49 | 49 | .magic = CRED_MAGIC, |
50 | 50 | #endif |
51 | 51 | .securebits = SECUREBITS_DEFAULT, |
52 | - .cap_inheritable = CAP_INIT_INH_SET, | |
52 | + .cap_inheritable = CAP_EMPTY_SET, | |
53 | 53 | .cap_permitted = CAP_FULL_SET, |
54 | - .cap_effective = CAP_INIT_EFF_SET, | |
55 | - .cap_bset = CAP_INIT_BSET, | |
54 | + .cap_effective = CAP_FULL_SET, | |
55 | + .cap_bset = CAP_FULL_SET, | |
56 | 56 | .user = INIT_USER, |
57 | 57 | .user_ns = &init_user_ns, |
58 | 58 | .group_info = &init_groups, |
kernel/kmod.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <linux/kmod.h> |
26 | 26 | #include <linux/slab.h> |
27 | 27 | #include <linux/completion.h> |
28 | +#include <linux/cred.h> | |
28 | 29 | #include <linux/file.h> |
29 | 30 | #include <linux/fdtable.h> |
30 | 31 | #include <linux/workqueue.h> |
... | ... | @@ -43,6 +44,13 @@ |
43 | 44 | |
44 | 45 | static struct workqueue_struct *khelper_wq; |
45 | 46 | |
47 | +#define CAP_BSET (void *)1 | |
48 | +#define CAP_PI (void *)2 | |
49 | + | |
50 | +static kernel_cap_t usermodehelper_bset = CAP_FULL_SET; | |
51 | +static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET; | |
52 | +static DEFINE_SPINLOCK(umh_sysctl_lock); | |
53 | + | |
46 | 54 | #ifdef CONFIG_MODULES |
47 | 55 | |
48 | 56 | /* |
... | ... | @@ -132,6 +140,7 @@ |
132 | 140 | static int ____call_usermodehelper(void *data) |
133 | 141 | { |
134 | 142 | struct subprocess_info *sub_info = data; |
143 | + struct cred *new; | |
135 | 144 | int retval; |
136 | 145 | |
137 | 146 | spin_lock_irq(¤t->sighand->siglock); |
... | ... | @@ -153,6 +162,19 @@ |
153 | 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 | 178 | retval = kernel_execve(sub_info->path, |
157 | 179 | (const char *const *)sub_info->argv, |
158 | 180 | (const char *const *)sub_info->envp); |
... | ... | @@ -419,6 +441,84 @@ |
419 | 441 | return retval; |
420 | 442 | } |
421 | 443 | EXPORT_SYMBOL(call_usermodehelper_exec); |
444 | + | |
445 | +static int proc_cap_handler(struct ctl_table *table, int write, | |
446 | + void __user *buffer, size_t *lenp, loff_t *ppos) | |
447 | +{ | |
448 | + struct ctl_table t; | |
449 | + unsigned long cap_array[_KERNEL_CAPABILITY_U32S]; | |
450 | + kernel_cap_t new_cap; | |
451 | + int err, i; | |
452 | + | |
453 | + if (write && (!capable(CAP_SETPCAP) || | |
454 | + !capable(CAP_SYS_MODULE))) | |
455 | + return -EPERM; | |
456 | + | |
457 | + /* | |
458 | + * convert from the global kernel_cap_t to the ulong array to print to | |
459 | + * userspace if this is a read. | |
460 | + */ | |
461 | + spin_lock(&umh_sysctl_lock); | |
462 | + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) { | |
463 | + if (table->data == CAP_BSET) | |
464 | + cap_array[i] = usermodehelper_bset.cap[i]; | |
465 | + else if (table->data == CAP_PI) | |
466 | + cap_array[i] = usermodehelper_inheritable.cap[i]; | |
467 | + else | |
468 | + BUG(); | |
469 | + } | |
470 | + spin_unlock(&umh_sysctl_lock); | |
471 | + | |
472 | + t = *table; | |
473 | + t.data = &cap_array; | |
474 | + | |
475 | + /* | |
476 | + * actually read or write and array of ulongs from userspace. Remember | |
477 | + * these are least significant 32 bits first | |
478 | + */ | |
479 | + err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos); | |
480 | + if (err < 0) | |
481 | + return err; | |
482 | + | |
483 | + /* | |
484 | + * convert from the sysctl array of ulongs to the kernel_cap_t | |
485 | + * internal representation | |
486 | + */ | |
487 | + for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) | |
488 | + new_cap.cap[i] = cap_array[i]; | |
489 | + | |
490 | + /* | |
491 | + * Drop everything not in the new_cap (but don't add things) | |
492 | + */ | |
493 | + spin_lock(&umh_sysctl_lock); | |
494 | + if (write) { | |
495 | + if (table->data == CAP_BSET) | |
496 | + usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap); | |
497 | + if (table->data == CAP_PI) | |
498 | + usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap); | |
499 | + } | |
500 | + spin_unlock(&umh_sysctl_lock); | |
501 | + | |
502 | + return 0; | |
503 | +} | |
504 | + | |
505 | +struct ctl_table usermodehelper_table[] = { | |
506 | + { | |
507 | + .procname = "bset", | |
508 | + .data = CAP_BSET, | |
509 | + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), | |
510 | + .mode = 0600, | |
511 | + .proc_handler = proc_cap_handler, | |
512 | + }, | |
513 | + { | |
514 | + .procname = "inheritable", | |
515 | + .data = CAP_PI, | |
516 | + .maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long), | |
517 | + .mode = 0600, | |
518 | + .proc_handler = proc_cap_handler, | |
519 | + }, | |
520 | + { } | |
521 | +}; | |
422 | 522 | |
423 | 523 | void __init usermodehelper_init(void) |
424 | 524 | { |
kernel/sysctl.c
... | ... | @@ -56,6 +56,7 @@ |
56 | 56 | #include <linux/kprobes.h> |
57 | 57 | #include <linux/pipe_fs_i.h> |
58 | 58 | #include <linux/oom.h> |
59 | +#include <linux/kmod.h> | |
59 | 60 | |
60 | 61 | #include <asm/uaccess.h> |
61 | 62 | #include <asm/processor.h> |
... | ... | @@ -614,6 +615,11 @@ |
614 | 615 | .procname = "random", |
615 | 616 | .mode = 0555, |
616 | 617 | .child = random_table, |
618 | + }, | |
619 | + { | |
620 | + .procname = "usermodehelper", | |
621 | + .mode = 0555, | |
622 | + .child = usermodehelper_table, | |
617 | 623 | }, |
618 | 624 | { |
619 | 625 | .procname = "overflowuid", |
net/dns_resolver/dns_key.c
... | ... | @@ -212,10 +212,12 @@ |
212 | 212 | int err = key->type_data.x[0]; |
213 | 213 | |
214 | 214 | seq_puts(m, key->description); |
215 | - if (err) | |
216 | - seq_printf(m, ": %d", err); | |
217 | - else | |
218 | - seq_printf(m, ": %u", key->datalen); | |
215 | + if (key_is_instantiated(key)) { | |
216 | + if (err) | |
217 | + seq_printf(m, ": %d", err); | |
218 | + else | |
219 | + seq_printf(m, ": %u", key->datalen); | |
220 | + } | |
219 | 221 | } |
220 | 222 | |
221 | 223 | /* |
security/Kconfig
... | ... | @@ -167,6 +167,7 @@ |
167 | 167 | config LSM_MMAP_MIN_ADDR |
168 | 168 | int "Low address space for LSM to protect from user allocation" |
169 | 169 | depends on SECURITY && SECURITY_SELINUX |
170 | + default 32768 if ARM | |
170 | 171 | default 65536 |
171 | 172 | help |
172 | 173 | This is the portion of low virtual memory which should be protected |
security/commoncap.c
... | ... | @@ -529,15 +529,10 @@ |
529 | 529 | new->suid = new->fsuid = new->euid; |
530 | 530 | new->sgid = new->fsgid = new->egid; |
531 | 531 | |
532 | - /* For init, we want to retain the capabilities set in the initial | |
533 | - * task. Thus we skip the usual capability rules | |
534 | - */ | |
535 | - if (!is_global_init(current)) { | |
536 | - if (effective) | |
537 | - new->cap_effective = new->cap_permitted; | |
538 | - else | |
539 | - cap_clear(new->cap_effective); | |
540 | - } | |
532 | + if (effective) | |
533 | + new->cap_effective = new->cap_permitted; | |
534 | + else | |
535 | + cap_clear(new->cap_effective); | |
541 | 536 | bprm->cap_effective = effective; |
542 | 537 | |
543 | 538 | /* |
security/keys/internal.h
... | ... | @@ -109,11 +109,13 @@ |
109 | 109 | const struct cred *cred, |
110 | 110 | struct key_type *type, |
111 | 111 | const void *description, |
112 | - key_match_func_t match); | |
112 | + key_match_func_t match, | |
113 | + bool no_state_check); | |
113 | 114 | |
114 | 115 | extern key_ref_t search_my_process_keyrings(struct key_type *type, |
115 | 116 | const void *description, |
116 | 117 | key_match_func_t match, |
118 | + bool no_state_check, | |
117 | 119 | const struct cred *cred); |
118 | 120 | extern key_ref_t search_process_keyrings(struct key_type *type, |
119 | 121 | const void *description, |
security/keys/keyctl.c
... | ... | @@ -206,8 +206,14 @@ |
206 | 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 | 214 | ret = key->serial; |
210 | 215 | |
216 | +error6: | |
211 | 217 | key_put(key); |
212 | 218 | error5: |
213 | 219 | key_type_put(ktype); |
security/keys/keyring.c
... | ... | @@ -176,13 +176,15 @@ |
176 | 176 | else |
177 | 177 | seq_puts(m, "[anon]"); |
178 | 178 | |
179 | - rcu_read_lock(); | |
180 | - klist = rcu_dereference(keyring->payload.subscriptions); | |
181 | - if (klist) | |
182 | - seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); | |
183 | - else | |
184 | - seq_puts(m, ": empty"); | |
185 | - rcu_read_unlock(); | |
179 | + if (key_is_instantiated(keyring)) { | |
180 | + rcu_read_lock(); | |
181 | + klist = rcu_dereference(keyring->payload.subscriptions); | |
182 | + if (klist) | |
183 | + seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys); | |
184 | + else | |
185 | + seq_puts(m, ": empty"); | |
186 | + rcu_read_unlock(); | |
187 | + } | |
186 | 188 | } |
187 | 189 | |
188 | 190 | /* |
... | ... | @@ -271,6 +273,7 @@ |
271 | 273 | * @type: The type of key to search for. |
272 | 274 | * @description: Parameter for @match. |
273 | 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 | 278 | * Search the supplied keyring tree for a key that matches the criteria given. |
276 | 279 | * The root keyring and any linked keyrings must grant Search permission to the |
... | ... | @@ -303,7 +306,8 @@ |
303 | 306 | const struct cred *cred, |
304 | 307 | struct key_type *type, |
305 | 308 | const void *description, |
306 | - key_match_func_t match) | |
309 | + key_match_func_t match, | |
310 | + bool no_state_check) | |
307 | 311 | { |
308 | 312 | struct { |
309 | 313 | struct keyring_list *keylist; |
... | ... | @@ -345,6 +349,8 @@ |
345 | 349 | kflags = keyring->flags; |
346 | 350 | if (keyring->type == type && match(keyring, description)) { |
347 | 351 | key = keyring; |
352 | + if (no_state_check) | |
353 | + goto found; | |
348 | 354 | |
349 | 355 | /* check it isn't negative and hasn't expired or been |
350 | 356 | * revoked */ |
351 | 357 | |
... | ... | @@ -384,11 +390,13 @@ |
384 | 390 | continue; |
385 | 391 | |
386 | 392 | /* skip revoked keys and expired keys */ |
387 | - if (kflags & (1 << KEY_FLAG_REVOKED)) | |
388 | - continue; | |
393 | + if (!no_state_check) { | |
394 | + if (kflags & (1 << KEY_FLAG_REVOKED)) | |
395 | + continue; | |
389 | 396 | |
390 | - if (key->expiry && now.tv_sec >= key->expiry) | |
391 | - continue; | |
397 | + if (key->expiry && now.tv_sec >= key->expiry) | |
398 | + continue; | |
399 | + } | |
392 | 400 | |
393 | 401 | /* keys that don't match */ |
394 | 402 | if (!match(key, description)) |
... | ... | @@ -399,6 +407,9 @@ |
399 | 407 | cred, KEY_SEARCH) < 0) |
400 | 408 | continue; |
401 | 409 | |
410 | + if (no_state_check) | |
411 | + goto found; | |
412 | + | |
402 | 413 | /* we set a different error code if we pass a negative key */ |
403 | 414 | if (kflags & (1 << KEY_FLAG_NEGATIVE)) { |
404 | 415 | err = key->type_data.reject_error; |
... | ... | @@ -478,7 +489,7 @@ |
478 | 489 | return ERR_PTR(-ENOKEY); |
479 | 490 | |
480 | 491 | return keyring_search_aux(keyring, current->cred, |
481 | - type, description, type->match); | |
492 | + type, description, type->match, false); | |
482 | 493 | } |
483 | 494 | EXPORT_SYMBOL(keyring_search); |
484 | 495 |
security/keys/proc.c
... | ... | @@ -199,7 +199,7 @@ |
199 | 199 | if (key->perm & KEY_POS_VIEW) { |
200 | 200 | skey_ref = search_my_process_keyrings(key->type, key, |
201 | 201 | lookup_user_key_possessed, |
202 | - cred); | |
202 | + true, cred); | |
203 | 203 | if (!IS_ERR(skey_ref)) { |
204 | 204 | key_ref_put(skey_ref); |
205 | 205 | key_ref = make_key_ref(key, 1); |
security/keys/process_keys.c
... | ... | @@ -331,6 +331,7 @@ |
331 | 331 | key_ref_t search_my_process_keyrings(struct key_type *type, |
332 | 332 | const void *description, |
333 | 333 | key_match_func_t match, |
334 | + bool no_state_check, | |
334 | 335 | const struct cred *cred) |
335 | 336 | { |
336 | 337 | key_ref_t key_ref, ret, err; |
... | ... | @@ -350,7 +351,7 @@ |
350 | 351 | if (cred->thread_keyring) { |
351 | 352 | key_ref = keyring_search_aux( |
352 | 353 | make_key_ref(cred->thread_keyring, 1), |
353 | - cred, type, description, match); | |
354 | + cred, type, description, match, no_state_check); | |
354 | 355 | if (!IS_ERR(key_ref)) |
355 | 356 | goto found; |
356 | 357 | |
... | ... | @@ -371,7 +372,7 @@ |
371 | 372 | if (cred->tgcred->process_keyring) { |
372 | 373 | key_ref = keyring_search_aux( |
373 | 374 | make_key_ref(cred->tgcred->process_keyring, 1), |
374 | - cred, type, description, match); | |
375 | + cred, type, description, match, no_state_check); | |
375 | 376 | if (!IS_ERR(key_ref)) |
376 | 377 | goto found; |
377 | 378 | |
... | ... | @@ -395,7 +396,7 @@ |
395 | 396 | make_key_ref(rcu_dereference( |
396 | 397 | cred->tgcred->session_keyring), |
397 | 398 | 1), |
398 | - cred, type, description, match); | |
399 | + cred, type, description, match, no_state_check); | |
399 | 400 | rcu_read_unlock(); |
400 | 401 | |
401 | 402 | if (!IS_ERR(key_ref)) |
... | ... | @@ -417,7 +418,7 @@ |
417 | 418 | else if (cred->user->session_keyring) { |
418 | 419 | key_ref = keyring_search_aux( |
419 | 420 | make_key_ref(cred->user->session_keyring, 1), |
420 | - cred, type, description, match); | |
421 | + cred, type, description, match, no_state_check); | |
421 | 422 | if (!IS_ERR(key_ref)) |
422 | 423 | goto found; |
423 | 424 | |
... | ... | @@ -459,7 +460,8 @@ |
459 | 460 | |
460 | 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 | 465 | if (!IS_ERR(key_ref)) |
464 | 466 | goto found; |
465 | 467 | err = key_ref; |
security/keys/request_key.c
... | ... | @@ -530,8 +530,7 @@ |
530 | 530 | dest_keyring, flags); |
531 | 531 | |
532 | 532 | /* search all the process keyrings for a key */ |
533 | - key_ref = search_process_keyrings(type, description, type->match, | |
534 | - cred); | |
533 | + key_ref = search_process_keyrings(type, description, type->match, cred); | |
535 | 534 | |
536 | 535 | if (!IS_ERR(key_ref)) { |
537 | 536 | key = key_ref_to_ptr(key_ref); |
security/keys/request_key_auth.c
security/keys/user_defined.c
... | ... | @@ -157,8 +157,8 @@ |
157 | 157 | void user_describe(const struct key *key, struct seq_file *m) |
158 | 158 | { |
159 | 159 | seq_puts(m, key->description); |
160 | - | |
161 | - seq_printf(m, ": %u", key->datalen); | |
160 | + if (key_is_instantiated(key)) | |
161 | + seq_printf(m, ": %u", key->datalen); | |
162 | 162 | } |
163 | 163 | |
164 | 164 | EXPORT_SYMBOL_GPL(user_describe); |
security/tomoyo/common.c
... | ... | @@ -108,10 +108,9 @@ |
108 | 108 | head->read_user_buf += len; |
109 | 109 | w += len; |
110 | 110 | } |
111 | - if (*w) { | |
112 | - head->r.w[0] = w; | |
111 | + head->r.w[0] = w; | |
112 | + if (*w) | |
113 | 113 | return false; |
114 | - } | |
115 | 114 | /* Add '\0' for query. */ |
116 | 115 | if (head->poll) { |
117 | 116 | if (!head->read_user_buf_avail || |
... | ... | @@ -459,8 +458,16 @@ |
459 | 458 | if (profile == &tomoyo_default_profile) |
460 | 459 | return -EINVAL; |
461 | 460 | if (!strcmp(data, "COMMENT")) { |
462 | - const struct tomoyo_path_info *old_comment = profile->comment; | |
463 | - profile->comment = tomoyo_get_name(cp); | |
461 | + static DEFINE_SPINLOCK(lock); | |
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 | 471 | tomoyo_put_name(old_comment); |
465 | 472 | return 0; |
466 | 473 | } |
security/tomoyo/file.c
security/tomoyo/memory.c
security/tomoyo/mount.c
security/tomoyo/util.c