aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 16:38:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-24 16:38:19 -0400
commitb0ca118dbacbc6c35e15f216e25e95cca7aedf5b (patch)
tree6c61c91ff0174c8774d4010b892ecf0bed560910
parent2bb732cdb48d271ff7a910260ffb851fb4bc8a28 (diff)
parentb7b57551bbda1390959207f79f2038aa7adb72ae (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6: (43 commits) TOMOYO: Fix wrong domainname validation. SELINUX: add /sys/fs/selinux mount point to put selinuxfs CRED: Fix load_flat_shared_library() to initialise bprm correctly SELinux: introduce path_has_perm flex_array: allow 0 length elements flex_arrays: allow zero length flex arrays flex_array: flex_array_prealloc takes a number of elements, not an end SELinux: pass last path component in may_create SELinux: put name based create rules in a hashtable SELinux: generic hashtab entry counter SELinux: calculate and print hashtab stats with a generic function SELinux: skip filename trans rules if ttype does not match parent dir SELinux: rename filename_compute_type argument to *type instead of *con SELinux: fix comment to state filename_compute_type takes an objname not a qstr SMACK: smack_file_lock can use the struct path LSM: separate LSM_AUDIT_DATA_DENTRY from LSM_AUDIT_DATA_PATH LSM: split LSM_AUDIT_DATA_FS into _PATH and _INODE SELINUX: Make selinux cache VFS RCU walks safe SECURITY: Move exec_permission RCU checks into security modules SELinux: security_read_policy should take a size_t not ssize_t ...
-rw-r--r--MAINTAINERS3
-rw-r--r--fs/binfmt_flat.c8
-rw-r--r--include/linux/capability.h5
-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--include/linux/lsm_audit.h11
-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--lib/flex_array.c26
-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/lsm_audit.c59
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c92
-rw-r--r--security/selinux/include/security.h9
-rw-r--r--security/selinux/netnode.c1
-rw-r--r--security/selinux/selinuxfs.c28
-rw-r--r--security/selinux/ss/policydb.c244
-rw-r--r--security/selinux/ss/policydb.h12
-rw-r--r--security/selinux/ss/services.c72
-rw-r--r--security/smack/smack.h11
-rw-r--r--security/smack/smack_lsm.c48
-rw-r--r--security/tomoyo/common.c17
-rw-r--r--security/tomoyo/file.c1
-rw-r--r--security/tomoyo/memory.c1
-rw-r--r--security/tomoyo/mount.c1
-rw-r--r--security/tomoyo/util.c2
39 files changed, 603 insertions, 284 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index b64825ddaf32..98c324b07a16 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5592,10 +5592,11 @@ M: James Morris <jmorris@namei.org>
5592M: Eric Paris <eparis@parisplace.org> 5592M: Eric Paris <eparis@parisplace.org>
5593L: selinux@tycho.nsa.gov (subscribers-only, general discussion) 5593L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
5594W: http://selinuxproject.org 5594W: http://selinuxproject.org
5595T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/security-testing-2.6.git 5595T: git git://git.infradead.org/users/eparis/selinux.git
5596S: Supported 5596S: Supported
5597F: include/linux/selinux* 5597F: include/linux/selinux*
5598F: security/selinux/ 5598F: security/selinux/
5599F: scripts/selinux/
5599 5600
5600APPARMOR SECURITY MODULE 5601APPARMOR SECURITY MODULE
5601M: John Johansen <john.johansen@canonical.com> 5602M: John Johansen <john.johansen@canonical.com>
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 397d3057d336..1bffbe0ed778 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -820,6 +820,8 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
820 int res; 820 int res;
821 char buf[16]; 821 char buf[16];
822 822
823 memset(&bprm, 0, sizeof(bprm));
824
823 /* Create the file name */ 825 /* Create the file name */
824 sprintf(buf, "/lib/lib%d.so", id); 826 sprintf(buf, "/lib/lib%d.so", id);
825 827
@@ -835,6 +837,12 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
835 if (!bprm.cred) 837 if (!bprm.cred)
836 goto out; 838 goto out;
837 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;
845
838 res = prepare_binprm(&bprm); 846 res = prepare_binprm(&bprm);
839 847
840 if (!IS_ERR_VALUE(res)) 848 if (!IS_ERR_VALUE(res))
diff --git a/include/linux/capability.h b/include/linux/capability.h
index 4554db0cde86..c42112350003 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -417,7 +417,6 @@ extern const kernel_cap_t __cap_init_eff_set;
417 417
418# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }}) 418# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
419# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) 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# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ 420# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \
422 | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \ 421 | CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
423 CAP_FS_MASK_B1 } }) 422 CAP_FS_MASK_B1 } })
@@ -427,11 +426,7 @@ extern const kernel_cap_t __cap_init_eff_set;
427 426
428#endif /* _KERNEL_CAPABILITY_U32S != 2 */ 427#endif /* _KERNEL_CAPABILITY_U32S != 2 */
429 428
430#define CAP_INIT_INH_SET CAP_EMPTY_SET
431
432# define cap_clear(c) do { (c) = __cap_empty_set; } while (0) 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#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag)) 431#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag))
437#define cap_lower(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))
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 689496bb6654..bafc58c00fc3 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 310231823852..d4a5c84c503d 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/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
index 112a55033352..88e78dedc2e8 100644
--- a/include/linux/lsm_audit.h
+++ b/include/linux/lsm_audit.h
@@ -27,7 +27,7 @@
27/* Auxiliary data to use in generating the audit record. */ 27/* Auxiliary data to use in generating the audit record. */
28struct common_audit_data { 28struct common_audit_data {
29 char type; 29 char type;
30#define LSM_AUDIT_DATA_FS 1 30#define LSM_AUDIT_DATA_PATH 1
31#define LSM_AUDIT_DATA_NET 2 31#define LSM_AUDIT_DATA_NET 2
32#define LSM_AUDIT_DATA_CAP 3 32#define LSM_AUDIT_DATA_CAP 3
33#define LSM_AUDIT_DATA_IPC 4 33#define LSM_AUDIT_DATA_IPC 4
@@ -35,12 +35,13 @@ struct common_audit_data {
35#define LSM_AUDIT_DATA_KEY 6 35#define LSM_AUDIT_DATA_KEY 6
36#define LSM_AUDIT_DATA_NONE 7 36#define LSM_AUDIT_DATA_NONE 7
37#define LSM_AUDIT_DATA_KMOD 8 37#define LSM_AUDIT_DATA_KMOD 8
38#define LSM_AUDIT_DATA_INODE 9
39#define LSM_AUDIT_DATA_DENTRY 10
38 struct task_struct *tsk; 40 struct task_struct *tsk;
39 union { 41 union {
40 struct { 42 struct path path;
41 struct path path; 43 struct dentry *dentry;
42 struct inode *inode; 44 struct inode *inode;
43 } fs;
44 struct { 45 struct {
45 int netif; 46 int netif;
46 struct sock *sk; 47 struct sock *sk;
diff --git a/kernel/capability.c b/kernel/capability.c
index 32a80e08ff4b..283c529f8b1c 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 8093c16b84b1..e12c8af793f8 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 .user_ns = &init_user_ns, 57 .user_ns = &init_user_ns,
58 .group_info = &init_groups, 58 .group_info = &init_groups,
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 5ae0ff38425f..ad6a81c58b44 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);
@@ -420,6 +442,84 @@ unlock:
420} 442}
421EXPORT_SYMBOL(call_usermodehelper_exec); 443EXPORT_SYMBOL(call_usermodehelper_exec);
422 444
445static 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
505struct 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};
522
423void __init usermodehelper_init(void) 523void __init usermodehelper_init(void)
424{ 524{
425 khelper_wq = create_singlethread_workqueue("khelper"); 525 khelper_wq = create_singlethread_workqueue("khelper");
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 3dd0c46fa3bb..4bffd62c2f13 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/lib/flex_array.c b/lib/flex_array.c
index 854b57bd7d9d..cab7621f98aa 100644
--- a/lib/flex_array.c
+++ b/lib/flex_array.c
@@ -88,8 +88,11 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
88 gfp_t flags) 88 gfp_t flags)
89{ 89{
90 struct flex_array *ret; 90 struct flex_array *ret;
91 int max_size = FLEX_ARRAY_NR_BASE_PTRS * 91 int max_size = 0;
92 FLEX_ARRAY_ELEMENTS_PER_PART(element_size); 92
93 if (element_size)
94 max_size = FLEX_ARRAY_NR_BASE_PTRS *
95 FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
93 96
94 /* max_size will end up 0 if element_size > PAGE_SIZE */ 97 /* max_size will end up 0 if element_size > PAGE_SIZE */
95 if (total > max_size) 98 if (total > max_size)
@@ -183,15 +186,18 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
183int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src, 186int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
184 gfp_t flags) 187 gfp_t flags)
185{ 188{
186 int part_nr = fa_element_to_part_nr(fa, element_nr); 189 int part_nr;
187 struct flex_array_part *part; 190 struct flex_array_part *part;
188 void *dst; 191 void *dst;
189 192
190 if (element_nr >= fa->total_nr_elements) 193 if (element_nr >= fa->total_nr_elements)
191 return -ENOSPC; 194 return -ENOSPC;
195 if (!fa->element_size)
196 return 0;
192 if (elements_fit_in_base(fa)) 197 if (elements_fit_in_base(fa))
193 part = (struct flex_array_part *)&fa->parts[0]; 198 part = (struct flex_array_part *)&fa->parts[0];
194 else { 199 else {
200 part_nr = fa_element_to_part_nr(fa, element_nr);
195 part = __fa_get_part(fa, part_nr, flags); 201 part = __fa_get_part(fa, part_nr, flags);
196 if (!part) 202 if (!part)
197 return -ENOMEM; 203 return -ENOMEM;
@@ -211,15 +217,18 @@ EXPORT_SYMBOL(flex_array_put);
211 */ 217 */
212int flex_array_clear(struct flex_array *fa, unsigned int element_nr) 218int flex_array_clear(struct flex_array *fa, unsigned int element_nr)
213{ 219{
214 int part_nr = fa_element_to_part_nr(fa, element_nr); 220 int part_nr;
215 struct flex_array_part *part; 221 struct flex_array_part *part;
216 void *dst; 222 void *dst;
217 223
218 if (element_nr >= fa->total_nr_elements) 224 if (element_nr >= fa->total_nr_elements)
219 return -ENOSPC; 225 return -ENOSPC;
226 if (!fa->element_size)
227 return 0;
220 if (elements_fit_in_base(fa)) 228 if (elements_fit_in_base(fa))
221 part = (struct flex_array_part *)&fa->parts[0]; 229 part = (struct flex_array_part *)&fa->parts[0];
222 else { 230 else {
231 part_nr = fa_element_to_part_nr(fa, element_nr);
223 part = fa->parts[part_nr]; 232 part = fa->parts[part_nr];
224 if (!part) 233 if (!part)
225 return -EINVAL; 234 return -EINVAL;
@@ -264,6 +273,8 @@ int flex_array_prealloc(struct flex_array *fa, unsigned int start,
264 273
265 if (end >= fa->total_nr_elements) 274 if (end >= fa->total_nr_elements)
266 return -ENOSPC; 275 return -ENOSPC;
276 if (!fa->element_size)
277 return 0;
267 if (elements_fit_in_base(fa)) 278 if (elements_fit_in_base(fa))
268 return 0; 279 return 0;
269 start_part = fa_element_to_part_nr(fa, start); 280 start_part = fa_element_to_part_nr(fa, start);
@@ -291,14 +302,17 @@ EXPORT_SYMBOL(flex_array_prealloc);
291 */ 302 */
292void *flex_array_get(struct flex_array *fa, unsigned int element_nr) 303void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
293{ 304{
294 int part_nr = fa_element_to_part_nr(fa, element_nr); 305 int part_nr;
295 struct flex_array_part *part; 306 struct flex_array_part *part;
296 307
308 if (!fa->element_size)
309 return NULL;
297 if (element_nr >= fa->total_nr_elements) 310 if (element_nr >= fa->total_nr_elements)
298 return NULL; 311 return NULL;
299 if (elements_fit_in_base(fa)) 312 if (elements_fit_in_base(fa))
300 part = (struct flex_array_part *)&fa->parts[0]; 313 part = (struct flex_array_part *)&fa->parts[0];
301 else { 314 else {
315 part_nr = fa_element_to_part_nr(fa, element_nr);
302 part = fa->parts[part_nr]; 316 part = fa->parts[part_nr];
303 if (!part) 317 if (!part)
304 return NULL; 318 return NULL;
@@ -353,7 +367,7 @@ int flex_array_shrink(struct flex_array *fa)
353 int part_nr; 367 int part_nr;
354 int ret = 0; 368 int ret = 0;
355 369
356 if (!fa->total_nr_elements) 370 if (!fa->total_nr_elements || !fa->element_size)
357 return 0; 371 return 0;
358 if (elements_fit_in_base(fa)) 372 if (elements_fit_in_base(fa))
359 return ret; 373 return ret;
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 f66baf44f32d..5b366d7af3c4 100644
--- a/security/keys/user_defined.c
+++ b/security/keys/user_defined.c
@@ -157,8 +157,8 @@ EXPORT_SYMBOL_GPL(user_destroy);
157void user_describe(const struct key *key, struct seq_file *m) 157void user_describe(const struct key *key, struct seq_file *m)
158{ 158{
159 seq_puts(m, key->description); 159 seq_puts(m, key->description);
160 160 if (key_is_instantiated(key))
161 seq_printf(m, ": %u", key->datalen); 161 seq_printf(m, ": %u", key->datalen);
162} 162}
163 163
164EXPORT_SYMBOL_GPL(user_describe); 164EXPORT_SYMBOL_GPL(user_describe);
diff --git a/security/lsm_audit.c b/security/lsm_audit.c
index 908aa712816a..893af8a2fa1e 100644
--- a/security/lsm_audit.c
+++ b/security/lsm_audit.c
@@ -210,7 +210,6 @@ static inline void print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
210static void dump_common_audit_data(struct audit_buffer *ab, 210static void dump_common_audit_data(struct audit_buffer *ab,
211 struct common_audit_data *a) 211 struct common_audit_data *a)
212{ 212{
213 struct inode *inode = NULL;
214 struct task_struct *tsk = current; 213 struct task_struct *tsk = current;
215 214
216 if (a->tsk) 215 if (a->tsk)
@@ -229,33 +228,47 @@ static void dump_common_audit_data(struct audit_buffer *ab,
229 case LSM_AUDIT_DATA_CAP: 228 case LSM_AUDIT_DATA_CAP:
230 audit_log_format(ab, " capability=%d ", a->u.cap); 229 audit_log_format(ab, " capability=%d ", a->u.cap);
231 break; 230 break;
232 case LSM_AUDIT_DATA_FS: 231 case LSM_AUDIT_DATA_PATH: {
233 if (a->u.fs.path.dentry) { 232 struct inode *inode;
234 struct dentry *dentry = a->u.fs.path.dentry; 233
235 if (a->u.fs.path.mnt) { 234 audit_log_d_path(ab, "path=", &a->u.path);
236 audit_log_d_path(ab, "path=", &a->u.fs.path); 235
237 } else { 236 inode = a->u.path.dentry->d_inode;
238 audit_log_format(ab, " name=");
239 audit_log_untrustedstring(ab,
240 dentry->d_name.name);
241 }
242 inode = dentry->d_inode;
243 } else if (a->u.fs.inode) {
244 struct dentry *dentry;
245 inode = a->u.fs.inode;
246 dentry = d_find_alias(inode);
247 if (dentry) {
248 audit_log_format(ab, " name=");
249 audit_log_untrustedstring(ab,
250 dentry->d_name.name);
251 dput(dentry);
252 }
253 }
254 if (inode) 237 if (inode)
255 audit_log_format(ab, " dev=%s ino=%lu", 238 audit_log_format(ab, " dev=%s ino=%lu",
256 inode->i_sb->s_id, 239 inode->i_sb->s_id,
257 inode->i_ino); 240 inode->i_ino);
258 break; 241 break;
242 }
243 case LSM_AUDIT_DATA_DENTRY: {
244 struct inode *inode;
245
246 audit_log_format(ab, " name=");
247 audit_log_untrustedstring(ab, a->u.dentry->d_name.name);
248
249 inode = a->u.dentry->d_inode;
250 if (inode)
251 audit_log_format(ab, " dev=%s ino=%lu",
252 inode->i_sb->s_id,
253 inode->i_ino);
254 break;
255 }
256 case LSM_AUDIT_DATA_INODE: {
257 struct dentry *dentry;
258 struct inode *inode;
259
260 inode = a->u.inode;
261 dentry = d_find_alias(inode);
262 if (dentry) {
263 audit_log_format(ab, " name=");
264 audit_log_untrustedstring(ab,
265 dentry->d_name.name);
266 dput(dentry);
267 }
268 audit_log_format(ab, " dev=%s ino=%lu", inode->i_sb->s_id,
269 inode->i_ino);
270 break;
271 }
259 case LSM_AUDIT_DATA_TASK: 272 case LSM_AUDIT_DATA_TASK:
260 tsk = a->u.tsk; 273 tsk = a->u.tsk;
261 if (tsk && tsk->pid) { 274 if (tsk && tsk->pid) {
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 3d2715fd35ea..fcb89cb0f223 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -526,7 +526,7 @@ int avc_audit(u32 ssid, u32 tsid,
526 * during retry. However this is logically just as if the operation 526 * during retry. However this is logically just as if the operation
527 * happened a little later. 527 * happened a little later.
528 */ 528 */
529 if ((a->type == LSM_AUDIT_DATA_FS) && 529 if ((a->type == LSM_AUDIT_DATA_INODE) &&
530 (flags & IPERM_FLAG_RCU)) 530 (flags & IPERM_FLAG_RCU))
531 return -ECHILD; 531 return -ECHILD;
532 532
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8fb248843009..a0d38459d650 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -990,6 +990,7 @@ static void selinux_write_opts(struct seq_file *m,
990 continue; 990 continue;
991 default: 991 default:
992 BUG(); 992 BUG();
993 return;
993 }; 994 };
994 /* we need a comma before each option */ 995 /* we need a comma before each option */
995 seq_putc(m, ','); 996 seq_putc(m, ',');
@@ -1443,6 +1444,7 @@ static int task_has_capability(struct task_struct *tsk,
1443 printk(KERN_ERR 1444 printk(KERN_ERR
1444 "SELinux: out of range capability %d\n", cap); 1445 "SELinux: out of range capability %d\n", cap);
1445 BUG(); 1446 BUG();
1447 return -EINVAL;
1446 } 1448 }
1447 1449
1448 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd); 1450 rc = avc_has_perm_noaudit(sid, sid, sclass, av, 0, &avd);
@@ -1487,8 +1489,8 @@ static int inode_has_perm(const struct cred *cred,
1487 1489
1488 if (!adp) { 1490 if (!adp) {
1489 adp = &ad; 1491 adp = &ad;
1490 COMMON_AUDIT_DATA_INIT(&ad, FS); 1492 COMMON_AUDIT_DATA_INIT(&ad, INODE);
1491 ad.u.fs.inode = inode; 1493 ad.u.inode = inode;
1492 } 1494 }
1493 1495
1494 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags); 1496 return avc_has_perm_flags(sid, isec->sid, isec->sclass, perms, adp, flags);
@@ -1498,16 +1500,29 @@ static int inode_has_perm(const struct cred *cred,
1498 the dentry to help the auditing code to more easily generate the 1500 the dentry to help the auditing code to more easily generate the
1499 pathname if needed. */ 1501 pathname if needed. */
1500static inline int dentry_has_perm(const struct cred *cred, 1502static inline int dentry_has_perm(const struct cred *cred,
1501 struct vfsmount *mnt,
1502 struct dentry *dentry, 1503 struct dentry *dentry,
1503 u32 av) 1504 u32 av)
1504{ 1505{
1505 struct inode *inode = dentry->d_inode; 1506 struct inode *inode = dentry->d_inode;
1506 struct common_audit_data ad; 1507 struct common_audit_data ad;
1507 1508
1508 COMMON_AUDIT_DATA_INIT(&ad, FS); 1509 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1509 ad.u.fs.path.mnt = mnt; 1510 ad.u.dentry = dentry;
1510 ad.u.fs.path.dentry = dentry; 1511 return inode_has_perm(cred, inode, av, &ad, 0);
1512}
1513
1514/* Same as inode_has_perm, but pass explicit audit data containing
1515 the path to help the auditing code to more easily generate the
1516 pathname if needed. */
1517static inline int path_has_perm(const struct cred *cred,
1518 struct path *path,
1519 u32 av)
1520{
1521 struct inode *inode = path->dentry->d_inode;
1522 struct common_audit_data ad;
1523
1524 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1525 ad.u.path = *path;
1511 return inode_has_perm(cred, inode, av, &ad, 0); 1526 return inode_has_perm(cred, inode, av, &ad, 0);
1512} 1527}
1513 1528
@@ -1529,8 +1544,8 @@ static int file_has_perm(const struct cred *cred,
1529 u32 sid = cred_sid(cred); 1544 u32 sid = cred_sid(cred);
1530 int rc; 1545 int rc;
1531 1546
1532 COMMON_AUDIT_DATA_INIT(&ad, FS); 1547 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1533 ad.u.fs.path = file->f_path; 1548 ad.u.path = file->f_path;
1534 1549
1535 if (sid != fsec->sid) { 1550 if (sid != fsec->sid) {
1536 rc = avc_has_perm(sid, fsec->sid, 1551 rc = avc_has_perm(sid, fsec->sid,
@@ -1568,8 +1583,8 @@ static int may_create(struct inode *dir,
1568 sid = tsec->sid; 1583 sid = tsec->sid;
1569 newsid = tsec->create_sid; 1584 newsid = tsec->create_sid;
1570 1585
1571 COMMON_AUDIT_DATA_INIT(&ad, FS); 1586 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1572 ad.u.fs.path.dentry = dentry; 1587 ad.u.dentry = dentry;
1573 1588
1574 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, 1589 rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR,
1575 DIR__ADD_NAME | DIR__SEARCH, 1590 DIR__ADD_NAME | DIR__SEARCH,
@@ -1621,8 +1636,8 @@ static int may_link(struct inode *dir,
1621 dsec = dir->i_security; 1636 dsec = dir->i_security;
1622 isec = dentry->d_inode->i_security; 1637 isec = dentry->d_inode->i_security;
1623 1638
1624 COMMON_AUDIT_DATA_INIT(&ad, FS); 1639 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1625 ad.u.fs.path.dentry = dentry; 1640 ad.u.dentry = dentry;
1626 1641
1627 av = DIR__SEARCH; 1642 av = DIR__SEARCH;
1628 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME); 1643 av |= (kind ? DIR__REMOVE_NAME : DIR__ADD_NAME);
@@ -1667,9 +1682,9 @@ static inline int may_rename(struct inode *old_dir,
1667 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 1682 old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode);
1668 new_dsec = new_dir->i_security; 1683 new_dsec = new_dir->i_security;
1669 1684
1670 COMMON_AUDIT_DATA_INIT(&ad, FS); 1685 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
1671 1686
1672 ad.u.fs.path.dentry = old_dentry; 1687 ad.u.dentry = old_dentry;
1673 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, 1688 rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR,
1674 DIR__REMOVE_NAME | DIR__SEARCH, &ad); 1689 DIR__REMOVE_NAME | DIR__SEARCH, &ad);
1675 if (rc) 1690 if (rc)
@@ -1685,7 +1700,7 @@ static inline int may_rename(struct inode *old_dir,
1685 return rc; 1700 return rc;
1686 } 1701 }
1687 1702
1688 ad.u.fs.path.dentry = new_dentry; 1703 ad.u.dentry = new_dentry;
1689 av = DIR__ADD_NAME | DIR__SEARCH; 1704 av = DIR__ADD_NAME | DIR__SEARCH;
1690 if (new_dentry->d_inode) 1705 if (new_dentry->d_inode)
1691 av |= DIR__REMOVE_NAME; 1706 av |= DIR__REMOVE_NAME;
@@ -1895,7 +1910,7 @@ static int selinux_quota_on(struct dentry *dentry)
1895{ 1910{
1896 const struct cred *cred = current_cred(); 1911 const struct cred *cred = current_cred();
1897 1912
1898 return dentry_has_perm(cred, NULL, dentry, FILE__QUOTAON); 1913 return dentry_has_perm(cred, dentry, FILE__QUOTAON);
1899} 1914}
1900 1915
1901static int selinux_syslog(int type) 1916static int selinux_syslog(int type)
@@ -1992,8 +2007,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm)
1992 return rc; 2007 return rc;
1993 } 2008 }
1994 2009
1995 COMMON_AUDIT_DATA_INIT(&ad, FS); 2010 COMMON_AUDIT_DATA_INIT(&ad, PATH);
1996 ad.u.fs.path = bprm->file->f_path; 2011 ad.u.path = bprm->file->f_path;
1997 2012
1998 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2013 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
1999 new_tsec->sid = old_tsec->sid; 2014 new_tsec->sid = old_tsec->sid;
@@ -2121,7 +2136,7 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2121 2136
2122 /* Revalidate access to inherited open files. */ 2137 /* Revalidate access to inherited open files. */
2123 2138
2124 COMMON_AUDIT_DATA_INIT(&ad, FS); 2139 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2125 2140
2126 spin_lock(&files->file_lock); 2141 spin_lock(&files->file_lock);
2127 for (;;) { 2142 for (;;) {
@@ -2469,8 +2484,8 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data)
2469 if (flags & MS_KERNMOUNT) 2484 if (flags & MS_KERNMOUNT)
2470 return 0; 2485 return 0;
2471 2486
2472 COMMON_AUDIT_DATA_INIT(&ad, FS); 2487 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2473 ad.u.fs.path.dentry = sb->s_root; 2488 ad.u.dentry = sb->s_root;
2474 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); 2489 return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad);
2475} 2490}
2476 2491
@@ -2479,8 +2494,8 @@ static int selinux_sb_statfs(struct dentry *dentry)
2479 const struct cred *cred = current_cred(); 2494 const struct cred *cred = current_cred();
2480 struct common_audit_data ad; 2495 struct common_audit_data ad;
2481 2496
2482 COMMON_AUDIT_DATA_INIT(&ad, FS); 2497 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2483 ad.u.fs.path.dentry = dentry->d_sb->s_root; 2498 ad.u.dentry = dentry->d_sb->s_root;
2484 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); 2499 return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad);
2485} 2500}
2486 2501
@@ -2496,8 +2511,7 @@ static int selinux_mount(char *dev_name,
2496 return superblock_has_perm(cred, path->mnt->mnt_sb, 2511 return superblock_has_perm(cred, path->mnt->mnt_sb,
2497 FILESYSTEM__REMOUNT, NULL); 2512 FILESYSTEM__REMOUNT, NULL);
2498 else 2513 else
2499 return dentry_has_perm(cred, path->mnt, path->dentry, 2514 return path_has_perm(cred, path, FILE__MOUNTON);
2500 FILE__MOUNTON);
2501} 2515}
2502 2516
2503static int selinux_umount(struct vfsmount *mnt, int flags) 2517static int selinux_umount(struct vfsmount *mnt, int flags)
@@ -2630,14 +2644,14 @@ static int selinux_inode_readlink(struct dentry *dentry)
2630{ 2644{
2631 const struct cred *cred = current_cred(); 2645 const struct cred *cred = current_cred();
2632 2646
2633 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2647 return dentry_has_perm(cred, dentry, FILE__READ);
2634} 2648}
2635 2649
2636static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata) 2650static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *nameidata)
2637{ 2651{
2638 const struct cred *cred = current_cred(); 2652 const struct cred *cred = current_cred();
2639 2653
2640 return dentry_has_perm(cred, NULL, dentry, FILE__READ); 2654 return dentry_has_perm(cred, dentry, FILE__READ);
2641} 2655}
2642 2656
2643static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags) 2657static int selinux_inode_permission(struct inode *inode, int mask, unsigned flags)
@@ -2654,8 +2668,8 @@ static int selinux_inode_permission(struct inode *inode, int mask, unsigned flag
2654 if (!mask) 2668 if (!mask)
2655 return 0; 2669 return 0;
2656 2670
2657 COMMON_AUDIT_DATA_INIT(&ad, FS); 2671 COMMON_AUDIT_DATA_INIT(&ad, INODE);
2658 ad.u.fs.inode = inode; 2672 ad.u.inode = inode;
2659 2673
2660 if (from_access) 2674 if (from_access)
2661 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS; 2675 ad.selinux_audit_data.auditdeny |= FILE__AUDIT_ACCESS;
@@ -2680,16 +2694,20 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
2680 2694
2681 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | 2695 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
2682 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) 2696 ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
2683 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2697 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2684 2698
2685 return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); 2699 return dentry_has_perm(cred, dentry, FILE__WRITE);
2686} 2700}
2687 2701
2688static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 2702static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
2689{ 2703{
2690 const struct cred *cred = current_cred(); 2704 const struct cred *cred = current_cred();
2705 struct path path;
2706
2707 path.dentry = dentry;
2708 path.mnt = mnt;
2691 2709
2692 return dentry_has_perm(cred, mnt, dentry, FILE__GETATTR); 2710 return path_has_perm(cred, &path, FILE__GETATTR);
2693} 2711}
2694 2712
2695static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) 2713static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
@@ -2710,7 +2728,7 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
2710 2728
2711 /* Not an attribute we recognize, so just check the 2729 /* Not an attribute we recognize, so just check the
2712 ordinary setattr permission. */ 2730 ordinary setattr permission. */
2713 return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); 2731 return dentry_has_perm(cred, dentry, FILE__SETATTR);
2714} 2732}
2715 2733
2716static int selinux_inode_setxattr(struct dentry *dentry, const char *name, 2734static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
@@ -2733,8 +2751,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name,
2733 if (!inode_owner_or_capable(inode)) 2751 if (!inode_owner_or_capable(inode))
2734 return -EPERM; 2752 return -EPERM;
2735 2753
2736 COMMON_AUDIT_DATA_INIT(&ad, FS); 2754 COMMON_AUDIT_DATA_INIT(&ad, DENTRY);
2737 ad.u.fs.path.dentry = dentry; 2755 ad.u.dentry = dentry;
2738 2756
2739 rc = avc_has_perm(sid, isec->sid, isec->sclass, 2757 rc = avc_has_perm(sid, isec->sid, isec->sclass,
2740 FILE__RELABELFROM, &ad); 2758 FILE__RELABELFROM, &ad);
@@ -2797,14 +2815,14 @@ static int selinux_inode_getxattr(struct dentry *dentry, const char *name)
2797{ 2815{
2798 const struct cred *cred = current_cred(); 2816 const struct cred *cred = current_cred();
2799 2817
2800 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2818 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2801} 2819}
2802 2820
2803static int selinux_inode_listxattr(struct dentry *dentry) 2821static int selinux_inode_listxattr(struct dentry *dentry)
2804{ 2822{
2805 const struct cred *cred = current_cred(); 2823 const struct cred *cred = current_cred();
2806 2824
2807 return dentry_has_perm(cred, NULL, dentry, FILE__GETATTR); 2825 return dentry_has_perm(cred, dentry, FILE__GETATTR);
2808} 2826}
2809 2827
2810static int selinux_inode_removexattr(struct dentry *dentry, const char *name) 2828static int selinux_inode_removexattr(struct dentry *dentry, const char *name)
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 348eb00cb668..3ba4feba048a 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -30,13 +30,14 @@
30#define POLICYDB_VERSION_PERMISSIVE 23 30#define POLICYDB_VERSION_PERMISSIVE 23
31#define POLICYDB_VERSION_BOUNDARY 24 31#define POLICYDB_VERSION_BOUNDARY 24
32#define POLICYDB_VERSION_FILENAME_TRANS 25 32#define POLICYDB_VERSION_FILENAME_TRANS 25
33#define POLICYDB_VERSION_ROLETRANS 26
33 34
34/* Range of policy versions we understand*/ 35/* Range of policy versions we understand*/
35#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE 36#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
36#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX 37#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
37#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE 38#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
38#else 39#else
39#define POLICYDB_VERSION_MAX POLICYDB_VERSION_FILENAME_TRANS 40#define POLICYDB_VERSION_MAX POLICYDB_VERSION_ROLETRANS
40#endif 41#endif
41 42
42/* Mask for just the mount related flags */ 43/* Mask for just the mount related flags */
@@ -85,7 +86,7 @@ extern int selinux_policycap_openperm;
85int security_mls_enabled(void); 86int security_mls_enabled(void);
86 87
87int security_load_policy(void *data, size_t len); 88int security_load_policy(void *data, size_t len);
88int security_read_policy(void **data, ssize_t *len); 89int security_read_policy(void **data, size_t *len);
89size_t security_policydb_len(void); 90size_t security_policydb_len(void);
90 91
91int security_policycap_supported(unsigned int req_cap); 92int security_policycap_supported(unsigned int req_cap);
@@ -111,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid,
111int security_transition_sid(u32 ssid, u32 tsid, u16 tclass, 112int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
112 const struct qstr *qstr, u32 *out_sid); 113 const struct qstr *qstr, u32 *out_sid);
113 114
114int security_transition_sid_user(u32 ssid, u32 tsid, 115int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
115 u16 tclass, u32 *out_sid); 116 const char *objname, u32 *out_sid);
116 117
117int security_member_sid(u32 ssid, u32 tsid, 118int security_member_sid(u32 ssid, u32 tsid,
118 u16 tclass, u32 *out_sid); 119 u16 tclass, u32 *out_sid);
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
index 65ebfe954f85..3618251d0fdb 100644
--- a/security/selinux/netnode.c
+++ b/security/selinux/netnode.c
@@ -141,6 +141,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family)
141 break; 141 break;
142 default: 142 default:
143 BUG(); 143 BUG();
144 return NULL;
144 } 145 }
145 146
146 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list) 147 list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list)
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2d3373b2e256..77d44138864f 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -28,6 +28,7 @@
28#include <linux/percpu.h> 28#include <linux/percpu.h>
29#include <linux/audit.h> 29#include <linux/audit.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <linux/kobject.h>
31 32
32/* selinuxfs pseudo filesystem for exporting the security policy API. 33/* selinuxfs pseudo filesystem for exporting the security policy API.
33 Based on the proc code and the fs/nfsd/nfsctl.c code. */ 34 Based on the proc code and the fs/nfsd/nfsctl.c code. */
@@ -753,11 +754,13 @@ out:
753static ssize_t sel_write_create(struct file *file, char *buf, size_t size) 754static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
754{ 755{
755 char *scon = NULL, *tcon = NULL; 756 char *scon = NULL, *tcon = NULL;
757 char *namebuf = NULL, *objname = NULL;
756 u32 ssid, tsid, newsid; 758 u32 ssid, tsid, newsid;
757 u16 tclass; 759 u16 tclass;
758 ssize_t length; 760 ssize_t length;
759 char *newcon = NULL; 761 char *newcon = NULL;
760 u32 len; 762 u32 len;
763 int nargs;
761 764
762 length = task_has_security(current, SECURITY__COMPUTE_CREATE); 765 length = task_has_security(current, SECURITY__COMPUTE_CREATE);
763 if (length) 766 if (length)
@@ -773,9 +776,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
773 if (!tcon) 776 if (!tcon)
774 goto out; 777 goto out;
775 778
779 length = -ENOMEM;
780 namebuf = kzalloc(size + 1, GFP_KERNEL);
781 if (!namebuf)
782 goto out;
783
776 length = -EINVAL; 784 length = -EINVAL;
777 if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) 785 nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf);
786 if (nargs < 3 || nargs > 4)
778 goto out; 787 goto out;
788 if (nargs == 4)
789 objname = namebuf;
779 790
780 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); 791 length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);
781 if (length) 792 if (length)
@@ -785,7 +796,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
785 if (length) 796 if (length)
786 goto out; 797 goto out;
787 798
788 length = security_transition_sid_user(ssid, tsid, tclass, &newsid); 799 length = security_transition_sid_user(ssid, tsid, tclass,
800 objname, &newsid);
789 if (length) 801 if (length)
790 goto out; 802 goto out;
791 803
@@ -804,6 +816,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
804 length = len; 816 length = len;
805out: 817out:
806 kfree(newcon); 818 kfree(newcon);
819 kfree(namebuf);
807 kfree(tcon); 820 kfree(tcon);
808 kfree(scon); 821 kfree(scon);
809 return length; 822 return length;
@@ -1901,6 +1914,7 @@ static struct file_system_type sel_fs_type = {
1901}; 1914};
1902 1915
1903struct vfsmount *selinuxfs_mount; 1916struct vfsmount *selinuxfs_mount;
1917static struct kobject *selinuxfs_kobj;
1904 1918
1905static int __init init_sel_fs(void) 1919static int __init init_sel_fs(void)
1906{ 1920{
@@ -1908,9 +1922,16 @@ static int __init init_sel_fs(void)
1908 1922
1909 if (!selinux_enabled) 1923 if (!selinux_enabled)
1910 return 0; 1924 return 0;
1925
1926 selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
1927 if (!selinuxfs_kobj)
1928 return -ENOMEM;
1929
1911 err = register_filesystem(&sel_fs_type); 1930 err = register_filesystem(&sel_fs_type);
1912 if (err) 1931 if (err) {
1932 kobject_put(selinuxfs_kobj);
1913 return err; 1933 return err;
1934 }
1914 1935
1915 selinuxfs_mount = kern_mount(&sel_fs_type); 1936 selinuxfs_mount = kern_mount(&sel_fs_type);
1916 if (IS_ERR(selinuxfs_mount)) { 1937 if (IS_ERR(selinuxfs_mount)) {
@@ -1927,6 +1948,7 @@ __initcall(init_sel_fs);
1927#ifdef CONFIG_SECURITY_SELINUX_DISABLE 1948#ifdef CONFIG_SECURITY_SELINUX_DISABLE
1928void exit_sel_fs(void) 1949void exit_sel_fs(void)
1929{ 1950{
1951 kobject_put(selinuxfs_kobj);
1930 unregister_filesystem(&sel_fs_type); 1952 unregister_filesystem(&sel_fs_type);
1931} 1953}
1932#endif 1954#endif
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 7102457661d6..102e9ec1b77a 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -128,6 +128,11 @@ static struct policydb_compat_info policydb_compat[] = {
128 .sym_num = SYM_NUM, 128 .sym_num = SYM_NUM,
129 .ocon_num = OCON_NUM, 129 .ocon_num = OCON_NUM,
130 }, 130 },
131 {
132 .version = POLICYDB_VERSION_ROLETRANS,
133 .sym_num = SYM_NUM,
134 .ocon_num = OCON_NUM,
135 },
131}; 136};
132 137
133static struct policydb_compat_info *policydb_lookup_compat(int version) 138static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -179,6 +184,43 @@ out:
179 return rc; 184 return rc;
180} 185}
181 186
187static u32 filenametr_hash(struct hashtab *h, const void *k)
188{
189 const struct filename_trans *ft = k;
190 unsigned long hash;
191 unsigned int byte_num;
192 unsigned char focus;
193
194 hash = ft->stype ^ ft->ttype ^ ft->tclass;
195
196 byte_num = 0;
197 while ((focus = ft->name[byte_num++]))
198 hash = partial_name_hash(focus, hash);
199 return hash & (h->size - 1);
200}
201
202static int filenametr_cmp(struct hashtab *h, const void *k1, const void *k2)
203{
204 const struct filename_trans *ft1 = k1;
205 const struct filename_trans *ft2 = k2;
206 int v;
207
208 v = ft1->stype - ft2->stype;
209 if (v)
210 return v;
211
212 v = ft1->ttype - ft2->ttype;
213 if (v)
214 return v;
215
216 v = ft1->tclass - ft2->tclass;
217 if (v)
218 return v;
219
220 return strcmp(ft1->name, ft2->name);
221
222}
223
182static u32 rangetr_hash(struct hashtab *h, const void *k) 224static u32 rangetr_hash(struct hashtab *h, const void *k)
183{ 225{
184 const struct range_trans *key = k; 226 const struct range_trans *key = k;
@@ -231,15 +273,22 @@ static int policydb_init(struct policydb *p)
231 if (rc) 273 if (rc)
232 goto out; 274 goto out;
233 275
276 p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
277 if (!p->filename_trans)
278 goto out;
279
234 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256); 280 p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
235 if (!p->range_tr) 281 if (!p->range_tr)
236 goto out; 282 goto out;
237 283
284 ebitmap_init(&p->filename_trans_ttypes);
238 ebitmap_init(&p->policycaps); 285 ebitmap_init(&p->policycaps);
239 ebitmap_init(&p->permissive_map); 286 ebitmap_init(&p->permissive_map);
240 287
241 return 0; 288 return 0;
242out: 289out:
290 hashtab_destroy(p->filename_trans);
291 hashtab_destroy(p->range_tr);
243 for (i = 0; i < SYM_NUM; i++) 292 for (i = 0; i < SYM_NUM; i++)
244 hashtab_destroy(p->symtab[i].table); 293 hashtab_destroy(p->symtab[i].table);
245 return rc; 294 return rc;
@@ -417,32 +466,26 @@ static int (*index_f[SYM_NUM]) (void *key, void *datum, void *datap) =
417}; 466};
418 467
419#ifdef DEBUG_HASHES 468#ifdef DEBUG_HASHES
420static void symtab_hash_eval(struct symtab *s) 469static void hash_eval(struct hashtab *h, const char *hash_name)
421{ 470{
422 int i; 471 struct hashtab_info info;
423
424 for (i = 0; i < SYM_NUM; i++) {
425 struct hashtab *h = s[i].table;
426 struct hashtab_info info;
427 472
428 hashtab_stat(h, &info); 473 hashtab_stat(h, &info);
429 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, " 474 printk(KERN_DEBUG "SELinux: %s: %d entries and %d/%d buckets used, "
430 "longest chain length %d\n", symtab_name[i], h->nel, 475 "longest chain length %d\n", hash_name, h->nel,
431 info.slots_used, h->size, info.max_chain_len); 476 info.slots_used, h->size, info.max_chain_len);
432 }
433} 477}
434 478
435static void rangetr_hash_eval(struct hashtab *h) 479static void symtab_hash_eval(struct symtab *s)
436{ 480{
437 struct hashtab_info info; 481 int i;
438 482
439 hashtab_stat(h, &info); 483 for (i = 0; i < SYM_NUM; i++)
440 printk(KERN_DEBUG "SELinux: rangetr: %d entries and %d/%d buckets used, " 484 hash_eval(s[i].table, symtab_name[i]);
441 "longest chain length %d\n", h->nel,
442 info.slots_used, h->size, info.max_chain_len);
443} 485}
486
444#else 487#else
445static inline void rangetr_hash_eval(struct hashtab *h) 488static inline void hash_eval(struct hashtab *h, char *hash_name)
446{ 489{
447} 490}
448#endif 491#endif
@@ -675,6 +718,16 @@ static int (*destroy_f[SYM_NUM]) (void *key, void *datum, void *datap) =
675 cat_destroy, 718 cat_destroy,
676}; 719};
677 720
721static int filenametr_destroy(void *key, void *datum, void *p)
722{
723 struct filename_trans *ft = key;
724 kfree(ft->name);
725 kfree(key);
726 kfree(datum);
727 cond_resched();
728 return 0;
729}
730
678static int range_tr_destroy(void *key, void *datum, void *p) 731static int range_tr_destroy(void *key, void *datum, void *p)
679{ 732{
680 struct mls_range *rt = datum; 733 struct mls_range *rt = datum;
@@ -709,7 +762,6 @@ void policydb_destroy(struct policydb *p)
709 int i; 762 int i;
710 struct role_allow *ra, *lra = NULL; 763 struct role_allow *ra, *lra = NULL;
711 struct role_trans *tr, *ltr = NULL; 764 struct role_trans *tr, *ltr = NULL;
712 struct filename_trans *ft, *nft;
713 765
714 for (i = 0; i < SYM_NUM; i++) { 766 for (i = 0; i < SYM_NUM; i++) {
715 cond_resched(); 767 cond_resched();
@@ -773,6 +825,9 @@ void policydb_destroy(struct policydb *p)
773 } 825 }
774 kfree(lra); 826 kfree(lra);
775 827
828 hashtab_map(p->filename_trans, filenametr_destroy, NULL);
829 hashtab_destroy(p->filename_trans);
830
776 hashtab_map(p->range_tr, range_tr_destroy, NULL); 831 hashtab_map(p->range_tr, range_tr_destroy, NULL);
777 hashtab_destroy(p->range_tr); 832 hashtab_destroy(p->range_tr);
778 833
@@ -788,14 +843,7 @@ void policydb_destroy(struct policydb *p)
788 flex_array_free(p->type_attr_map_array); 843 flex_array_free(p->type_attr_map_array);
789 } 844 }
790 845
791 ft = p->filename_trans; 846 ebitmap_destroy(&p->filename_trans_ttypes);
792 while (ft) {
793 nft = ft->next;
794 kfree(ft->name);
795 kfree(ft);
796 ft = nft;
797 }
798
799 ebitmap_destroy(&p->policycaps); 847 ebitmap_destroy(&p->policycaps);
800 ebitmap_destroy(&p->permissive_map); 848 ebitmap_destroy(&p->permissive_map);
801 849
@@ -1795,7 +1843,7 @@ static int range_read(struct policydb *p, void *fp)
1795 rt = NULL; 1843 rt = NULL;
1796 r = NULL; 1844 r = NULL;
1797 } 1845 }
1798 rangetr_hash_eval(p->range_tr); 1846 hash_eval(p->range_tr, "rangetr");
1799 rc = 0; 1847 rc = 0;
1800out: 1848out:
1801 kfree(rt); 1849 kfree(rt);
@@ -1805,9 +1853,10 @@ out:
1805 1853
1806static int filename_trans_read(struct policydb *p, void *fp) 1854static int filename_trans_read(struct policydb *p, void *fp)
1807{ 1855{
1808 struct filename_trans *ft, *last; 1856 struct filename_trans *ft;
1809 u32 nel, len; 1857 struct filename_trans_datum *otype;
1810 char *name; 1858 char *name;
1859 u32 nel, len;
1811 __le32 buf[4]; 1860 __le32 buf[4];
1812 int rc, i; 1861 int rc, i;
1813 1862
@@ -1816,25 +1865,23 @@ static int filename_trans_read(struct policydb *p, void *fp)
1816 1865
1817 rc = next_entry(buf, fp, sizeof(u32)); 1866 rc = next_entry(buf, fp, sizeof(u32));
1818 if (rc) 1867 if (rc)
1819 goto out; 1868 return rc;
1820 nel = le32_to_cpu(buf[0]); 1869 nel = le32_to_cpu(buf[0]);
1821 1870
1822 last = p->filename_trans;
1823 while (last && last->next)
1824 last = last->next;
1825
1826 for (i = 0; i < nel; i++) { 1871 for (i = 0; i < nel; i++) {
1872 ft = NULL;
1873 otype = NULL;
1874 name = NULL;
1875
1827 rc = -ENOMEM; 1876 rc = -ENOMEM;
1828 ft = kzalloc(sizeof(*ft), GFP_KERNEL); 1877 ft = kzalloc(sizeof(*ft), GFP_KERNEL);
1829 if (!ft) 1878 if (!ft)
1830 goto out; 1879 goto out;
1831 1880
1832 /* add it to the tail of the list */ 1881 rc = -ENOMEM;
1833 if (!last) 1882 otype = kmalloc(sizeof(*otype), GFP_KERNEL);
1834 p->filename_trans = ft; 1883 if (!otype)
1835 else 1884 goto out;
1836 last->next = ft;
1837 last = ft;
1838 1885
1839 /* length of the path component string */ 1886 /* length of the path component string */
1840 rc = next_entry(buf, fp, sizeof(u32)); 1887 rc = next_entry(buf, fp, sizeof(u32));
@@ -1862,10 +1909,22 @@ static int filename_trans_read(struct policydb *p, void *fp)
1862 ft->stype = le32_to_cpu(buf[0]); 1909 ft->stype = le32_to_cpu(buf[0]);
1863 ft->ttype = le32_to_cpu(buf[1]); 1910 ft->ttype = le32_to_cpu(buf[1]);
1864 ft->tclass = le32_to_cpu(buf[2]); 1911 ft->tclass = le32_to_cpu(buf[2]);
1865 ft->otype = le32_to_cpu(buf[3]); 1912
1913 otype->otype = le32_to_cpu(buf[3]);
1914
1915 rc = ebitmap_set_bit(&p->filename_trans_ttypes, ft->ttype, 1);
1916 if (rc)
1917 goto out;
1918
1919 hashtab_insert(p->filename_trans, ft, otype);
1866 } 1920 }
1867 rc = 0; 1921 hash_eval(p->filename_trans, "filenametr");
1922 return 0;
1868out: 1923out:
1924 kfree(ft);
1925 kfree(name);
1926 kfree(otype);
1927
1869 return rc; 1928 return rc;
1870} 1929}
1871 1930
@@ -2266,6 +2325,11 @@ int policydb_read(struct policydb *p, void *fp)
2266 p->symtab[i].nprim = nprim; 2325 p->symtab[i].nprim = nprim;
2267 } 2326 }
2268 2327
2328 rc = -EINVAL;
2329 p->process_class = string_to_security_class(p, "process");
2330 if (!p->process_class)
2331 goto bad;
2332
2269 rc = avtab_read(&p->te_avtab, fp, p); 2333 rc = avtab_read(&p->te_avtab, fp, p);
2270 if (rc) 2334 if (rc)
2271 goto bad; 2335 goto bad;
@@ -2298,8 +2362,17 @@ int policydb_read(struct policydb *p, void *fp)
2298 tr->role = le32_to_cpu(buf[0]); 2362 tr->role = le32_to_cpu(buf[0]);
2299 tr->type = le32_to_cpu(buf[1]); 2363 tr->type = le32_to_cpu(buf[1]);
2300 tr->new_role = le32_to_cpu(buf[2]); 2364 tr->new_role = le32_to_cpu(buf[2]);
2365 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2366 rc = next_entry(buf, fp, sizeof(u32));
2367 if (rc)
2368 goto bad;
2369 tr->tclass = le32_to_cpu(buf[0]);
2370 } else
2371 tr->tclass = p->process_class;
2372
2301 if (!policydb_role_isvalid(p, tr->role) || 2373 if (!policydb_role_isvalid(p, tr->role) ||
2302 !policydb_type_isvalid(p, tr->type) || 2374 !policydb_type_isvalid(p, tr->type) ||
2375 !policydb_class_isvalid(p, tr->tclass) ||
2303 !policydb_role_isvalid(p, tr->new_role)) 2376 !policydb_role_isvalid(p, tr->new_role))
2304 goto bad; 2377 goto bad;
2305 ltr = tr; 2378 ltr = tr;
@@ -2341,11 +2414,6 @@ int policydb_read(struct policydb *p, void *fp)
2341 goto bad; 2414 goto bad;
2342 2415
2343 rc = -EINVAL; 2416 rc = -EINVAL;
2344 p->process_class = string_to_security_class(p, "process");
2345 if (!p->process_class)
2346 goto bad;
2347
2348 rc = -EINVAL;
2349 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition"); 2417 p->process_trans_perms = string_to_av_perm(p, p->process_class, "transition");
2350 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition"); 2418 p->process_trans_perms |= string_to_av_perm(p, p->process_class, "dyntransition");
2351 if (!p->process_trans_perms) 2419 if (!p->process_trans_perms)
@@ -2517,8 +2585,9 @@ static int cat_write(void *vkey, void *datum, void *ptr)
2517 return 0; 2585 return 0;
2518} 2586}
2519 2587
2520static int role_trans_write(struct role_trans *r, void *fp) 2588static int role_trans_write(struct policydb *p, void *fp)
2521{ 2589{
2590 struct role_trans *r = p->role_tr;
2522 struct role_trans *tr; 2591 struct role_trans *tr;
2523 u32 buf[3]; 2592 u32 buf[3];
2524 size_t nel; 2593 size_t nel;
@@ -2538,6 +2607,12 @@ static int role_trans_write(struct role_trans *r, void *fp)
2538 rc = put_entry(buf, sizeof(u32), 3, fp); 2607 rc = put_entry(buf, sizeof(u32), 3, fp);
2539 if (rc) 2608 if (rc)
2540 return rc; 2609 return rc;
2610 if (p->policyvers >= POLICYDB_VERSION_ROLETRANS) {
2611 buf[0] = cpu_to_le32(tr->tclass);
2612 rc = put_entry(buf, sizeof(u32), 1, fp);
2613 if (rc)
2614 return rc;
2615 }
2541 } 2616 }
2542 2617
2543 return 0; 2618 return 0;
@@ -3045,7 +3120,7 @@ static int genfs_write(struct policydb *p, void *fp)
3045 return 0; 3120 return 0;
3046} 3121}
3047 3122
3048static int range_count(void *key, void *data, void *ptr) 3123static int hashtab_cnt(void *key, void *data, void *ptr)
3049{ 3124{
3050 int *cnt = ptr; 3125 int *cnt = ptr;
3051 *cnt = *cnt + 1; 3126 *cnt = *cnt + 1;
@@ -3093,7 +3168,7 @@ static int range_write(struct policydb *p, void *fp)
3093 3168
3094 /* count the number of entries in the hashtab */ 3169 /* count the number of entries in the hashtab */
3095 nel = 0; 3170 nel = 0;
3096 rc = hashtab_map(p->range_tr, range_count, &nel); 3171 rc = hashtab_map(p->range_tr, hashtab_cnt, &nel);
3097 if (rc) 3172 if (rc)
3098 return rc; 3173 return rc;
3099 3174
@@ -3110,43 +3185,60 @@ static int range_write(struct policydb *p, void *fp)
3110 return 0; 3185 return 0;
3111} 3186}
3112 3187
3113static int filename_trans_write(struct policydb *p, void *fp) 3188static int filename_write_helper(void *key, void *data, void *ptr)
3114{ 3189{
3115 struct filename_trans *ft;
3116 u32 len, nel = 0;
3117 __le32 buf[4]; 3190 __le32 buf[4];
3191 struct filename_trans *ft = key;
3192 struct filename_trans_datum *otype = data;
3193 void *fp = ptr;
3118 int rc; 3194 int rc;
3195 u32 len;
3119 3196
3120 for (ft = p->filename_trans; ft; ft = ft->next) 3197 len = strlen(ft->name);
3121 nel++; 3198 buf[0] = cpu_to_le32(len);
3122
3123 buf[0] = cpu_to_le32(nel);
3124 rc = put_entry(buf, sizeof(u32), 1, fp); 3199 rc = put_entry(buf, sizeof(u32), 1, fp);
3125 if (rc) 3200 if (rc)
3126 return rc; 3201 return rc;
3127 3202
3128 for (ft = p->filename_trans; ft; ft = ft->next) { 3203 rc = put_entry(ft->name, sizeof(char), len, fp);
3129 len = strlen(ft->name); 3204 if (rc)
3130 buf[0] = cpu_to_le32(len); 3205 return rc;
3131 rc = put_entry(buf, sizeof(u32), 1, fp);
3132 if (rc)
3133 return rc;
3134 3206
3135 rc = put_entry(ft->name, sizeof(char), len, fp); 3207 buf[0] = ft->stype;
3136 if (rc) 3208 buf[1] = ft->ttype;
3137 return rc; 3209 buf[2] = ft->tclass;
3210 buf[3] = otype->otype;
3138 3211
3139 buf[0] = ft->stype; 3212 rc = put_entry(buf, sizeof(u32), 4, fp);
3140 buf[1] = ft->ttype; 3213 if (rc)
3141 buf[2] = ft->tclass; 3214 return rc;
3142 buf[3] = ft->otype;
3143 3215
3144 rc = put_entry(buf, sizeof(u32), 4, fp);
3145 if (rc)
3146 return rc;
3147 }
3148 return 0; 3216 return 0;
3149} 3217}
3218
3219static int filename_trans_write(struct policydb *p, void *fp)
3220{
3221 u32 nel;
3222 __le32 buf[1];
3223 int rc;
3224
3225 nel = 0;
3226 rc = hashtab_map(p->filename_trans, hashtab_cnt, &nel);
3227 if (rc)
3228 return rc;
3229
3230 buf[0] = cpu_to_le32(nel);
3231 rc = put_entry(buf, sizeof(u32), 1, fp);
3232 if (rc)
3233 return rc;
3234
3235 rc = hashtab_map(p->filename_trans, filename_write_helper, fp);
3236 if (rc)
3237 return rc;
3238
3239 return 0;
3240}
3241
3150/* 3242/*
3151 * Write the configuration data in a policy database 3243 * Write the configuration data in a policy database
3152 * structure to a policy database binary representation 3244 * structure to a policy database binary representation
@@ -3249,7 +3341,7 @@ int policydb_write(struct policydb *p, void *fp)
3249 if (rc) 3341 if (rc)
3250 return rc; 3342 return rc;
3251 3343
3252 rc = role_trans_write(p->role_tr, fp); 3344 rc = role_trans_write(p, fp);
3253 if (rc) 3345 if (rc)
3254 return rc; 3346 return rc;
3255 3347
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index 732ea4a68682..b846c0387180 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -72,17 +72,20 @@ struct role_datum {
72 72
73struct role_trans { 73struct role_trans {
74 u32 role; /* current role */ 74 u32 role; /* current role */
75 u32 type; /* program executable type */ 75 u32 type; /* program executable type, or new object type */
76 u32 tclass; /* process class, or new object class */
76 u32 new_role; /* new role */ 77 u32 new_role; /* new role */
77 struct role_trans *next; 78 struct role_trans *next;
78}; 79};
79 80
80struct filename_trans { 81struct filename_trans {
81 struct filename_trans *next;
82 u32 stype; /* current process */ 82 u32 stype; /* current process */
83 u32 ttype; /* parent dir context */ 83 u32 ttype; /* parent dir context */
84 u16 tclass; /* class of new object */ 84 u16 tclass; /* class of new object */
85 const char *name; /* last path component */ 85 const char *name; /* last path component */
86};
87
88struct filename_trans_datum {
86 u32 otype; /* expected of new object */ 89 u32 otype; /* expected of new object */
87}; 90};
88 91
@@ -227,7 +230,10 @@ struct policydb {
227 struct role_trans *role_tr; 230 struct role_trans *role_tr;
228 231
229 /* file transitions with the last path component */ 232 /* file transitions with the last path component */
230 struct filename_trans *filename_trans; 233 /* quickly exclude lookups when parent ttype has no rules */
234 struct ebitmap filename_trans_ttypes;
235 /* actual set of filename_trans rules */
236 struct hashtab *filename_trans;
231 237
232 /* bools indexed by (value - 1) */ 238 /* bools indexed by (value - 1) */
233 struct cond_bool_datum **bool_val_to_struct; 239 struct cond_bool_datum **bool_val_to_struct;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6ef4af47dac4..c3e4b52699f4 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1359,26 +1359,35 @@ out:
1359} 1359}
1360 1360
1361static void filename_compute_type(struct policydb *p, struct context *newcontext, 1361static void filename_compute_type(struct policydb *p, struct context *newcontext,
1362 u32 scon, u32 tcon, u16 tclass, 1362 u32 stype, u32 ttype, u16 tclass,
1363 const struct qstr *qstr) 1363 const char *objname)
1364{ 1364{
1365 struct filename_trans *ft; 1365 struct filename_trans ft;
1366 for (ft = p->filename_trans; ft; ft = ft->next) { 1366 struct filename_trans_datum *otype;
1367 if (ft->stype == scon && 1367
1368 ft->ttype == tcon && 1368 /*
1369 ft->tclass == tclass && 1369 * Most filename trans rules are going to live in specific directories
1370 !strcmp(ft->name, qstr->name)) { 1370 * like /dev or /var/run. This bitmap will quickly skip rule searches
1371 newcontext->type = ft->otype; 1371 * if the ttype does not contain any rules.
1372 return; 1372 */
1373 } 1373 if (!ebitmap_get_bit(&p->filename_trans_ttypes, ttype))
1374 } 1374 return;
1375
1376 ft.stype = stype;
1377 ft.ttype = ttype;
1378 ft.tclass = tclass;
1379 ft.name = objname;
1380
1381 otype = hashtab_search(p->filename_trans, &ft);
1382 if (otype)
1383 newcontext->type = otype->otype;
1375} 1384}
1376 1385
1377static int security_compute_sid(u32 ssid, 1386static int security_compute_sid(u32 ssid,
1378 u32 tsid, 1387 u32 tsid,
1379 u16 orig_tclass, 1388 u16 orig_tclass,
1380 u32 specified, 1389 u32 specified,
1381 const struct qstr *qstr, 1390 const char *objname,
1382 u32 *out_sid, 1391 u32 *out_sid,
1383 bool kern) 1392 bool kern)
1384{ 1393{
@@ -1478,23 +1487,21 @@ static int security_compute_sid(u32 ssid,
1478 newcontext.type = avdatum->data; 1487 newcontext.type = avdatum->data;
1479 } 1488 }
1480 1489
1481 /* if we have a qstr this is a file trans check so check those rules */ 1490 /* if we have a objname this is a file trans check so check those rules */
1482 if (qstr) 1491 if (objname)
1483 filename_compute_type(&policydb, &newcontext, scontext->type, 1492 filename_compute_type(&policydb, &newcontext, scontext->type,
1484 tcontext->type, tclass, qstr); 1493 tcontext->type, tclass, objname);
1485 1494
1486 /* Check for class-specific changes. */ 1495 /* Check for class-specific changes. */
1487 if (tclass == policydb.process_class) { 1496 if (specified & AVTAB_TRANSITION) {
1488 if (specified & AVTAB_TRANSITION) { 1497 /* Look for a role transition rule. */
1489 /* Look for a role transition rule. */ 1498 for (roletr = policydb.role_tr; roletr; roletr = roletr->next) {
1490 for (roletr = policydb.role_tr; roletr; 1499 if ((roletr->role == scontext->role) &&
1491 roletr = roletr->next) { 1500 (roletr->type == tcontext->type) &&
1492 if (roletr->role == scontext->role && 1501 (roletr->tclass == tclass)) {
1493 roletr->type == tcontext->type) { 1502 /* Use the role transition rule. */
1494 /* Use the role transition rule. */ 1503 newcontext.role = roletr->new_role;
1495 newcontext.role = roletr->new_role; 1504 break;
1496 break;
1497 }
1498 } 1505 }
1499 } 1506 }
1500 } 1507 }
@@ -1541,13 +1548,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,
1541 const struct qstr *qstr, u32 *out_sid) 1548 const struct qstr *qstr, u32 *out_sid)
1542{ 1549{
1543 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1550 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1544 qstr, out_sid, true); 1551 qstr ? qstr->name : NULL, out_sid, true);
1545} 1552}
1546 1553
1547int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) 1554int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass,
1555 const char *objname, u32 *out_sid)
1548{ 1556{
1549 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, 1557 return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION,
1550 NULL, out_sid, false); 1558 objname, out_sid, false);
1551} 1559}
1552 1560
1553/** 1561/**
@@ -3190,7 +3198,7 @@ out:
3190 * @len: length of data in bytes 3198 * @len: length of data in bytes
3191 * 3199 *
3192 */ 3200 */
3193int security_read_policy(void **data, ssize_t *len) 3201int security_read_policy(void **data, size_t *len)
3194{ 3202{
3195 int rc; 3203 int rc;
3196 struct policy_file fp; 3204 struct policy_file fp;
diff --git a/security/smack/smack.h b/security/smack/smack.h
index b449cfdad21c..2b6c6a516123 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -316,22 +316,17 @@ static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a,
316static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a, 316static inline void smk_ad_setfield_u_fs_path_dentry(struct smk_audit_info *a,
317 struct dentry *d) 317 struct dentry *d)
318{ 318{
319 a->a.u.fs.path.dentry = d; 319 a->a.u.dentry = d;
320}
321static inline void smk_ad_setfield_u_fs_path_mnt(struct smk_audit_info *a,
322 struct vfsmount *m)
323{
324 a->a.u.fs.path.mnt = m;
325} 320}
326static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a, 321static inline void smk_ad_setfield_u_fs_inode(struct smk_audit_info *a,
327 struct inode *i) 322 struct inode *i)
328{ 323{
329 a->a.u.fs.inode = i; 324 a->a.u.inode = i;
330} 325}
331static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a, 326static inline void smk_ad_setfield_u_fs_path(struct smk_audit_info *a,
332 struct path p) 327 struct path p)
333{ 328{
334 a->a.u.fs.path = p; 329 a->a.u.path = p;
335} 330}
336static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a, 331static inline void smk_ad_setfield_u_net_sk(struct smk_audit_info *a,
337 struct sock *sk) 332 struct sock *sk)
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 400a5d5cde61..9831a39c11f6 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -383,7 +383,7 @@ static int smack_sb_statfs(struct dentry *dentry)
383 int rc; 383 int rc;
384 struct smk_audit_info ad; 384 struct smk_audit_info ad;
385 385
386 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 386 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
387 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 387 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
388 388
389 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad); 389 rc = smk_curacc(sbp->smk_floor, MAY_READ, &ad);
@@ -407,7 +407,7 @@ static int smack_sb_mount(char *dev_name, struct path *path,
407 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security; 407 struct superblock_smack *sbp = path->mnt->mnt_sb->s_security;
408 struct smk_audit_info ad; 408 struct smk_audit_info ad;
409 409
410 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 410 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
411 smk_ad_setfield_u_fs_path(&ad, *path); 411 smk_ad_setfield_u_fs_path(&ad, *path);
412 412
413 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); 413 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
@@ -425,10 +425,13 @@ static int smack_sb_umount(struct vfsmount *mnt, int flags)
425{ 425{
426 struct superblock_smack *sbp; 426 struct superblock_smack *sbp;
427 struct smk_audit_info ad; 427 struct smk_audit_info ad;
428 struct path path;
428 429
429 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 430 path.dentry = mnt->mnt_root;
430 smk_ad_setfield_u_fs_path_dentry(&ad, mnt->mnt_root); 431 path.mnt = mnt;
431 smk_ad_setfield_u_fs_path_mnt(&ad, mnt); 432
433 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
434 smk_ad_setfield_u_fs_path(&ad, path);
432 435
433 sbp = mnt->mnt_sb->s_security; 436 sbp = mnt->mnt_sb->s_security;
434 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad); 437 return smk_curacc(sbp->smk_floor, MAY_WRITE, &ad);
@@ -563,7 +566,7 @@ static int smack_inode_link(struct dentry *old_dentry, struct inode *dir,
563 struct smk_audit_info ad; 566 struct smk_audit_info ad;
564 int rc; 567 int rc;
565 568
566 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 569 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
567 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); 570 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
568 571
569 isp = smk_of_inode(old_dentry->d_inode); 572 isp = smk_of_inode(old_dentry->d_inode);
@@ -592,7 +595,7 @@ static int smack_inode_unlink(struct inode *dir, struct dentry *dentry)
592 struct smk_audit_info ad; 595 struct smk_audit_info ad;
593 int rc; 596 int rc;
594 597
595 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 598 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
596 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 599 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
597 600
598 /* 601 /*
@@ -623,7 +626,7 @@ static int smack_inode_rmdir(struct inode *dir, struct dentry *dentry)
623 struct smk_audit_info ad; 626 struct smk_audit_info ad;
624 int rc; 627 int rc;
625 628
626 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 629 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
627 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 630 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
628 631
629 /* 632 /*
@@ -663,7 +666,7 @@ static int smack_inode_rename(struct inode *old_inode,
663 char *isp; 666 char *isp;
664 struct smk_audit_info ad; 667 struct smk_audit_info ad;
665 668
666 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 669 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
667 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry); 670 smk_ad_setfield_u_fs_path_dentry(&ad, old_dentry);
668 671
669 isp = smk_of_inode(old_dentry->d_inode); 672 isp = smk_of_inode(old_dentry->d_inode);
@@ -700,7 +703,7 @@ static int smack_inode_permission(struct inode *inode, int mask, unsigned flags)
700 /* May be droppable after audit */ 703 /* May be droppable after audit */
701 if (flags & IPERM_FLAG_RCU) 704 if (flags & IPERM_FLAG_RCU)
702 return -ECHILD; 705 return -ECHILD;
703 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 706 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_INODE);
704 smk_ad_setfield_u_fs_inode(&ad, inode); 707 smk_ad_setfield_u_fs_inode(&ad, inode);
705 return smk_curacc(smk_of_inode(inode), mask, &ad); 708 return smk_curacc(smk_of_inode(inode), mask, &ad);
706} 709}
@@ -720,7 +723,7 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
720 */ 723 */
721 if (iattr->ia_valid & ATTR_FORCE) 724 if (iattr->ia_valid & ATTR_FORCE)
722 return 0; 725 return 0;
723 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 726 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
724 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 727 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
725 728
726 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 729 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
@@ -736,10 +739,13 @@ static int smack_inode_setattr(struct dentry *dentry, struct iattr *iattr)
736static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 739static int smack_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
737{ 740{
738 struct smk_audit_info ad; 741 struct smk_audit_info ad;
742 struct path path;
739 743
740 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 744 path.dentry = dentry;
741 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 745 path.mnt = mnt;
742 smk_ad_setfield_u_fs_path_mnt(&ad, mnt); 746
747 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
748 smk_ad_setfield_u_fs_path(&ad, path);
743 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 749 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
744} 750}
745 751
@@ -784,7 +790,7 @@ static int smack_inode_setxattr(struct dentry *dentry, const char *name,
784 } else 790 } else
785 rc = cap_inode_setxattr(dentry, name, value, size, flags); 791 rc = cap_inode_setxattr(dentry, name, value, size, flags);
786 792
787 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 793 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
788 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 794 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
789 795
790 if (rc == 0) 796 if (rc == 0)
@@ -845,7 +851,7 @@ static int smack_inode_getxattr(struct dentry *dentry, const char *name)
845{ 851{
846 struct smk_audit_info ad; 852 struct smk_audit_info ad;
847 853
848 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 854 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
849 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 855 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
850 856
851 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad); 857 return smk_curacc(smk_of_inode(dentry->d_inode), MAY_READ, &ad);
@@ -877,7 +883,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name)
877 } else 883 } else
878 rc = cap_inode_removexattr(dentry, name); 884 rc = cap_inode_removexattr(dentry, name);
879 885
880 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 886 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_DENTRY);
881 smk_ad_setfield_u_fs_path_dentry(&ad, dentry); 887 smk_ad_setfield_u_fs_path_dentry(&ad, dentry);
882 if (rc == 0) 888 if (rc == 0)
883 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad); 889 rc = smk_curacc(smk_of_inode(dentry->d_inode), MAY_WRITE, &ad);
@@ -1047,7 +1053,7 @@ static int smack_file_ioctl(struct file *file, unsigned int cmd,
1047 int rc = 0; 1053 int rc = 0;
1048 struct smk_audit_info ad; 1054 struct smk_audit_info ad;
1049 1055
1050 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 1056 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1051 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1057 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1052 1058
1053 if (_IOC_DIR(cmd) & _IOC_WRITE) 1059 if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -1070,8 +1076,8 @@ static int smack_file_lock(struct file *file, unsigned int cmd)
1070{ 1076{
1071 struct smk_audit_info ad; 1077 struct smk_audit_info ad;
1072 1078
1073 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 1079 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1074 smk_ad_setfield_u_fs_path_dentry(&ad, file->f_path.dentry); 1080 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1075 return smk_curacc(file->f_security, MAY_WRITE, &ad); 1081 return smk_curacc(file->f_security, MAY_WRITE, &ad);
1076} 1082}
1077 1083
@@ -1089,7 +1095,7 @@ static int smack_file_fcntl(struct file *file, unsigned int cmd,
1089 struct smk_audit_info ad; 1095 struct smk_audit_info ad;
1090 int rc; 1096 int rc;
1091 1097
1092 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_FS); 1098 smk_ad_init(&ad, __func__, LSM_AUDIT_DATA_PATH);
1093 smk_ad_setfield_u_fs_path(&ad, file->f_path); 1099 smk_ad_setfield_u_fs_path(&ad, file->f_path);
1094 1100
1095 switch (cmd) { 1101 switch (cmd) {
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
diff --git a/security/tomoyo/mount.c b/security/tomoyo/mount.c
index 82bf8c2390bc..162a864dba24 100644
--- a/security/tomoyo/mount.c
+++ b/security/tomoyo/mount.c
@@ -143,6 +143,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
143 goto out; 143 goto out;
144 } 144 }
145 requested_dev_name = tomoyo_realpath_from_path(&path); 145 requested_dev_name = tomoyo_realpath_from_path(&path);
146 path_put(&path);
146 if (!requested_dev_name) { 147 if (!requested_dev_name) {
147 error = -ENOENT; 148 error = -ENOENT;
148 goto out; 149 goto out;
diff --git a/security/tomoyo/util.c b/security/tomoyo/util.c
index 9bfc1ee8222d..6d5393204d95 100644
--- a/security/tomoyo/util.c
+++ b/security/tomoyo/util.c
@@ -390,7 +390,7 @@ bool tomoyo_correct_domain(const unsigned char *domainname)
390 if (!cp) 390 if (!cp)
391 break; 391 break;
392 if (*domainname != '/' || 392 if (*domainname != '/' ||
393 !tomoyo_correct_word2(domainname, cp - domainname - 1)) 393 !tomoyo_correct_word2(domainname, cp - domainname))
394 goto out; 394 goto out;
395 domainname = cp + 1; 395 domainname = cp + 1;
396 } 396 }