diff options
36 files changed, 435 insertions, 429 deletions
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index 9d7c99394ec6..640f65c6ef84 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c | |||
@@ -1752,12 +1752,12 @@ static int comedi_open(struct inode *inode, struct file *file) | |||
1752 | mutex_lock(&dev->mutex); | 1752 | mutex_lock(&dev->mutex); |
1753 | if (dev->attached) | 1753 | if (dev->attached) |
1754 | goto ok; | 1754 | goto ok; |
1755 | if (!capable(CAP_SYS_MODULE) && dev->in_request_module) { | 1755 | if (!capable(CAP_NET_ADMIN) && dev->in_request_module) { |
1756 | DPRINTK("in request module\n"); | 1756 | DPRINTK("in request module\n"); |
1757 | mutex_unlock(&dev->mutex); | 1757 | mutex_unlock(&dev->mutex); |
1758 | return -ENODEV; | 1758 | return -ENODEV; |
1759 | } | 1759 | } |
1760 | if (capable(CAP_SYS_MODULE) && dev->in_request_module) | 1760 | if (capable(CAP_NET_ADMIN) && dev->in_request_module) |
1761 | goto ok; | 1761 | goto ok; |
1762 | 1762 | ||
1763 | dev->in_request_module = 1; | 1763 | dev->in_request_module = 1; |
@@ -1770,8 +1770,8 @@ static int comedi_open(struct inode *inode, struct file *file) | |||
1770 | 1770 | ||
1771 | dev->in_request_module = 0; | 1771 | dev->in_request_module = 0; |
1772 | 1772 | ||
1773 | if (!dev->attached && !capable(CAP_SYS_MODULE)) { | 1773 | if (!dev->attached && !capable(CAP_NET_ADMIN)) { |
1774 | DPRINTK("not attached and not CAP_SYS_MODULE\n"); | 1774 | DPRINTK("not attached and not CAP_NET_ADMIN\n"); |
1775 | mutex_unlock(&dev->mutex); | 1775 | mutex_unlock(&dev->mutex); |
1776 | return -ENODEV; | 1776 | return -ENODEV; |
1777 | } | 1777 | } |
diff --git a/fs/locks.c b/fs/locks.c index b6440f52178f..52366e877d76 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1591,7 +1591,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) | |||
1591 | if (can_sleep) | 1591 | if (can_sleep) |
1592 | lock->fl_flags |= FL_SLEEP; | 1592 | lock->fl_flags |= FL_SLEEP; |
1593 | 1593 | ||
1594 | error = security_file_lock(filp, cmd); | 1594 | error = security_file_lock(filp, lock->fl_type); |
1595 | if (error) | 1595 | if (error) |
1596 | goto out_free; | 1596 | goto out_free; |
1597 | 1597 | ||
diff --git a/include/linux/cred.h b/include/linux/cred.h index 4fa999696310..b3c76e815d66 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -186,7 +186,8 @@ static inline struct cred *get_new_cred(struct cred *cred) | |||
186 | */ | 186 | */ |
187 | static inline const struct cred *get_cred(const struct cred *cred) | 187 | static inline const struct cred *get_cred(const struct cred *cred) |
188 | { | 188 | { |
189 | return get_new_cred((struct cred *) cred); | 189 | struct cred *nonconst_cred = (struct cred *) cred; |
190 | return get_new_cred(nonconst_cred); | ||
190 | } | 191 | } |
191 | 192 | ||
192 | /** | 193 | /** |
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h index e461b2c3d711..190c37854870 100644 --- a/include/linux/lsm_audit.h +++ b/include/linux/lsm_audit.h | |||
@@ -33,6 +33,7 @@ struct common_audit_data { | |||
33 | #define LSM_AUDIT_DATA_IPC 4 | 33 | #define LSM_AUDIT_DATA_IPC 4 |
34 | #define LSM_AUDIT_DATA_TASK 5 | 34 | #define LSM_AUDIT_DATA_TASK 5 |
35 | #define LSM_AUDIT_DATA_KEY 6 | 35 | #define LSM_AUDIT_DATA_KEY 6 |
36 | #define LSM_AUDIT_NO_AUDIT 7 | ||
36 | struct task_struct *tsk; | 37 | struct task_struct *tsk; |
37 | union { | 38 | union { |
38 | struct { | 39 | struct { |
@@ -66,16 +67,19 @@ struct common_audit_data { | |||
66 | } key_struct; | 67 | } key_struct; |
67 | #endif | 68 | #endif |
68 | } u; | 69 | } u; |
69 | const char *function; | ||
70 | /* this union contains LSM specific data */ | 70 | /* this union contains LSM specific data */ |
71 | union { | 71 | union { |
72 | #ifdef CONFIG_SECURITY_SMACK | ||
72 | /* SMACK data */ | 73 | /* SMACK data */ |
73 | struct smack_audit_data { | 74 | struct smack_audit_data { |
75 | const char *function; | ||
74 | char *subject; | 76 | char *subject; |
75 | char *object; | 77 | char *object; |
76 | char *request; | 78 | char *request; |
77 | int result; | 79 | int result; |
78 | } smack_audit_data; | 80 | } smack_audit_data; |
81 | #endif | ||
82 | #ifdef CONFIG_SECURITY_SELINUX | ||
79 | /* SELinux data */ | 83 | /* SELinux data */ |
80 | struct { | 84 | struct { |
81 | u32 ssid; | 85 | u32 ssid; |
@@ -83,10 +87,12 @@ struct common_audit_data { | |||
83 | u16 tclass; | 87 | u16 tclass; |
84 | u32 requested; | 88 | u32 requested; |
85 | u32 audited; | 89 | u32 audited; |
90 | u32 denied; | ||
86 | struct av_decision *avd; | 91 | struct av_decision *avd; |
87 | int result; | 92 | int result; |
88 | } selinux_audit_data; | 93 | } selinux_audit_data; |
89 | } lsm_priv; | 94 | #endif |
95 | }; | ||
90 | /* these callback will be implemented by a specific LSM */ | 96 | /* these callback will be implemented by a specific LSM */ |
91 | void (*lsm_pre_audit)(struct audit_buffer *, void *); | 97 | void (*lsm_pre_audit)(struct audit_buffer *, void *); |
92 | void (*lsm_post_audit)(struct audit_buffer *, void *); | 98 | void (*lsm_post_audit)(struct audit_buffer *, void *); |
@@ -104,7 +110,7 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, | |||
104 | /* Initialize an LSM audit data structure. */ | 110 | /* Initialize an LSM audit data structure. */ |
105 | #define COMMON_AUDIT_DATA_INIT(_d, _t) \ | 111 | #define COMMON_AUDIT_DATA_INIT(_d, _t) \ |
106 | { memset((_d), 0, sizeof(struct common_audit_data)); \ | 112 | { memset((_d), 0, sizeof(struct common_audit_data)); \ |
107 | (_d)->type = LSM_AUDIT_DATA_##_t; (_d)->function = __func__; } | 113 | (_d)->type = LSM_AUDIT_DATA_##_t; } |
108 | 114 | ||
109 | void common_lsm_audit(struct common_audit_data *a); | 115 | void common_lsm_audit(struct common_audit_data *a); |
110 | 116 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index 0f1ea4a66957..5c7ce13c1696 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -2077,7 +2077,7 @@ static inline unsigned long wait_task_inactive(struct task_struct *p, | |||
2077 | #define for_each_process(p) \ | 2077 | #define for_each_process(p) \ |
2078 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) | 2078 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) |
2079 | 2079 | ||
2080 | extern bool is_single_threaded(struct task_struct *); | 2080 | extern bool current_is_single_threaded(void); |
2081 | 2081 | ||
2082 | /* | 2082 | /* |
2083 | * Careful: do_each_thread/while_each_thread is a double loop so | 2083 | * Careful: do_each_thread/while_each_thread is a double loop so |
diff --git a/include/linux/security.h b/include/linux/security.h index 1f16eea2017b..a16d6b7c4ebe 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -53,7 +53,7 @@ struct audit_krule; | |||
53 | extern int cap_capable(struct task_struct *tsk, const struct cred *cred, | 53 | extern int cap_capable(struct task_struct *tsk, const struct cred *cred, |
54 | int cap, int audit); | 54 | int cap, int audit); |
55 | extern int cap_settime(struct timespec *ts, struct timezone *tz); | 55 | extern int cap_settime(struct timespec *ts, struct timezone *tz); |
56 | extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); | 56 | extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); |
57 | extern int cap_ptrace_traceme(struct task_struct *parent); | 57 | extern int cap_ptrace_traceme(struct task_struct *parent); |
58 | extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); | 58 | extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); |
59 | extern int cap_capset(struct cred *new, const struct cred *old, | 59 | extern int cap_capset(struct cred *new, const struct cred *old, |
@@ -678,6 +678,10 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
678 | * @inode points to the inode to use as a reference. | 678 | * @inode points to the inode to use as a reference. |
679 | * The current task must be the one that nominated @inode. | 679 | * The current task must be the one that nominated @inode. |
680 | * Return 0 if successful. | 680 | * Return 0 if successful. |
681 | * @kernel_module_request: | ||
682 | * Ability to trigger the kernel to automatically upcall to userspace for | ||
683 | * userspace to load a kernel module with the given name. | ||
684 | * Return 0 if successful. | ||
681 | * @task_setuid: | 685 | * @task_setuid: |
682 | * Check permission before setting one or more of the user identity | 686 | * Check permission before setting one or more of the user identity |
683 | * attributes of the current process. The @flags parameter indicates | 687 | * attributes of the current process. The @flags parameter indicates |
@@ -1229,7 +1233,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1229 | * @alter contains the flag indicating whether changes are to be made. | 1233 | * @alter contains the flag indicating whether changes are to be made. |
1230 | * Return 0 if permission is granted. | 1234 | * Return 0 if permission is granted. |
1231 | * | 1235 | * |
1232 | * @ptrace_may_access: | 1236 | * @ptrace_access_check: |
1233 | * Check permission before allowing the current process to trace the | 1237 | * Check permission before allowing the current process to trace the |
1234 | * @child process. | 1238 | * @child process. |
1235 | * Security modules may also want to perform a process tracing check | 1239 | * Security modules may also want to perform a process tracing check |
@@ -1244,7 +1248,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1244 | * Check that the @parent process has sufficient permission to trace the | 1248 | * Check that the @parent process has sufficient permission to trace the |
1245 | * current process before allowing the current process to present itself | 1249 | * current process before allowing the current process to present itself |
1246 | * to the @parent process for tracing. | 1250 | * to the @parent process for tracing. |
1247 | * The parent process will still have to undergo the ptrace_may_access | 1251 | * The parent process will still have to undergo the ptrace_access_check |
1248 | * checks before it is allowed to trace this one. | 1252 | * checks before it is allowed to trace this one. |
1249 | * @parent contains the task_struct structure for debugger process. | 1253 | * @parent contains the task_struct structure for debugger process. |
1250 | * Return 0 if permission is granted. | 1254 | * Return 0 if permission is granted. |
@@ -1356,7 +1360,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1356 | struct security_operations { | 1360 | struct security_operations { |
1357 | char name[SECURITY_NAME_MAX + 1]; | 1361 | char name[SECURITY_NAME_MAX + 1]; |
1358 | 1362 | ||
1359 | int (*ptrace_may_access) (struct task_struct *child, unsigned int mode); | 1363 | int (*ptrace_access_check) (struct task_struct *child, unsigned int mode); |
1360 | int (*ptrace_traceme) (struct task_struct *parent); | 1364 | int (*ptrace_traceme) (struct task_struct *parent); |
1361 | int (*capget) (struct task_struct *target, | 1365 | int (*capget) (struct task_struct *target, |
1362 | kernel_cap_t *effective, | 1366 | kernel_cap_t *effective, |
@@ -1489,6 +1493,7 @@ struct security_operations { | |||
1489 | void (*cred_commit)(struct cred *new, const struct cred *old); | 1493 | void (*cred_commit)(struct cred *new, const struct cred *old); |
1490 | int (*kernel_act_as)(struct cred *new, u32 secid); | 1494 | int (*kernel_act_as)(struct cred *new, u32 secid); |
1491 | int (*kernel_create_files_as)(struct cred *new, struct inode *inode); | 1495 | int (*kernel_create_files_as)(struct cred *new, struct inode *inode); |
1496 | int (*kernel_module_request)(void); | ||
1492 | int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags); | 1497 | int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags); |
1493 | int (*task_fix_setuid) (struct cred *new, const struct cred *old, | 1498 | int (*task_fix_setuid) (struct cred *new, const struct cred *old, |
1494 | int flags); | 1499 | int flags); |
@@ -1637,7 +1642,7 @@ extern int security_module_enable(struct security_operations *ops); | |||
1637 | extern int register_security(struct security_operations *ops); | 1642 | extern int register_security(struct security_operations *ops); |
1638 | 1643 | ||
1639 | /* Security operations */ | 1644 | /* Security operations */ |
1640 | int security_ptrace_may_access(struct task_struct *child, unsigned int mode); | 1645 | int security_ptrace_access_check(struct task_struct *child, unsigned int mode); |
1641 | int security_ptrace_traceme(struct task_struct *parent); | 1646 | int security_ptrace_traceme(struct task_struct *parent); |
1642 | int security_capget(struct task_struct *target, | 1647 | int security_capget(struct task_struct *target, |
1643 | kernel_cap_t *effective, | 1648 | kernel_cap_t *effective, |
@@ -1741,6 +1746,7 @@ int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); | |||
1741 | void security_commit_creds(struct cred *new, const struct cred *old); | 1746 | void security_commit_creds(struct cred *new, const struct cred *old); |
1742 | int security_kernel_act_as(struct cred *new, u32 secid); | 1747 | int security_kernel_act_as(struct cred *new, u32 secid); |
1743 | int security_kernel_create_files_as(struct cred *new, struct inode *inode); | 1748 | int security_kernel_create_files_as(struct cred *new, struct inode *inode); |
1749 | int security_kernel_module_request(void); | ||
1744 | int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags); | 1750 | int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags); |
1745 | int security_task_fix_setuid(struct cred *new, const struct cred *old, | 1751 | int security_task_fix_setuid(struct cred *new, const struct cred *old, |
1746 | int flags); | 1752 | int flags); |
@@ -1818,10 +1824,10 @@ static inline int security_init(void) | |||
1818 | return 0; | 1824 | return 0; |
1819 | } | 1825 | } |
1820 | 1826 | ||
1821 | static inline int security_ptrace_may_access(struct task_struct *child, | 1827 | static inline int security_ptrace_access_check(struct task_struct *child, |
1822 | unsigned int mode) | 1828 | unsigned int mode) |
1823 | { | 1829 | { |
1824 | return cap_ptrace_may_access(child, mode); | 1830 | return cap_ptrace_access_check(child, mode); |
1825 | } | 1831 | } |
1826 | 1832 | ||
1827 | static inline int security_ptrace_traceme(struct task_struct *parent) | 1833 | static inline int security_ptrace_traceme(struct task_struct *parent) |
@@ -2292,6 +2298,11 @@ static inline int security_kernel_create_files_as(struct cred *cred, | |||
2292 | return 0; | 2298 | return 0; |
2293 | } | 2299 | } |
2294 | 2300 | ||
2301 | static inline int security_kernel_module_request(void) | ||
2302 | { | ||
2303 | return 0; | ||
2304 | } | ||
2305 | |||
2295 | static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, | 2306 | static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, |
2296 | int flags) | 2307 | int flags) |
2297 | { | 2308 | { |
diff --git a/kernel/kmod.c b/kernel/kmod.c index 385c31a1bdbf..5a7ae57f983f 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c | |||
@@ -78,6 +78,10 @@ int __request_module(bool wait, const char *fmt, ...) | |||
78 | #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ | 78 | #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ |
79 | static int kmod_loop_msg; | 79 | static int kmod_loop_msg; |
80 | 80 | ||
81 | ret = security_kernel_module_request(); | ||
82 | if (ret) | ||
83 | return ret; | ||
84 | |||
81 | va_start(args, fmt); | 85 | va_start(args, fmt); |
82 | ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); | 86 | ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); |
83 | va_end(args); | 87 | va_end(args); |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 082c320e4dbf..307c285af59e 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -152,7 +152,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode) | |||
152 | if (!dumpable && !capable(CAP_SYS_PTRACE)) | 152 | if (!dumpable && !capable(CAP_SYS_PTRACE)) |
153 | return -EPERM; | 153 | return -EPERM; |
154 | 154 | ||
155 | return security_ptrace_may_access(task, mode); | 155 | return security_ptrace_access_check(task, mode); |
156 | } | 156 | } |
157 | 157 | ||
158 | bool ptrace_may_access(struct task_struct *task, unsigned int mode) | 158 | bool ptrace_may_access(struct task_struct *task, unsigned int mode) |
diff --git a/lib/is_single_threaded.c b/lib/is_single_threaded.c index f1ed2fe76c65..bd2bea963364 100644 --- a/lib/is_single_threaded.c +++ b/lib/is_single_threaded.c | |||
@@ -12,34 +12,47 @@ | |||
12 | 12 | ||
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | 14 | ||
15 | /** | 15 | /* |
16 | * is_single_threaded - Determine if a thread group is single-threaded or not | 16 | * Returns true if the task does not share ->mm with another thread/process. |
17 | * @p: A task in the thread group in question | ||
18 | * | ||
19 | * This returns true if the thread group to which a task belongs is single | ||
20 | * threaded, false if it is not. | ||
21 | */ | 17 | */ |
22 | bool is_single_threaded(struct task_struct *p) | 18 | bool current_is_single_threaded(void) |
23 | { | 19 | { |
24 | struct task_struct *g, *t; | 20 | struct task_struct *task = current; |
25 | struct mm_struct *mm = p->mm; | 21 | struct mm_struct *mm = task->mm; |
22 | struct task_struct *p, *t; | ||
23 | bool ret; | ||
26 | 24 | ||
27 | if (atomic_read(&p->signal->count) != 1) | 25 | if (atomic_read(&task->signal->live) != 1) |
28 | goto no; | 26 | return false; |
29 | 27 | ||
30 | if (atomic_read(&p->mm->mm_users) != 1) { | 28 | if (atomic_read(&mm->mm_users) == 1) |
31 | read_lock(&tasklist_lock); | 29 | return true; |
32 | do_each_thread(g, t) { | ||
33 | if (t->mm == mm && t != p) | ||
34 | goto no_unlock; | ||
35 | } while_each_thread(g, t); | ||
36 | read_unlock(&tasklist_lock); | ||
37 | } | ||
38 | 30 | ||
39 | return true; | 31 | ret = false; |
32 | rcu_read_lock(); | ||
33 | for_each_process(p) { | ||
34 | if (unlikely(p->flags & PF_KTHREAD)) | ||
35 | continue; | ||
36 | if (unlikely(p == task->group_leader)) | ||
37 | continue; | ||
38 | |||
39 | t = p; | ||
40 | do { | ||
41 | if (unlikely(t->mm == mm)) | ||
42 | goto found; | ||
43 | if (likely(t->mm)) | ||
44 | break; | ||
45 | /* | ||
46 | * t->mm == NULL. Make sure next_thread/next_task | ||
47 | * will see other CLONE_VM tasks which might be | ||
48 | * forked before exiting. | ||
49 | */ | ||
50 | smp_rmb(); | ||
51 | } while_each_thread(p, t); | ||
52 | } | ||
53 | ret = true; | ||
54 | found: | ||
55 | rcu_read_unlock(); | ||
40 | 56 | ||
41 | no_unlock: | 57 | return ret; |
42 | read_unlock(&tasklist_lock); | ||
43 | no: | ||
44 | return false; | ||
45 | } | 58 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 6a94475aee85..278d489aad3b 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1031,7 +1031,7 @@ void dev_load(struct net *net, const char *name) | |||
1031 | dev = __dev_get_by_name(net, name); | 1031 | dev = __dev_get_by_name(net, name); |
1032 | read_unlock(&dev_base_lock); | 1032 | read_unlock(&dev_base_lock); |
1033 | 1033 | ||
1034 | if (!dev && capable(CAP_SYS_MODULE)) | 1034 | if (!dev && capable(CAP_NET_ADMIN)) |
1035 | request_module("%s", name); | 1035 | request_module("%s", name); |
1036 | } | 1036 | } |
1037 | 1037 | ||
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index e92beb9e55e0..6428b342b164 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
@@ -116,7 +116,7 @@ int tcp_set_default_congestion_control(const char *name) | |||
116 | spin_lock(&tcp_cong_list_lock); | 116 | spin_lock(&tcp_cong_list_lock); |
117 | ca = tcp_ca_find(name); | 117 | ca = tcp_ca_find(name); |
118 | #ifdef CONFIG_MODULES | 118 | #ifdef CONFIG_MODULES |
119 | if (!ca && capable(CAP_SYS_MODULE)) { | 119 | if (!ca && capable(CAP_NET_ADMIN)) { |
120 | spin_unlock(&tcp_cong_list_lock); | 120 | spin_unlock(&tcp_cong_list_lock); |
121 | 121 | ||
122 | request_module("tcp_%s", name); | 122 | request_module("tcp_%s", name); |
@@ -246,7 +246,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) | |||
246 | 246 | ||
247 | #ifdef CONFIG_MODULES | 247 | #ifdef CONFIG_MODULES |
248 | /* not found attempt to autoload module */ | 248 | /* not found attempt to autoload module */ |
249 | if (!ca && capable(CAP_SYS_MODULE)) { | 249 | if (!ca && capable(CAP_NET_ADMIN)) { |
250 | rcu_read_unlock(); | 250 | rcu_read_unlock(); |
251 | request_module("tcp_%s", name); | 251 | request_module("tcp_%s", name); |
252 | rcu_read_lock(); | 252 | rcu_read_lock(); |
diff --git a/security/Makefile b/security/Makefile index b56e7f9ecbc2..95ecc06392d7 100644 --- a/security/Makefile +++ b/security/Makefile | |||
@@ -16,9 +16,7 @@ obj-$(CONFIG_SECURITYFS) += inode.o | |||
16 | # Must precede capability.o in order to stack properly. | 16 | # Must precede capability.o in order to stack properly. |
17 | obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o | 17 | obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o |
18 | obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o | 18 | obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o |
19 | ifeq ($(CONFIG_AUDIT),y) | 19 | obj-$(CONFIG_AUDIT) += lsm_audit.o |
20 | obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o | ||
21 | endif | ||
22 | obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o | 20 | obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o |
23 | obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o | 21 | obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o |
24 | obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o | 22 | obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o |
diff --git a/security/capability.c b/security/capability.c index 88f752e8152c..1b943f54b2ea 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -396,6 +396,11 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
396 | return 0; | 396 | return 0; |
397 | } | 397 | } |
398 | 398 | ||
399 | static int cap_kernel_module_request(void) | ||
400 | { | ||
401 | return 0; | ||
402 | } | ||
403 | |||
399 | static int cap_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) | 404 | static int cap_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) |
400 | { | 405 | { |
401 | return 0; | 406 | return 0; |
@@ -854,7 +859,7 @@ struct security_operations default_security_ops = { | |||
854 | 859 | ||
855 | void security_fixup_ops(struct security_operations *ops) | 860 | void security_fixup_ops(struct security_operations *ops) |
856 | { | 861 | { |
857 | set_to_cap_if_null(ops, ptrace_may_access); | 862 | set_to_cap_if_null(ops, ptrace_access_check); |
858 | set_to_cap_if_null(ops, ptrace_traceme); | 863 | set_to_cap_if_null(ops, ptrace_traceme); |
859 | set_to_cap_if_null(ops, capget); | 864 | set_to_cap_if_null(ops, capget); |
860 | set_to_cap_if_null(ops, capset); | 865 | set_to_cap_if_null(ops, capset); |
@@ -945,6 +950,7 @@ void security_fixup_ops(struct security_operations *ops) | |||
945 | set_to_cap_if_null(ops, cred_commit); | 950 | set_to_cap_if_null(ops, cred_commit); |
946 | set_to_cap_if_null(ops, kernel_act_as); | 951 | set_to_cap_if_null(ops, kernel_act_as); |
947 | set_to_cap_if_null(ops, kernel_create_files_as); | 952 | set_to_cap_if_null(ops, kernel_create_files_as); |
953 | set_to_cap_if_null(ops, kernel_module_request); | ||
948 | set_to_cap_if_null(ops, task_setuid); | 954 | set_to_cap_if_null(ops, task_setuid); |
949 | set_to_cap_if_null(ops, task_fix_setuid); | 955 | set_to_cap_if_null(ops, task_fix_setuid); |
950 | set_to_cap_if_null(ops, task_setgid); | 956 | set_to_cap_if_null(ops, task_setgid); |
diff --git a/security/commoncap.c b/security/commoncap.c index e3097c0a1311..fe30751a6cd9 100644 --- a/security/commoncap.c +++ b/security/commoncap.c | |||
@@ -101,7 +101,7 @@ int cap_settime(struct timespec *ts, struct timezone *tz) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * cap_ptrace_may_access - Determine whether the current process may access | 104 | * cap_ptrace_access_check - Determine whether the current process may access |
105 | * another | 105 | * another |
106 | * @child: The process to be accessed | 106 | * @child: The process to be accessed |
107 | * @mode: The mode of attachment. | 107 | * @mode: The mode of attachment. |
@@ -109,7 +109,7 @@ int cap_settime(struct timespec *ts, struct timezone *tz) | |||
109 | * Determine whether a process may access another, returning 0 if permission | 109 | * Determine whether a process may access another, returning 0 if permission |
110 | * granted, -ve if denied. | 110 | * granted, -ve if denied. |
111 | */ | 111 | */ |
112 | int cap_ptrace_may_access(struct task_struct *child, unsigned int mode) | 112 | int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) |
113 | { | 113 | { |
114 | int ret = 0; | 114 | int ret = 0; |
115 | 115 | ||
diff --git a/security/keys/proc.c b/security/keys/proc.c index 769f9bdfd2b3..39793c774f33 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c | |||
@@ -120,6 +120,7 @@ static int proc_keys_open(struct inode *inode, struct file *file) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | static void *proc_keys_start(struct seq_file *p, loff_t *_pos) | 122 | static void *proc_keys_start(struct seq_file *p, loff_t *_pos) |
123 | __acquires(key_serial_lock) | ||
123 | { | 124 | { |
124 | struct rb_node *_p; | 125 | struct rb_node *_p; |
125 | loff_t pos = *_pos; | 126 | loff_t pos = *_pos; |
@@ -144,6 +145,7 @@ static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) | |||
144 | } | 145 | } |
145 | 146 | ||
146 | static void proc_keys_stop(struct seq_file *p, void *v) | 147 | static void proc_keys_stop(struct seq_file *p, void *v) |
148 | __releases(key_serial_lock) | ||
147 | { | 149 | { |
148 | spin_unlock(&key_serial_lock); | 150 | spin_unlock(&key_serial_lock); |
149 | } | 151 | } |
@@ -257,6 +259,7 @@ static int proc_key_users_open(struct inode *inode, struct file *file) | |||
257 | } | 259 | } |
258 | 260 | ||
259 | static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) | 261 | static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) |
262 | __acquires(key_user_lock) | ||
260 | { | 263 | { |
261 | struct rb_node *_p; | 264 | struct rb_node *_p; |
262 | loff_t pos = *_pos; | 265 | loff_t pos = *_pos; |
@@ -281,6 +284,7 @@ static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) | |||
281 | } | 284 | } |
282 | 285 | ||
283 | static void proc_key_users_stop(struct seq_file *p, void *v) | 286 | static void proc_key_users_stop(struct seq_file *p, void *v) |
287 | __releases(key_user_lock) | ||
284 | { | 288 | { |
285 | spin_unlock(&key_user_lock); | 289 | spin_unlock(&key_user_lock); |
286 | } | 290 | } |
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index 276d27882ce8..ed929af466d3 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c | |||
@@ -702,7 +702,7 @@ long join_session_keyring(const char *name) | |||
702 | /* only permit this if there's a single thread in the thread group - | 702 | /* only permit this if there's a single thread in the thread group - |
703 | * this avoids us having to adjust the creds on all threads and risking | 703 | * this avoids us having to adjust the creds on all threads and risking |
704 | * ENOMEM */ | 704 | * ENOMEM */ |
705 | if (!is_single_threaded(current)) | 705 | if (!current_is_single_threaded()) |
706 | return -EMLINK; | 706 | return -EMLINK; |
707 | 707 | ||
708 | new = prepare_creds(); | 708 | new = prepare_creds(); |
diff --git a/security/lsm_audit.c b/security/lsm_audit.c index 94b868494b31..500aad0ebd6a 100644 --- a/security/lsm_audit.c +++ b/security/lsm_audit.c | |||
@@ -220,6 +220,8 @@ static void dump_common_audit_data(struct audit_buffer *ab, | |||
220 | } | 220 | } |
221 | 221 | ||
222 | switch (a->type) { | 222 | switch (a->type) { |
223 | case LSM_AUDIT_NO_AUDIT: | ||
224 | return; | ||
223 | case LSM_AUDIT_DATA_IPC: | 225 | case LSM_AUDIT_DATA_IPC: |
224 | audit_log_format(ab, " key=%d ", a->u.ipc_id); | 226 | audit_log_format(ab, " key=%d ", a->u.ipc_id); |
225 | break; | 227 | break; |
diff --git a/security/security.c b/security/security.c index dc7674fbfc7a..0e993f42ce3d 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -124,9 +124,9 @@ int register_security(struct security_operations *ops) | |||
124 | 124 | ||
125 | /* Security operations */ | 125 | /* Security operations */ |
126 | 126 | ||
127 | int security_ptrace_may_access(struct task_struct *child, unsigned int mode) | 127 | int security_ptrace_access_check(struct task_struct *child, unsigned int mode) |
128 | { | 128 | { |
129 | return security_ops->ptrace_may_access(child, mode); | 129 | return security_ops->ptrace_access_check(child, mode); |
130 | } | 130 | } |
131 | 131 | ||
132 | int security_ptrace_traceme(struct task_struct *parent) | 132 | int security_ptrace_traceme(struct task_struct *parent) |
@@ -709,6 +709,11 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
709 | return security_ops->kernel_create_files_as(new, inode); | 709 | return security_ops->kernel_create_files_as(new, inode); |
710 | } | 710 | } |
711 | 711 | ||
712 | int security_kernel_module_request(void) | ||
713 | { | ||
714 | return security_ops->kernel_module_request(); | ||
715 | } | ||
716 | |||
712 | int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) | 717 | int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) |
713 | { | 718 | { |
714 | return security_ops->task_setuid(id0, id1, id2, flags); | 719 | return security_ops->task_setuid(id0, id1, id2, flags); |
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index b2ab60859832..e3d19014259b 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c | |||
@@ -137,7 +137,7 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) | |||
137 | * @tclass: target security class | 137 | * @tclass: target security class |
138 | * @av: access vector | 138 | * @av: access vector |
139 | */ | 139 | */ |
140 | void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) | 140 | static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) |
141 | { | 141 | { |
142 | const char **common_pts = NULL; | 142 | const char **common_pts = NULL; |
143 | u32 common_base = 0; | 143 | u32 common_base = 0; |
@@ -492,23 +492,35 @@ out: | |||
492 | return node; | 492 | return node; |
493 | } | 493 | } |
494 | 494 | ||
495 | static inline void avc_print_ipv6_addr(struct audit_buffer *ab, | 495 | /** |
496 | struct in6_addr *addr, __be16 port, | 496 | * avc_audit_pre_callback - SELinux specific information |
497 | char *name1, char *name2) | 497 | * will be called by generic audit code |
498 | * @ab: the audit buffer | ||
499 | * @a: audit_data | ||
500 | */ | ||
501 | static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) | ||
498 | { | 502 | { |
499 | if (!ipv6_addr_any(addr)) | 503 | struct common_audit_data *ad = a; |
500 | audit_log_format(ab, " %s=%pI6", name1, addr); | 504 | audit_log_format(ab, "avc: %s ", |
501 | if (port) | 505 | ad->selinux_audit_data.denied ? "denied" : "granted"); |
502 | audit_log_format(ab, " %s=%d", name2, ntohs(port)); | 506 | avc_dump_av(ab, ad->selinux_audit_data.tclass, |
507 | ad->selinux_audit_data.audited); | ||
508 | audit_log_format(ab, " for "); | ||
503 | } | 509 | } |
504 | 510 | ||
505 | static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr, | 511 | /** |
506 | __be16 port, char *name1, char *name2) | 512 | * avc_audit_post_callback - SELinux specific information |
513 | * will be called by generic audit code | ||
514 | * @ab: the audit buffer | ||
515 | * @a: audit_data | ||
516 | */ | ||
517 | static void avc_audit_post_callback(struct audit_buffer *ab, void *a) | ||
507 | { | 518 | { |
508 | if (addr) | 519 | struct common_audit_data *ad = a; |
509 | audit_log_format(ab, " %s=%pI4", name1, &addr); | 520 | audit_log_format(ab, " "); |
510 | if (port) | 521 | avc_dump_query(ab, ad->selinux_audit_data.ssid, |
511 | audit_log_format(ab, " %s=%d", name2, ntohs(port)); | 522 | ad->selinux_audit_data.tsid, |
523 | ad->selinux_audit_data.tclass); | ||
512 | } | 524 | } |
513 | 525 | ||
514 | /** | 526 | /** |
@@ -532,13 +544,10 @@ static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr, | |||
532 | */ | 544 | */ |
533 | void avc_audit(u32 ssid, u32 tsid, | 545 | void avc_audit(u32 ssid, u32 tsid, |
534 | u16 tclass, u32 requested, | 546 | u16 tclass, u32 requested, |
535 | struct av_decision *avd, int result, struct avc_audit_data *a) | 547 | struct av_decision *avd, int result, struct common_audit_data *a) |
536 | { | 548 | { |
537 | struct task_struct *tsk = current; | 549 | struct common_audit_data stack_data; |
538 | struct inode *inode = NULL; | ||
539 | u32 denied, audited; | 550 | u32 denied, audited; |
540 | struct audit_buffer *ab; | ||
541 | |||
542 | denied = requested & ~avd->allowed; | 551 | denied = requested & ~avd->allowed; |
543 | if (denied) { | 552 | if (denied) { |
544 | audited = denied; | 553 | audited = denied; |
@@ -551,144 +560,20 @@ void avc_audit(u32 ssid, u32 tsid, | |||
551 | if (!(audited & avd->auditallow)) | 560 | if (!(audited & avd->auditallow)) |
552 | return; | 561 | return; |
553 | } | 562 | } |
554 | 563 | if (!a) { | |
555 | ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC); | 564 | a = &stack_data; |
556 | if (!ab) | 565 | memset(a, 0, sizeof(*a)); |
557 | return; /* audit_panic has been called */ | 566 | a->type = LSM_AUDIT_NO_AUDIT; |
558 | audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); | ||
559 | avc_dump_av(ab, tclass, audited); | ||
560 | audit_log_format(ab, " for "); | ||
561 | if (a && a->tsk) | ||
562 | tsk = a->tsk; | ||
563 | if (tsk && tsk->pid) { | ||
564 | audit_log_format(ab, " pid=%d comm=", tsk->pid); | ||
565 | audit_log_untrustedstring(ab, tsk->comm); | ||
566 | } | 567 | } |
567 | if (a) { | 568 | a->selinux_audit_data.tclass = tclass; |
568 | switch (a->type) { | 569 | a->selinux_audit_data.requested = requested; |
569 | case AVC_AUDIT_DATA_IPC: | 570 | a->selinux_audit_data.ssid = ssid; |
570 | audit_log_format(ab, " key=%d", a->u.ipc_id); | 571 | a->selinux_audit_data.tsid = tsid; |
571 | break; | 572 | a->selinux_audit_data.audited = audited; |
572 | case AVC_AUDIT_DATA_CAP: | 573 | a->selinux_audit_data.denied = denied; |
573 | audit_log_format(ab, " capability=%d", a->u.cap); | 574 | a->lsm_pre_audit = avc_audit_pre_callback; |
574 | break; | 575 | a->lsm_post_audit = avc_audit_post_callback; |
575 | case AVC_AUDIT_DATA_FS: | 576 | common_lsm_audit(a); |
576 | if (a->u.fs.path.dentry) { | ||
577 | struct dentry *dentry = a->u.fs.path.dentry; | ||
578 | if (a->u.fs.path.mnt) { | ||
579 | audit_log_d_path(ab, "path=", | ||
580 | &a->u.fs.path); | ||
581 | } else { | ||
582 | audit_log_format(ab, " name="); | ||
583 | audit_log_untrustedstring(ab, dentry->d_name.name); | ||
584 | } | ||
585 | inode = dentry->d_inode; | ||
586 | } else if (a->u.fs.inode) { | ||
587 | struct dentry *dentry; | ||
588 | inode = a->u.fs.inode; | ||
589 | dentry = d_find_alias(inode); | ||
590 | if (dentry) { | ||
591 | audit_log_format(ab, " name="); | ||
592 | audit_log_untrustedstring(ab, dentry->d_name.name); | ||
593 | dput(dentry); | ||
594 | } | ||
595 | } | ||
596 | if (inode) | ||
597 | audit_log_format(ab, " dev=%s ino=%lu", | ||
598 | inode->i_sb->s_id, | ||
599 | inode->i_ino); | ||
600 | break; | ||
601 | case AVC_AUDIT_DATA_NET: | ||
602 | if (a->u.net.sk) { | ||
603 | struct sock *sk = a->u.net.sk; | ||
604 | struct unix_sock *u; | ||
605 | int len = 0; | ||
606 | char *p = NULL; | ||
607 | |||
608 | switch (sk->sk_family) { | ||
609 | case AF_INET: { | ||
610 | struct inet_sock *inet = inet_sk(sk); | ||
611 | |||
612 | avc_print_ipv4_addr(ab, inet->rcv_saddr, | ||
613 | inet->sport, | ||
614 | "laddr", "lport"); | ||
615 | avc_print_ipv4_addr(ab, inet->daddr, | ||
616 | inet->dport, | ||
617 | "faddr", "fport"); | ||
618 | break; | ||
619 | } | ||
620 | case AF_INET6: { | ||
621 | struct inet_sock *inet = inet_sk(sk); | ||
622 | struct ipv6_pinfo *inet6 = inet6_sk(sk); | ||
623 | |||
624 | avc_print_ipv6_addr(ab, &inet6->rcv_saddr, | ||
625 | inet->sport, | ||
626 | "laddr", "lport"); | ||
627 | avc_print_ipv6_addr(ab, &inet6->daddr, | ||
628 | inet->dport, | ||
629 | "faddr", "fport"); | ||
630 | break; | ||
631 | } | ||
632 | case AF_UNIX: | ||
633 | u = unix_sk(sk); | ||
634 | if (u->dentry) { | ||
635 | struct path path = { | ||
636 | .dentry = u->dentry, | ||
637 | .mnt = u->mnt | ||
638 | }; | ||
639 | audit_log_d_path(ab, "path=", | ||
640 | &path); | ||
641 | break; | ||
642 | } | ||
643 | if (!u->addr) | ||
644 | break; | ||
645 | len = u->addr->len-sizeof(short); | ||
646 | p = &u->addr->name->sun_path[0]; | ||
647 | audit_log_format(ab, " path="); | ||
648 | if (*p) | ||
649 | audit_log_untrustedstring(ab, p); | ||
650 | else | ||
651 | audit_log_n_hex(ab, p, len); | ||
652 | break; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | switch (a->u.net.family) { | ||
657 | case AF_INET: | ||
658 | avc_print_ipv4_addr(ab, a->u.net.v4info.saddr, | ||
659 | a->u.net.sport, | ||
660 | "saddr", "src"); | ||
661 | avc_print_ipv4_addr(ab, a->u.net.v4info.daddr, | ||
662 | a->u.net.dport, | ||
663 | "daddr", "dest"); | ||
664 | break; | ||
665 | case AF_INET6: | ||
666 | avc_print_ipv6_addr(ab, &a->u.net.v6info.saddr, | ||
667 | a->u.net.sport, | ||
668 | "saddr", "src"); | ||
669 | avc_print_ipv6_addr(ab, &a->u.net.v6info.daddr, | ||
670 | a->u.net.dport, | ||
671 | "daddr", "dest"); | ||
672 | break; | ||
673 | } | ||
674 | if (a->u.net.netif > 0) { | ||
675 | struct net_device *dev; | ||
676 | |||
677 | /* NOTE: we always use init's namespace */ | ||
678 | dev = dev_get_by_index(&init_net, | ||
679 | a->u.net.netif); | ||
680 | if (dev) { | ||
681 | audit_log_format(ab, " netif=%s", | ||
682 | dev->name); | ||
683 | dev_put(dev); | ||
684 | } | ||
685 | } | ||
686 | break; | ||
687 | } | ||
688 | } | ||
689 | audit_log_format(ab, " "); | ||
690 | avc_dump_query(ab, ssid, tsid, tclass); | ||
691 | audit_log_end(ab); | ||
692 | } | 577 | } |
693 | 578 | ||
694 | /** | 579 | /** |
@@ -956,7 +841,7 @@ out: | |||
956 | * another -errno upon other errors. | 841 | * another -errno upon other errors. |
957 | */ | 842 | */ |
958 | int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, | 843 | int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, |
959 | u32 requested, struct avc_audit_data *auditdata) | 844 | u32 requested, struct common_audit_data *auditdata) |
960 | { | 845 | { |
961 | struct av_decision avd; | 846 | struct av_decision avd; |
962 | int rc; | 847 | int rc; |
@@ -970,3 +855,9 @@ u32 avc_policy_seqno(void) | |||
970 | { | 855 | { |
971 | return avc_cache.latest_notif; | 856 | return avc_cache.latest_notif; |
972 | } | 857 | } |
858 | |||
859 | void avc_disable(void) | ||
860 | { | ||
861 | if (avc_node_cachep) | ||
862 | kmem_cache_destroy(avc_node_cachep); | ||
863 | } | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 8d8b69c5664e..6d0b1ccb5b99 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1479,14 +1479,14 @@ static int task_has_capability(struct task_struct *tsk, | |||
1479 | const struct cred *cred, | 1479 | const struct cred *cred, |
1480 | int cap, int audit) | 1480 | int cap, int audit) |
1481 | { | 1481 | { |
1482 | struct avc_audit_data ad; | 1482 | struct common_audit_data ad; |
1483 | struct av_decision avd; | 1483 | struct av_decision avd; |
1484 | u16 sclass; | 1484 | u16 sclass; |
1485 | u32 sid = cred_sid(cred); | 1485 | u32 sid = cred_sid(cred); |
1486 | u32 av = CAP_TO_MASK(cap); | 1486 | u32 av = CAP_TO_MASK(cap); |
1487 | int rc; | 1487 | int rc; |
1488 | 1488 | ||
1489 | AVC_AUDIT_DATA_INIT(&ad, CAP); | 1489 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
1490 | ad.tsk = tsk; | 1490 | ad.tsk = tsk; |
1491 | ad.u.cap = cap; | 1491 | ad.u.cap = cap; |
1492 | 1492 | ||
@@ -1525,10 +1525,10 @@ static int task_has_system(struct task_struct *tsk, | |||
1525 | static int inode_has_perm(const struct cred *cred, | 1525 | static int inode_has_perm(const struct cred *cred, |
1526 | struct inode *inode, | 1526 | struct inode *inode, |
1527 | u32 perms, | 1527 | u32 perms, |
1528 | struct avc_audit_data *adp) | 1528 | struct common_audit_data *adp) |
1529 | { | 1529 | { |
1530 | struct inode_security_struct *isec; | 1530 | struct inode_security_struct *isec; |
1531 | struct avc_audit_data ad; | 1531 | struct common_audit_data ad; |
1532 | u32 sid; | 1532 | u32 sid; |
1533 | 1533 | ||
1534 | if (unlikely(IS_PRIVATE(inode))) | 1534 | if (unlikely(IS_PRIVATE(inode))) |
@@ -1539,7 +1539,7 @@ static int inode_has_perm(const struct cred *cred, | |||
1539 | 1539 | ||
1540 | if (!adp) { | 1540 | if (!adp) { |
1541 | adp = &ad; | 1541 | adp = &ad; |
1542 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1542 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
1543 | ad.u.fs.inode = inode; | 1543 | ad.u.fs.inode = inode; |
1544 | } | 1544 | } |
1545 | 1545 | ||
@@ -1555,9 +1555,9 @@ static inline int dentry_has_perm(const struct cred *cred, | |||
1555 | u32 av) | 1555 | u32 av) |
1556 | { | 1556 | { |
1557 | struct inode *inode = dentry->d_inode; | 1557 | struct inode *inode = dentry->d_inode; |
1558 | struct avc_audit_data ad; | 1558 | struct common_audit_data ad; |
1559 | 1559 | ||
1560 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1560 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
1561 | ad.u.fs.path.mnt = mnt; | 1561 | ad.u.fs.path.mnt = mnt; |
1562 | ad.u.fs.path.dentry = dentry; | 1562 | ad.u.fs.path.dentry = dentry; |
1563 | return inode_has_perm(cred, inode, av, &ad); | 1563 | return inode_has_perm(cred, inode, av, &ad); |
@@ -1577,11 +1577,11 @@ static int file_has_perm(const struct cred *cred, | |||
1577 | { | 1577 | { |
1578 | struct file_security_struct *fsec = file->f_security; | 1578 | struct file_security_struct *fsec = file->f_security; |
1579 | struct inode *inode = file->f_path.dentry->d_inode; | 1579 | struct inode *inode = file->f_path.dentry->d_inode; |
1580 | struct avc_audit_data ad; | 1580 | struct common_audit_data ad; |
1581 | u32 sid = cred_sid(cred); | 1581 | u32 sid = cred_sid(cred); |
1582 | int rc; | 1582 | int rc; |
1583 | 1583 | ||
1584 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1584 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
1585 | ad.u.fs.path = file->f_path; | 1585 | ad.u.fs.path = file->f_path; |
1586 | 1586 | ||
1587 | if (sid != fsec->sid) { | 1587 | if (sid != fsec->sid) { |
@@ -1612,7 +1612,7 @@ static int may_create(struct inode *dir, | |||
1612 | struct inode_security_struct *dsec; | 1612 | struct inode_security_struct *dsec; |
1613 | struct superblock_security_struct *sbsec; | 1613 | struct superblock_security_struct *sbsec; |
1614 | u32 sid, newsid; | 1614 | u32 sid, newsid; |
1615 | struct avc_audit_data ad; | 1615 | struct common_audit_data ad; |
1616 | int rc; | 1616 | int rc; |
1617 | 1617 | ||
1618 | dsec = dir->i_security; | 1618 | dsec = dir->i_security; |
@@ -1621,7 +1621,7 @@ static int may_create(struct inode *dir, | |||
1621 | sid = tsec->sid; | 1621 | sid = tsec->sid; |
1622 | newsid = tsec->create_sid; | 1622 | newsid = tsec->create_sid; |
1623 | 1623 | ||
1624 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1624 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
1625 | ad.u.fs.path.dentry = dentry; | 1625 | ad.u.fs.path.dentry = dentry; |
1626 | 1626 | ||
1627 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, | 1627 | rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, |
@@ -1665,7 +1665,7 @@ static int may_link(struct inode *dir, | |||
1665 | 1665 | ||
1666 | { | 1666 | { |
1667 | struct inode_security_struct *dsec, *isec; | 1667 | struct inode_security_struct *dsec, *isec; |
1668 | struct avc_audit_data ad; | 1668 | struct common_audit_data ad; |
1669 | u32 sid = current_sid(); | 1669 | u32 sid = current_sid(); |
1670 | u32 av; | 1670 | u32 av; |
1671 | int rc; | 1671 | int rc; |
@@ -1673,7 +1673,7 @@ static int may_link(struct inode *dir, | |||
1673 | dsec = dir->i_security; | 1673 | dsec = dir->i_security; |
1674 | isec = dentry->d_inode->i_security; | 1674 | isec = dentry->d_inode->i_security; |
1675 | 1675 | ||
1676 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1676 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
1677 | ad.u.fs.path.dentry = dentry; | 1677 | ad.u.fs.path.dentry = dentry; |
1678 | 1678 | ||
1679 | av = DIR__SEARCH; | 1679 | av = DIR__SEARCH; |
@@ -1708,7 +1708,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1708 | struct dentry *new_dentry) | 1708 | struct dentry *new_dentry) |
1709 | { | 1709 | { |
1710 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; | 1710 | struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; |
1711 | struct avc_audit_data ad; | 1711 | struct common_audit_data ad; |
1712 | u32 sid = current_sid(); | 1712 | u32 sid = current_sid(); |
1713 | u32 av; | 1713 | u32 av; |
1714 | int old_is_dir, new_is_dir; | 1714 | int old_is_dir, new_is_dir; |
@@ -1719,7 +1719,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1719 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); | 1719 | old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); |
1720 | new_dsec = new_dir->i_security; | 1720 | new_dsec = new_dir->i_security; |
1721 | 1721 | ||
1722 | AVC_AUDIT_DATA_INIT(&ad, FS); | 1722 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
1723 | 1723 | ||
1724 | ad.u.fs.path.dentry = old_dentry; | 1724 | ad.u.fs.path.dentry = old_dentry; |
1725 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, | 1725 | rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, |
@@ -1761,7 +1761,7 @@ static inline int may_rename(struct inode *old_dir, | |||
1761 | static int superblock_has_perm(const struct cred *cred, | 1761 | static int superblock_has_perm(const struct cred *cred, |
1762 | struct super_block *sb, | 1762 | struct super_block *sb, |
1763 | u32 perms, | 1763 | u32 perms, |
1764 | struct avc_audit_data *ad) | 1764 | struct common_audit_data *ad) |
1765 | { | 1765 | { |
1766 | struct superblock_security_struct *sbsec; | 1766 | struct superblock_security_struct *sbsec; |
1767 | u32 sid = cred_sid(cred); | 1767 | u32 sid = cred_sid(cred); |
@@ -1855,12 +1855,12 @@ static inline u32 open_file_to_av(struct file *file) | |||
1855 | 1855 | ||
1856 | /* Hook functions begin here. */ | 1856 | /* Hook functions begin here. */ |
1857 | 1857 | ||
1858 | static int selinux_ptrace_may_access(struct task_struct *child, | 1858 | static int selinux_ptrace_access_check(struct task_struct *child, |
1859 | unsigned int mode) | 1859 | unsigned int mode) |
1860 | { | 1860 | { |
1861 | int rc; | 1861 | int rc; |
1862 | 1862 | ||
1863 | rc = cap_ptrace_may_access(child, mode); | 1863 | rc = cap_ptrace_access_check(child, mode); |
1864 | if (rc) | 1864 | if (rc) |
1865 | return rc; | 1865 | return rc; |
1866 | 1866 | ||
@@ -2101,7 +2101,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2101 | const struct task_security_struct *old_tsec; | 2101 | const struct task_security_struct *old_tsec; |
2102 | struct task_security_struct *new_tsec; | 2102 | struct task_security_struct *new_tsec; |
2103 | struct inode_security_struct *isec; | 2103 | struct inode_security_struct *isec; |
2104 | struct avc_audit_data ad; | 2104 | struct common_audit_data ad; |
2105 | struct inode *inode = bprm->file->f_path.dentry->d_inode; | 2105 | struct inode *inode = bprm->file->f_path.dentry->d_inode; |
2106 | int rc; | 2106 | int rc; |
2107 | 2107 | ||
@@ -2139,7 +2139,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2139 | return rc; | 2139 | return rc; |
2140 | } | 2140 | } |
2141 | 2141 | ||
2142 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2142 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
2143 | ad.u.fs.path = bprm->file->f_path; | 2143 | ad.u.fs.path = bprm->file->f_path; |
2144 | 2144 | ||
2145 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | 2145 | if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) |
@@ -2232,7 +2232,7 @@ extern struct dentry *selinux_null; | |||
2232 | static inline void flush_unauthorized_files(const struct cred *cred, | 2232 | static inline void flush_unauthorized_files(const struct cred *cred, |
2233 | struct files_struct *files) | 2233 | struct files_struct *files) |
2234 | { | 2234 | { |
2235 | struct avc_audit_data ad; | 2235 | struct common_audit_data ad; |
2236 | struct file *file, *devnull = NULL; | 2236 | struct file *file, *devnull = NULL; |
2237 | struct tty_struct *tty; | 2237 | struct tty_struct *tty; |
2238 | struct fdtable *fdt; | 2238 | struct fdtable *fdt; |
@@ -2266,7 +2266,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
2266 | 2266 | ||
2267 | /* Revalidate access to inherited open files. */ | 2267 | /* Revalidate access to inherited open files. */ |
2268 | 2268 | ||
2269 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2269 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
2270 | 2270 | ||
2271 | spin_lock(&files->file_lock); | 2271 | spin_lock(&files->file_lock); |
2272 | for (;;) { | 2272 | for (;;) { |
@@ -2515,7 +2515,7 @@ out: | |||
2515 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | 2515 | static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) |
2516 | { | 2516 | { |
2517 | const struct cred *cred = current_cred(); | 2517 | const struct cred *cred = current_cred(); |
2518 | struct avc_audit_data ad; | 2518 | struct common_audit_data ad; |
2519 | int rc; | 2519 | int rc; |
2520 | 2520 | ||
2521 | rc = superblock_doinit(sb, data); | 2521 | rc = superblock_doinit(sb, data); |
@@ -2526,7 +2526,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2526 | if (flags & MS_KERNMOUNT) | 2526 | if (flags & MS_KERNMOUNT) |
2527 | return 0; | 2527 | return 0; |
2528 | 2528 | ||
2529 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2529 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
2530 | ad.u.fs.path.dentry = sb->s_root; | 2530 | ad.u.fs.path.dentry = sb->s_root; |
2531 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); | 2531 | return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); |
2532 | } | 2532 | } |
@@ -2534,9 +2534,9 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) | |||
2534 | static int selinux_sb_statfs(struct dentry *dentry) | 2534 | static int selinux_sb_statfs(struct dentry *dentry) |
2535 | { | 2535 | { |
2536 | const struct cred *cred = current_cred(); | 2536 | const struct cred *cred = current_cred(); |
2537 | struct avc_audit_data ad; | 2537 | struct common_audit_data ad; |
2538 | 2538 | ||
2539 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2539 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
2540 | ad.u.fs.path.dentry = dentry->d_sb->s_root; | 2540 | ad.u.fs.path.dentry = dentry->d_sb->s_root; |
2541 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); | 2541 | return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); |
2542 | } | 2542 | } |
@@ -2756,7 +2756,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2756 | struct inode *inode = dentry->d_inode; | 2756 | struct inode *inode = dentry->d_inode; |
2757 | struct inode_security_struct *isec = inode->i_security; | 2757 | struct inode_security_struct *isec = inode->i_security; |
2758 | struct superblock_security_struct *sbsec; | 2758 | struct superblock_security_struct *sbsec; |
2759 | struct avc_audit_data ad; | 2759 | struct common_audit_data ad; |
2760 | u32 newsid, sid = current_sid(); | 2760 | u32 newsid, sid = current_sid(); |
2761 | int rc = 0; | 2761 | int rc = 0; |
2762 | 2762 | ||
@@ -2770,7 +2770,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2770 | if (!is_owner_or_cap(inode)) | 2770 | if (!is_owner_or_cap(inode)) |
2771 | return -EPERM; | 2771 | return -EPERM; |
2772 | 2772 | ||
2773 | AVC_AUDIT_DATA_INIT(&ad, FS); | 2773 | COMMON_AUDIT_DATA_INIT(&ad, FS); |
2774 | ad.u.fs.path.dentry = dentry; | 2774 | ad.u.fs.path.dentry = dentry; |
2775 | 2775 | ||
2776 | rc = avc_has_perm(sid, isec->sid, isec->sclass, | 2776 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
@@ -2939,11 +2939,6 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
2939 | const struct cred *cred = current_cred(); | 2939 | const struct cred *cred = current_cred(); |
2940 | struct inode *inode = file->f_path.dentry->d_inode; | 2940 | struct inode *inode = file->f_path.dentry->d_inode; |
2941 | 2941 | ||
2942 | if (!mask) { | ||
2943 | /* No permission to check. Existence test. */ | ||
2944 | return 0; | ||
2945 | } | ||
2946 | |||
2947 | /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ | 2942 | /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ |
2948 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) | 2943 | if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) |
2949 | mask |= MAY_APPEND; | 2944 | mask |= MAY_APPEND; |
@@ -2954,10 +2949,20 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) | |||
2954 | 2949 | ||
2955 | static int selinux_file_permission(struct file *file, int mask) | 2950 | static int selinux_file_permission(struct file *file, int mask) |
2956 | { | 2951 | { |
2952 | struct inode *inode = file->f_path.dentry->d_inode; | ||
2953 | struct file_security_struct *fsec = file->f_security; | ||
2954 | struct inode_security_struct *isec = inode->i_security; | ||
2955 | u32 sid = current_sid(); | ||
2956 | |||
2957 | if (!mask) | 2957 | if (!mask) |
2958 | /* No permission to check. Existence test. */ | 2958 | /* No permission to check. Existence test. */ |
2959 | return 0; | 2959 | return 0; |
2960 | 2960 | ||
2961 | if (sid == fsec->sid && fsec->isid == isec->sid && | ||
2962 | fsec->pseqno == avc_policy_seqno()) | ||
2963 | /* No change since dentry_open check. */ | ||
2964 | return 0; | ||
2965 | |||
2961 | return selinux_revalidate_file_permission(file, mask); | 2966 | return selinux_revalidate_file_permission(file, mask); |
2962 | } | 2967 | } |
2963 | 2968 | ||
@@ -3292,6 +3297,11 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) | |||
3292 | return 0; | 3297 | return 0; |
3293 | } | 3298 | } |
3294 | 3299 | ||
3300 | static int selinux_kernel_module_request(void) | ||
3301 | { | ||
3302 | return task_has_system(current, SYSTEM__MODULE_REQUEST); | ||
3303 | } | ||
3304 | |||
3295 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 3305 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
3296 | { | 3306 | { |
3297 | return current_has_perm(p, PROCESS__SETPGID); | 3307 | return current_has_perm(p, PROCESS__SETPGID); |
@@ -3409,7 +3419,7 @@ static void selinux_task_to_inode(struct task_struct *p, | |||
3409 | 3419 | ||
3410 | /* Returns error only if unable to parse addresses */ | 3420 | /* Returns error only if unable to parse addresses */ |
3411 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, | 3421 | static int selinux_parse_skb_ipv4(struct sk_buff *skb, |
3412 | struct avc_audit_data *ad, u8 *proto) | 3422 | struct common_audit_data *ad, u8 *proto) |
3413 | { | 3423 | { |
3414 | int offset, ihlen, ret = -EINVAL; | 3424 | int offset, ihlen, ret = -EINVAL; |
3415 | struct iphdr _iph, *ih; | 3425 | struct iphdr _iph, *ih; |
@@ -3490,7 +3500,7 @@ out: | |||
3490 | 3500 | ||
3491 | /* Returns error only if unable to parse addresses */ | 3501 | /* Returns error only if unable to parse addresses */ |
3492 | static int selinux_parse_skb_ipv6(struct sk_buff *skb, | 3502 | static int selinux_parse_skb_ipv6(struct sk_buff *skb, |
3493 | struct avc_audit_data *ad, u8 *proto) | 3503 | struct common_audit_data *ad, u8 *proto) |
3494 | { | 3504 | { |
3495 | u8 nexthdr; | 3505 | u8 nexthdr; |
3496 | int ret = -EINVAL, offset; | 3506 | int ret = -EINVAL, offset; |
@@ -3561,7 +3571,7 @@ out: | |||
3561 | 3571 | ||
3562 | #endif /* IPV6 */ | 3572 | #endif /* IPV6 */ |
3563 | 3573 | ||
3564 | static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, | 3574 | static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, |
3565 | char **_addrp, int src, u8 *proto) | 3575 | char **_addrp, int src, u8 *proto) |
3566 | { | 3576 | { |
3567 | char *addrp; | 3577 | char *addrp; |
@@ -3643,7 +3653,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, | |||
3643 | u32 perms) | 3653 | u32 perms) |
3644 | { | 3654 | { |
3645 | struct inode_security_struct *isec; | 3655 | struct inode_security_struct *isec; |
3646 | struct avc_audit_data ad; | 3656 | struct common_audit_data ad; |
3647 | u32 sid; | 3657 | u32 sid; |
3648 | int err = 0; | 3658 | int err = 0; |
3649 | 3659 | ||
@@ -3653,7 +3663,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, | |||
3653 | goto out; | 3663 | goto out; |
3654 | sid = task_sid(task); | 3664 | sid = task_sid(task); |
3655 | 3665 | ||
3656 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3666 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3657 | ad.u.net.sk = sock->sk; | 3667 | ad.u.net.sk = sock->sk; |
3658 | err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); | 3668 | err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
3659 | 3669 | ||
@@ -3740,7 +3750,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3740 | if (family == PF_INET || family == PF_INET6) { | 3750 | if (family == PF_INET || family == PF_INET6) { |
3741 | char *addrp; | 3751 | char *addrp; |
3742 | struct inode_security_struct *isec; | 3752 | struct inode_security_struct *isec; |
3743 | struct avc_audit_data ad; | 3753 | struct common_audit_data ad; |
3744 | struct sockaddr_in *addr4 = NULL; | 3754 | struct sockaddr_in *addr4 = NULL; |
3745 | struct sockaddr_in6 *addr6 = NULL; | 3755 | struct sockaddr_in6 *addr6 = NULL; |
3746 | unsigned short snum; | 3756 | unsigned short snum; |
@@ -3769,7 +3779,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3769 | snum, &sid); | 3779 | snum, &sid); |
3770 | if (err) | 3780 | if (err) |
3771 | goto out; | 3781 | goto out; |
3772 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3782 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3773 | ad.u.net.sport = htons(snum); | 3783 | ad.u.net.sport = htons(snum); |
3774 | ad.u.net.family = family; | 3784 | ad.u.net.family = family; |
3775 | err = avc_has_perm(isec->sid, sid, | 3785 | err = avc_has_perm(isec->sid, sid, |
@@ -3802,7 +3812,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
3802 | if (err) | 3812 | if (err) |
3803 | goto out; | 3813 | goto out; |
3804 | 3814 | ||
3805 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3815 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3806 | ad.u.net.sport = htons(snum); | 3816 | ad.u.net.sport = htons(snum); |
3807 | ad.u.net.family = family; | 3817 | ad.u.net.family = family; |
3808 | 3818 | ||
@@ -3836,7 +3846,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3836 | isec = SOCK_INODE(sock)->i_security; | 3846 | isec = SOCK_INODE(sock)->i_security; |
3837 | if (isec->sclass == SECCLASS_TCP_SOCKET || | 3847 | if (isec->sclass == SECCLASS_TCP_SOCKET || |
3838 | isec->sclass == SECCLASS_DCCP_SOCKET) { | 3848 | isec->sclass == SECCLASS_DCCP_SOCKET) { |
3839 | struct avc_audit_data ad; | 3849 | struct common_audit_data ad; |
3840 | struct sockaddr_in *addr4 = NULL; | 3850 | struct sockaddr_in *addr4 = NULL; |
3841 | struct sockaddr_in6 *addr6 = NULL; | 3851 | struct sockaddr_in6 *addr6 = NULL; |
3842 | unsigned short snum; | 3852 | unsigned short snum; |
@@ -3861,7 +3871,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, | |||
3861 | perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? | 3871 | perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? |
3862 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; | 3872 | TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; |
3863 | 3873 | ||
3864 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3874 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3865 | ad.u.net.dport = htons(snum); | 3875 | ad.u.net.dport = htons(snum); |
3866 | ad.u.net.family = sk->sk_family; | 3876 | ad.u.net.family = sk->sk_family; |
3867 | err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); | 3877 | err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); |
@@ -3951,13 +3961,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, | |||
3951 | struct sk_security_struct *ssec; | 3961 | struct sk_security_struct *ssec; |
3952 | struct inode_security_struct *isec; | 3962 | struct inode_security_struct *isec; |
3953 | struct inode_security_struct *other_isec; | 3963 | struct inode_security_struct *other_isec; |
3954 | struct avc_audit_data ad; | 3964 | struct common_audit_data ad; |
3955 | int err; | 3965 | int err; |
3956 | 3966 | ||
3957 | isec = SOCK_INODE(sock)->i_security; | 3967 | isec = SOCK_INODE(sock)->i_security; |
3958 | other_isec = SOCK_INODE(other)->i_security; | 3968 | other_isec = SOCK_INODE(other)->i_security; |
3959 | 3969 | ||
3960 | AVC_AUDIT_DATA_INIT(&ad, NET); | 3970 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3961 | ad.u.net.sk = other->sk; | 3971 | ad.u.net.sk = other->sk; |
3962 | 3972 | ||
3963 | err = avc_has_perm(isec->sid, other_isec->sid, | 3973 | err = avc_has_perm(isec->sid, other_isec->sid, |
@@ -3983,13 +3993,13 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
3983 | { | 3993 | { |
3984 | struct inode_security_struct *isec; | 3994 | struct inode_security_struct *isec; |
3985 | struct inode_security_struct *other_isec; | 3995 | struct inode_security_struct *other_isec; |
3986 | struct avc_audit_data ad; | 3996 | struct common_audit_data ad; |
3987 | int err; | 3997 | int err; |
3988 | 3998 | ||
3989 | isec = SOCK_INODE(sock)->i_security; | 3999 | isec = SOCK_INODE(sock)->i_security; |
3990 | other_isec = SOCK_INODE(other)->i_security; | 4000 | other_isec = SOCK_INODE(other)->i_security; |
3991 | 4001 | ||
3992 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4002 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
3993 | ad.u.net.sk = other->sk; | 4003 | ad.u.net.sk = other->sk; |
3994 | 4004 | ||
3995 | err = avc_has_perm(isec->sid, other_isec->sid, | 4005 | err = avc_has_perm(isec->sid, other_isec->sid, |
@@ -4002,7 +4012,7 @@ static int selinux_socket_unix_may_send(struct socket *sock, | |||
4002 | 4012 | ||
4003 | static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, | 4013 | static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, |
4004 | u32 peer_sid, | 4014 | u32 peer_sid, |
4005 | struct avc_audit_data *ad) | 4015 | struct common_audit_data *ad) |
4006 | { | 4016 | { |
4007 | int err; | 4017 | int err; |
4008 | u32 if_sid; | 4018 | u32 if_sid; |
@@ -4030,10 +4040,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, | |||
4030 | struct sk_security_struct *sksec = sk->sk_security; | 4040 | struct sk_security_struct *sksec = sk->sk_security; |
4031 | u32 peer_sid; | 4041 | u32 peer_sid; |
4032 | u32 sk_sid = sksec->sid; | 4042 | u32 sk_sid = sksec->sid; |
4033 | struct avc_audit_data ad; | 4043 | struct common_audit_data ad; |
4034 | char *addrp; | 4044 | char *addrp; |
4035 | 4045 | ||
4036 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4046 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4037 | ad.u.net.netif = skb->iif; | 4047 | ad.u.net.netif = skb->iif; |
4038 | ad.u.net.family = family; | 4048 | ad.u.net.family = family; |
4039 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4049 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
@@ -4071,7 +4081,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4071 | struct sk_security_struct *sksec = sk->sk_security; | 4081 | struct sk_security_struct *sksec = sk->sk_security; |
4072 | u16 family = sk->sk_family; | 4082 | u16 family = sk->sk_family; |
4073 | u32 sk_sid = sksec->sid; | 4083 | u32 sk_sid = sksec->sid; |
4074 | struct avc_audit_data ad; | 4084 | struct common_audit_data ad; |
4075 | char *addrp; | 4085 | char *addrp; |
4076 | u8 secmark_active; | 4086 | u8 secmark_active; |
4077 | u8 peerlbl_active; | 4087 | u8 peerlbl_active; |
@@ -4095,7 +4105,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
4095 | if (!secmark_active && !peerlbl_active) | 4105 | if (!secmark_active && !peerlbl_active) |
4096 | return 0; | 4106 | return 0; |
4097 | 4107 | ||
4098 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4108 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4099 | ad.u.net.netif = skb->iif; | 4109 | ad.u.net.netif = skb->iif; |
4100 | ad.u.net.family = family; | 4110 | ad.u.net.family = family; |
4101 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); | 4111 | err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); |
@@ -4353,7 +4363,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4353 | int err; | 4363 | int err; |
4354 | char *addrp; | 4364 | char *addrp; |
4355 | u32 peer_sid; | 4365 | u32 peer_sid; |
4356 | struct avc_audit_data ad; | 4366 | struct common_audit_data ad; |
4357 | u8 secmark_active; | 4367 | u8 secmark_active; |
4358 | u8 netlbl_active; | 4368 | u8 netlbl_active; |
4359 | u8 peerlbl_active; | 4369 | u8 peerlbl_active; |
@@ -4370,7 +4380,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, | |||
4370 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) | 4380 | if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) |
4371 | return NF_DROP; | 4381 | return NF_DROP; |
4372 | 4382 | ||
4373 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4383 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4374 | ad.u.net.netif = ifindex; | 4384 | ad.u.net.netif = ifindex; |
4375 | ad.u.net.family = family; | 4385 | ad.u.net.family = family; |
4376 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) | 4386 | if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) |
@@ -4458,7 +4468,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4458 | { | 4468 | { |
4459 | struct sock *sk = skb->sk; | 4469 | struct sock *sk = skb->sk; |
4460 | struct sk_security_struct *sksec; | 4470 | struct sk_security_struct *sksec; |
4461 | struct avc_audit_data ad; | 4471 | struct common_audit_data ad; |
4462 | char *addrp; | 4472 | char *addrp; |
4463 | u8 proto; | 4473 | u8 proto; |
4464 | 4474 | ||
@@ -4466,7 +4476,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, | |||
4466 | return NF_ACCEPT; | 4476 | return NF_ACCEPT; |
4467 | sksec = sk->sk_security; | 4477 | sksec = sk->sk_security; |
4468 | 4478 | ||
4469 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4479 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4470 | ad.u.net.netif = ifindex; | 4480 | ad.u.net.netif = ifindex; |
4471 | ad.u.net.family = family; | 4481 | ad.u.net.family = family; |
4472 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) | 4482 | if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) |
@@ -4490,7 +4500,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4490 | u32 secmark_perm; | 4500 | u32 secmark_perm; |
4491 | u32 peer_sid; | 4501 | u32 peer_sid; |
4492 | struct sock *sk; | 4502 | struct sock *sk; |
4493 | struct avc_audit_data ad; | 4503 | struct common_audit_data ad; |
4494 | char *addrp; | 4504 | char *addrp; |
4495 | u8 secmark_active; | 4505 | u8 secmark_active; |
4496 | u8 peerlbl_active; | 4506 | u8 peerlbl_active; |
@@ -4549,7 +4559,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, | |||
4549 | secmark_perm = PACKET__SEND; | 4559 | secmark_perm = PACKET__SEND; |
4550 | } | 4560 | } |
4551 | 4561 | ||
4552 | AVC_AUDIT_DATA_INIT(&ad, NET); | 4562 | COMMON_AUDIT_DATA_INIT(&ad, NET); |
4553 | ad.u.net.netif = ifindex; | 4563 | ad.u.net.netif = ifindex; |
4554 | ad.u.net.family = family; | 4564 | ad.u.net.family = family; |
4555 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) | 4565 | if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) |
@@ -4619,13 +4629,13 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) | |||
4619 | static int selinux_netlink_recv(struct sk_buff *skb, int capability) | 4629 | static int selinux_netlink_recv(struct sk_buff *skb, int capability) |
4620 | { | 4630 | { |
4621 | int err; | 4631 | int err; |
4622 | struct avc_audit_data ad; | 4632 | struct common_audit_data ad; |
4623 | 4633 | ||
4624 | err = cap_netlink_recv(skb, capability); | 4634 | err = cap_netlink_recv(skb, capability); |
4625 | if (err) | 4635 | if (err) |
4626 | return err; | 4636 | return err; |
4627 | 4637 | ||
4628 | AVC_AUDIT_DATA_INIT(&ad, CAP); | 4638 | COMMON_AUDIT_DATA_INIT(&ad, CAP); |
4629 | ad.u.cap = capability; | 4639 | ad.u.cap = capability; |
4630 | 4640 | ||
4631 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, | 4641 | return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, |
@@ -4684,12 +4694,12 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, | |||
4684 | u32 perms) | 4694 | u32 perms) |
4685 | { | 4695 | { |
4686 | struct ipc_security_struct *isec; | 4696 | struct ipc_security_struct *isec; |
4687 | struct avc_audit_data ad; | 4697 | struct common_audit_data ad; |
4688 | u32 sid = current_sid(); | 4698 | u32 sid = current_sid(); |
4689 | 4699 | ||
4690 | isec = ipc_perms->security; | 4700 | isec = ipc_perms->security; |
4691 | 4701 | ||
4692 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4702 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4693 | ad.u.ipc_id = ipc_perms->key; | 4703 | ad.u.ipc_id = ipc_perms->key; |
4694 | 4704 | ||
4695 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); | 4705 | return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); |
@@ -4709,7 +4719,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) | |||
4709 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | 4719 | static int selinux_msg_queue_alloc_security(struct msg_queue *msq) |
4710 | { | 4720 | { |
4711 | struct ipc_security_struct *isec; | 4721 | struct ipc_security_struct *isec; |
4712 | struct avc_audit_data ad; | 4722 | struct common_audit_data ad; |
4713 | u32 sid = current_sid(); | 4723 | u32 sid = current_sid(); |
4714 | int rc; | 4724 | int rc; |
4715 | 4725 | ||
@@ -4719,7 +4729,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) | |||
4719 | 4729 | ||
4720 | isec = msq->q_perm.security; | 4730 | isec = msq->q_perm.security; |
4721 | 4731 | ||
4722 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4732 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4723 | ad.u.ipc_id = msq->q_perm.key; | 4733 | ad.u.ipc_id = msq->q_perm.key; |
4724 | 4734 | ||
4725 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4735 | rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
@@ -4739,12 +4749,12 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq) | |||
4739 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) | 4749 | static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) |
4740 | { | 4750 | { |
4741 | struct ipc_security_struct *isec; | 4751 | struct ipc_security_struct *isec; |
4742 | struct avc_audit_data ad; | 4752 | struct common_audit_data ad; |
4743 | u32 sid = current_sid(); | 4753 | u32 sid = current_sid(); |
4744 | 4754 | ||
4745 | isec = msq->q_perm.security; | 4755 | isec = msq->q_perm.security; |
4746 | 4756 | ||
4747 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4757 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4748 | ad.u.ipc_id = msq->q_perm.key; | 4758 | ad.u.ipc_id = msq->q_perm.key; |
4749 | 4759 | ||
4750 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, | 4760 | return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, |
@@ -4783,7 +4793,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
4783 | { | 4793 | { |
4784 | struct ipc_security_struct *isec; | 4794 | struct ipc_security_struct *isec; |
4785 | struct msg_security_struct *msec; | 4795 | struct msg_security_struct *msec; |
4786 | struct avc_audit_data ad; | 4796 | struct common_audit_data ad; |
4787 | u32 sid = current_sid(); | 4797 | u32 sid = current_sid(); |
4788 | int rc; | 4798 | int rc; |
4789 | 4799 | ||
@@ -4804,7 +4814,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, | |||
4804 | return rc; | 4814 | return rc; |
4805 | } | 4815 | } |
4806 | 4816 | ||
4807 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4817 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4808 | ad.u.ipc_id = msq->q_perm.key; | 4818 | ad.u.ipc_id = msq->q_perm.key; |
4809 | 4819 | ||
4810 | /* Can this process write to the queue? */ | 4820 | /* Can this process write to the queue? */ |
@@ -4828,14 +4838,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
4828 | { | 4838 | { |
4829 | struct ipc_security_struct *isec; | 4839 | struct ipc_security_struct *isec; |
4830 | struct msg_security_struct *msec; | 4840 | struct msg_security_struct *msec; |
4831 | struct avc_audit_data ad; | 4841 | struct common_audit_data ad; |
4832 | u32 sid = task_sid(target); | 4842 | u32 sid = task_sid(target); |
4833 | int rc; | 4843 | int rc; |
4834 | 4844 | ||
4835 | isec = msq->q_perm.security; | 4845 | isec = msq->q_perm.security; |
4836 | msec = msg->security; | 4846 | msec = msg->security; |
4837 | 4847 | ||
4838 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4848 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4839 | ad.u.ipc_id = msq->q_perm.key; | 4849 | ad.u.ipc_id = msq->q_perm.key; |
4840 | 4850 | ||
4841 | rc = avc_has_perm(sid, isec->sid, | 4851 | rc = avc_has_perm(sid, isec->sid, |
@@ -4850,7 +4860,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, | |||
4850 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) | 4860 | static int selinux_shm_alloc_security(struct shmid_kernel *shp) |
4851 | { | 4861 | { |
4852 | struct ipc_security_struct *isec; | 4862 | struct ipc_security_struct *isec; |
4853 | struct avc_audit_data ad; | 4863 | struct common_audit_data ad; |
4854 | u32 sid = current_sid(); | 4864 | u32 sid = current_sid(); |
4855 | int rc; | 4865 | int rc; |
4856 | 4866 | ||
@@ -4860,7 +4870,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) | |||
4860 | 4870 | ||
4861 | isec = shp->shm_perm.security; | 4871 | isec = shp->shm_perm.security; |
4862 | 4872 | ||
4863 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4873 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4864 | ad.u.ipc_id = shp->shm_perm.key; | 4874 | ad.u.ipc_id = shp->shm_perm.key; |
4865 | 4875 | ||
4866 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 4876 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
@@ -4880,12 +4890,12 @@ static void selinux_shm_free_security(struct shmid_kernel *shp) | |||
4880 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) | 4890 | static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) |
4881 | { | 4891 | { |
4882 | struct ipc_security_struct *isec; | 4892 | struct ipc_security_struct *isec; |
4883 | struct avc_audit_data ad; | 4893 | struct common_audit_data ad; |
4884 | u32 sid = current_sid(); | 4894 | u32 sid = current_sid(); |
4885 | 4895 | ||
4886 | isec = shp->shm_perm.security; | 4896 | isec = shp->shm_perm.security; |
4887 | 4897 | ||
4888 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4898 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4889 | ad.u.ipc_id = shp->shm_perm.key; | 4899 | ad.u.ipc_id = shp->shm_perm.key; |
4890 | 4900 | ||
4891 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, | 4901 | return avc_has_perm(sid, isec->sid, SECCLASS_SHM, |
@@ -4942,7 +4952,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, | |||
4942 | static int selinux_sem_alloc_security(struct sem_array *sma) | 4952 | static int selinux_sem_alloc_security(struct sem_array *sma) |
4943 | { | 4953 | { |
4944 | struct ipc_security_struct *isec; | 4954 | struct ipc_security_struct *isec; |
4945 | struct avc_audit_data ad; | 4955 | struct common_audit_data ad; |
4946 | u32 sid = current_sid(); | 4956 | u32 sid = current_sid(); |
4947 | int rc; | 4957 | int rc; |
4948 | 4958 | ||
@@ -4952,7 +4962,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) | |||
4952 | 4962 | ||
4953 | isec = sma->sem_perm.security; | 4963 | isec = sma->sem_perm.security; |
4954 | 4964 | ||
4955 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4965 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4956 | ad.u.ipc_id = sma->sem_perm.key; | 4966 | ad.u.ipc_id = sma->sem_perm.key; |
4957 | 4967 | ||
4958 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 4968 | rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
@@ -4972,12 +4982,12 @@ static void selinux_sem_free_security(struct sem_array *sma) | |||
4972 | static int selinux_sem_associate(struct sem_array *sma, int semflg) | 4982 | static int selinux_sem_associate(struct sem_array *sma, int semflg) |
4973 | { | 4983 | { |
4974 | struct ipc_security_struct *isec; | 4984 | struct ipc_security_struct *isec; |
4975 | struct avc_audit_data ad; | 4985 | struct common_audit_data ad; |
4976 | u32 sid = current_sid(); | 4986 | u32 sid = current_sid(); |
4977 | 4987 | ||
4978 | isec = sma->sem_perm.security; | 4988 | isec = sma->sem_perm.security; |
4979 | 4989 | ||
4980 | AVC_AUDIT_DATA_INIT(&ad, IPC); | 4990 | COMMON_AUDIT_DATA_INIT(&ad, IPC); |
4981 | ad.u.ipc_id = sma->sem_perm.key; | 4991 | ad.u.ipc_id = sma->sem_perm.key; |
4982 | 4992 | ||
4983 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, | 4993 | return avc_has_perm(sid, isec->sid, SECCLASS_SEM, |
@@ -5195,7 +5205,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5195 | 5205 | ||
5196 | /* Only allow single threaded processes to change context */ | 5206 | /* Only allow single threaded processes to change context */ |
5197 | error = -EPERM; | 5207 | error = -EPERM; |
5198 | if (!is_single_threaded(p)) { | 5208 | if (!current_is_single_threaded()) { |
5199 | error = security_bounded_transition(tsec->sid, sid); | 5209 | error = security_bounded_transition(tsec->sid, sid); |
5200 | if (error) | 5210 | if (error) |
5201 | goto abort_change; | 5211 | goto abort_change; |
@@ -5323,7 +5333,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) | |||
5323 | static struct security_operations selinux_ops = { | 5333 | static struct security_operations selinux_ops = { |
5324 | .name = "selinux", | 5334 | .name = "selinux", |
5325 | 5335 | ||
5326 | .ptrace_may_access = selinux_ptrace_may_access, | 5336 | .ptrace_access_check = selinux_ptrace_access_check, |
5327 | .ptrace_traceme = selinux_ptrace_traceme, | 5337 | .ptrace_traceme = selinux_ptrace_traceme, |
5328 | .capget = selinux_capget, | 5338 | .capget = selinux_capget, |
5329 | .capset = selinux_capset, | 5339 | .capset = selinux_capset, |
@@ -5400,6 +5410,7 @@ static struct security_operations selinux_ops = { | |||
5400 | .cred_prepare = selinux_cred_prepare, | 5410 | .cred_prepare = selinux_cred_prepare, |
5401 | .kernel_act_as = selinux_kernel_act_as, | 5411 | .kernel_act_as = selinux_kernel_act_as, |
5402 | .kernel_create_files_as = selinux_kernel_create_files_as, | 5412 | .kernel_create_files_as = selinux_kernel_create_files_as, |
5413 | .kernel_module_request = selinux_kernel_module_request, | ||
5403 | .task_setpgid = selinux_task_setpgid, | 5414 | .task_setpgid = selinux_task_setpgid, |
5404 | .task_getpgid = selinux_task_getpgid, | 5415 | .task_getpgid = selinux_task_getpgid, |
5405 | .task_getsid = selinux_task_getsid, | 5416 | .task_getsid = selinux_task_getsid, |
@@ -5691,6 +5702,9 @@ int selinux_disable(void) | |||
5691 | selinux_disabled = 1; | 5702 | selinux_disabled = 1; |
5692 | selinux_enabled = 0; | 5703 | selinux_enabled = 0; |
5693 | 5704 | ||
5705 | /* Try to destroy the avc node cache */ | ||
5706 | avc_disable(); | ||
5707 | |||
5694 | /* Reset security_ops to the secondary module, dummy or capability. */ | 5708 | /* Reset security_ops to the secondary module, dummy or capability. */ |
5695 | security_ops = secondary_ops; | 5709 | security_ops = secondary_ops; |
5696 | 5710 | ||
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h index 31df1d7c1aee..2b683ad83d21 100644 --- a/security/selinux/include/av_perm_to_string.h +++ b/security/selinux/include/av_perm_to_string.h | |||
@@ -107,6 +107,7 @@ | |||
107 | S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") | 107 | S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") |
108 | S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") | 108 | S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") |
109 | S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console") | 109 | S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console") |
110 | S_(SECCLASS_SYSTEM, SYSTEM__MODULE_REQUEST, "module_request") | ||
110 | S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown") | 111 | S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown") |
111 | S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override") | 112 | S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override") |
112 | S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search") | 113 | S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search") |
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h index d645192ee950..21c722669902 100644 --- a/security/selinux/include/av_permissions.h +++ b/security/selinux/include/av_permissions.h | |||
@@ -508,6 +508,7 @@ | |||
508 | #define SYSTEM__SYSLOG_READ 0x00000002UL | 508 | #define SYSTEM__SYSLOG_READ 0x00000002UL |
509 | #define SYSTEM__SYSLOG_MOD 0x00000004UL | 509 | #define SYSTEM__SYSLOG_MOD 0x00000004UL |
510 | #define SYSTEM__SYSLOG_CONSOLE 0x00000008UL | 510 | #define SYSTEM__SYSLOG_CONSOLE 0x00000008UL |
511 | #define SYSTEM__MODULE_REQUEST 0x00000010UL | ||
511 | #define CAPABILITY__CHOWN 0x00000001UL | 512 | #define CAPABILITY__CHOWN 0x00000001UL |
512 | #define CAPABILITY__DAC_OVERRIDE 0x00000002UL | 513 | #define CAPABILITY__DAC_OVERRIDE 0x00000002UL |
513 | #define CAPABILITY__DAC_READ_SEARCH 0x00000004UL | 514 | #define CAPABILITY__DAC_READ_SEARCH 0x00000004UL |
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h index d12ff1a9c0aa..e94e82f73818 100644 --- a/security/selinux/include/avc.h +++ b/security/selinux/include/avc.h | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/spinlock.h> | 13 | #include <linux/spinlock.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/audit.h> | 15 | #include <linux/audit.h> |
16 | #include <linux/lsm_audit.h> | ||
16 | #include <linux/in6.h> | 17 | #include <linux/in6.h> |
17 | #include <linux/path.h> | 18 | #include <linux/path.h> |
18 | #include <asm/system.h> | 19 | #include <asm/system.h> |
@@ -36,48 +37,6 @@ struct inode; | |||
36 | struct sock; | 37 | struct sock; |
37 | struct sk_buff; | 38 | struct sk_buff; |
38 | 39 | ||
39 | /* Auxiliary data to use in generating the audit record. */ | ||
40 | struct avc_audit_data { | ||
41 | char type; | ||
42 | #define AVC_AUDIT_DATA_FS 1 | ||
43 | #define AVC_AUDIT_DATA_NET 2 | ||
44 | #define AVC_AUDIT_DATA_CAP 3 | ||
45 | #define AVC_AUDIT_DATA_IPC 4 | ||
46 | struct task_struct *tsk; | ||
47 | union { | ||
48 | struct { | ||
49 | struct path path; | ||
50 | struct inode *inode; | ||
51 | } fs; | ||
52 | struct { | ||
53 | int netif; | ||
54 | struct sock *sk; | ||
55 | u16 family; | ||
56 | __be16 dport; | ||
57 | __be16 sport; | ||
58 | union { | ||
59 | struct { | ||
60 | __be32 daddr; | ||
61 | __be32 saddr; | ||
62 | } v4; | ||
63 | struct { | ||
64 | struct in6_addr daddr; | ||
65 | struct in6_addr saddr; | ||
66 | } v6; | ||
67 | } fam; | ||
68 | } net; | ||
69 | int cap; | ||
70 | int ipc_id; | ||
71 | } u; | ||
72 | }; | ||
73 | |||
74 | #define v4info fam.v4 | ||
75 | #define v6info fam.v6 | ||
76 | |||
77 | /* Initialize an AVC audit data structure. */ | ||
78 | #define AVC_AUDIT_DATA_INIT(_d,_t) \ | ||
79 | { memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; } | ||
80 | |||
81 | /* | 40 | /* |
82 | * AVC statistics | 41 | * AVC statistics |
83 | */ | 42 | */ |
@@ -98,7 +57,9 @@ void __init avc_init(void); | |||
98 | 57 | ||
99 | void avc_audit(u32 ssid, u32 tsid, | 58 | void avc_audit(u32 ssid, u32 tsid, |
100 | u16 tclass, u32 requested, | 59 | u16 tclass, u32 requested, |
101 | struct av_decision *avd, int result, struct avc_audit_data *auditdata); | 60 | struct av_decision *avd, |
61 | int result, | ||
62 | struct common_audit_data *a); | ||
102 | 63 | ||
103 | #define AVC_STRICT 1 /* Ignore permissive mode. */ | 64 | #define AVC_STRICT 1 /* Ignore permissive mode. */ |
104 | int avc_has_perm_noaudit(u32 ssid, u32 tsid, | 65 | int avc_has_perm_noaudit(u32 ssid, u32 tsid, |
@@ -108,7 +69,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, | |||
108 | 69 | ||
109 | int avc_has_perm(u32 ssid, u32 tsid, | 70 | int avc_has_perm(u32 ssid, u32 tsid, |
110 | u16 tclass, u32 requested, | 71 | u16 tclass, u32 requested, |
111 | struct avc_audit_data *auditdata); | 72 | struct common_audit_data *auditdata); |
112 | 73 | ||
113 | u32 avc_policy_seqno(void); | 74 | u32 avc_policy_seqno(void); |
114 | 75 | ||
@@ -127,13 +88,13 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, | |||
127 | u32 events, u32 ssid, u32 tsid, | 88 | u32 events, u32 ssid, u32 tsid, |
128 | u16 tclass, u32 perms); | 89 | u16 tclass, u32 perms); |
129 | 90 | ||
130 | /* Shows permission in human readable form */ | ||
131 | void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av); | ||
132 | |||
133 | /* Exported to selinuxfs */ | 91 | /* Exported to selinuxfs */ |
134 | int avc_get_hash_stats(char *page); | 92 | int avc_get_hash_stats(char *page); |
135 | extern unsigned int avc_cache_threshold; | 93 | extern unsigned int avc_cache_threshold; |
136 | 94 | ||
95 | /* Attempt to free avc node cache */ | ||
96 | void avc_disable(void); | ||
97 | |||
137 | #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS | 98 | #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS |
138 | DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); | 99 | DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); |
139 | #endif | 100 | #endif |
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index b4b5b9b2f0be..8d7384280a7a 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h | |||
@@ -59,7 +59,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family); | |||
59 | int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | 59 | int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, |
60 | struct sk_buff *skb, | 60 | struct sk_buff *skb, |
61 | u16 family, | 61 | u16 family, |
62 | struct avc_audit_data *ad); | 62 | struct common_audit_data *ad); |
63 | int selinux_netlbl_socket_setsockopt(struct socket *sock, | 63 | int selinux_netlbl_socket_setsockopt(struct socket *sock, |
64 | int level, | 64 | int level, |
65 | int optname); | 65 | int optname); |
@@ -129,7 +129,7 @@ static inline int selinux_netlbl_socket_post_create(struct sock *sk, | |||
129 | static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | 129 | static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, |
130 | struct sk_buff *skb, | 130 | struct sk_buff *skb, |
131 | u16 family, | 131 | u16 family, |
132 | struct avc_audit_data *ad) | 132 | struct common_audit_data *ad) |
133 | { | 133 | { |
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 289e24b39e3e..13128f9a3e5a 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
@@ -41,9 +41,9 @@ static inline int selinux_xfrm_enabled(void) | |||
41 | } | 41 | } |
42 | 42 | ||
43 | int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, | 43 | int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, |
44 | struct avc_audit_data *ad); | 44 | struct common_audit_data *ad); |
45 | int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, | 45 | int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, |
46 | struct avc_audit_data *ad, u8 proto); | 46 | struct common_audit_data *ad, u8 proto); |
47 | int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); | 47 | int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); |
48 | 48 | ||
49 | static inline void selinux_xfrm_notify_policyload(void) | 49 | static inline void selinux_xfrm_notify_policyload(void) |
@@ -57,13 +57,13 @@ static inline int selinux_xfrm_enabled(void) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, | 59 | static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, |
60 | struct avc_audit_data *ad) | 60 | struct common_audit_data *ad) |
61 | { | 61 | { |
62 | return 0; | 62 | return 0; |
63 | } | 63 | } |
64 | 64 | ||
65 | static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, | 65 | static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, |
66 | struct avc_audit_data *ad, u8 proto) | 66 | struct common_audit_data *ad, u8 proto) |
67 | { | 67 | { |
68 | return 0; | 68 | return 0; |
69 | } | 69 | } |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 2e984413c7b2..e68823741ad5 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -342,7 +342,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) | |||
342 | int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | 342 | int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, |
343 | struct sk_buff *skb, | 343 | struct sk_buff *skb, |
344 | u16 family, | 344 | u16 family, |
345 | struct avc_audit_data *ad) | 345 | struct common_audit_data *ad) |
346 | { | 346 | { |
347 | int rc; | 347 | int rc; |
348 | u32 nlbl_sid; | 348 | u32 nlbl_sid; |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 500e6f78e115..ff17820d35ec 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -22,6 +22,11 @@ | |||
22 | * | 22 | * |
23 | * Added validation of kernel classes and permissions | 23 | * Added validation of kernel classes and permissions |
24 | * | 24 | * |
25 | * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com> | ||
26 | * | ||
27 | * Added support for bounds domain and audit messaged on masked permissions | ||
28 | * | ||
29 | * Copyright (C) 2008, 2009 NEC Corporation | ||
25 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. | 30 | * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. |
26 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. | 31 | * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. |
27 | * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC | 32 | * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC |
@@ -279,6 +284,95 @@ mls_ops: | |||
279 | } | 284 | } |
280 | 285 | ||
281 | /* | 286 | /* |
287 | * security_dump_masked_av - dumps masked permissions during | ||
288 | * security_compute_av due to RBAC, MLS/Constraint and Type bounds. | ||
289 | */ | ||
290 | static int dump_masked_av_helper(void *k, void *d, void *args) | ||
291 | { | ||
292 | struct perm_datum *pdatum = d; | ||
293 | char **permission_names = args; | ||
294 | |||
295 | BUG_ON(pdatum->value < 1 || pdatum->value > 32); | ||
296 | |||
297 | permission_names[pdatum->value - 1] = (char *)k; | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static void security_dump_masked_av(struct context *scontext, | ||
303 | struct context *tcontext, | ||
304 | u16 tclass, | ||
305 | u32 permissions, | ||
306 | const char *reason) | ||
307 | { | ||
308 | struct common_datum *common_dat; | ||
309 | struct class_datum *tclass_dat; | ||
310 | struct audit_buffer *ab; | ||
311 | char *tclass_name; | ||
312 | char *scontext_name = NULL; | ||
313 | char *tcontext_name = NULL; | ||
314 | char *permission_names[32]; | ||
315 | int index, length; | ||
316 | bool need_comma = false; | ||
317 | |||
318 | if (!permissions) | ||
319 | return; | ||
320 | |||
321 | tclass_name = policydb.p_class_val_to_name[tclass - 1]; | ||
322 | tclass_dat = policydb.class_val_to_struct[tclass - 1]; | ||
323 | common_dat = tclass_dat->comdatum; | ||
324 | |||
325 | /* init permission_names */ | ||
326 | if (common_dat && | ||
327 | hashtab_map(common_dat->permissions.table, | ||
328 | dump_masked_av_helper, permission_names) < 0) | ||
329 | goto out; | ||
330 | |||
331 | if (hashtab_map(tclass_dat->permissions.table, | ||
332 | dump_masked_av_helper, permission_names) < 0) | ||
333 | goto out; | ||
334 | |||
335 | /* get scontext/tcontext in text form */ | ||
336 | if (context_struct_to_string(scontext, | ||
337 | &scontext_name, &length) < 0) | ||
338 | goto out; | ||
339 | |||
340 | if (context_struct_to_string(tcontext, | ||
341 | &tcontext_name, &length) < 0) | ||
342 | goto out; | ||
343 | |||
344 | /* audit a message */ | ||
345 | ab = audit_log_start(current->audit_context, | ||
346 | GFP_ATOMIC, AUDIT_SELINUX_ERR); | ||
347 | if (!ab) | ||
348 | goto out; | ||
349 | |||
350 | audit_log_format(ab, "op=security_compute_av reason=%s " | ||
351 | "scontext=%s tcontext=%s tclass=%s perms=", | ||
352 | reason, scontext_name, tcontext_name, tclass_name); | ||
353 | |||
354 | for (index = 0; index < 32; index++) { | ||
355 | u32 mask = (1 << index); | ||
356 | |||
357 | if ((mask & permissions) == 0) | ||
358 | continue; | ||
359 | |||
360 | audit_log_format(ab, "%s%s", | ||
361 | need_comma ? "," : "", | ||
362 | permission_names[index] | ||
363 | ? permission_names[index] : "????"); | ||
364 | need_comma = true; | ||
365 | } | ||
366 | audit_log_end(ab); | ||
367 | out: | ||
368 | /* release scontext/tcontext */ | ||
369 | kfree(tcontext_name); | ||
370 | kfree(scontext_name); | ||
371 | |||
372 | return; | ||
373 | } | ||
374 | |||
375 | /* | ||
282 | * security_boundary_permission - drops violated permissions | 376 | * security_boundary_permission - drops violated permissions |
283 | * on boundary constraint. | 377 | * on boundary constraint. |
284 | */ | 378 | */ |
@@ -347,28 +441,12 @@ static void type_attribute_bounds_av(struct context *scontext, | |||
347 | } | 441 | } |
348 | 442 | ||
349 | if (masked) { | 443 | if (masked) { |
350 | struct audit_buffer *ab; | ||
351 | char *stype_name | ||
352 | = policydb.p_type_val_to_name[source->value - 1]; | ||
353 | char *ttype_name | ||
354 | = policydb.p_type_val_to_name[target->value - 1]; | ||
355 | char *tclass_name | ||
356 | = policydb.p_class_val_to_name[tclass - 1]; | ||
357 | |||
358 | /* mask violated permissions */ | 444 | /* mask violated permissions */ |
359 | avd->allowed &= ~masked; | 445 | avd->allowed &= ~masked; |
360 | 446 | ||
361 | /* notice to userspace via audit message */ | 447 | /* audit masked permissions */ |
362 | ab = audit_log_start(current->audit_context, | 448 | security_dump_masked_av(scontext, tcontext, |
363 | GFP_ATOMIC, AUDIT_SELINUX_ERR); | 449 | tclass, masked, "bounds"); |
364 | if (!ab) | ||
365 | return; | ||
366 | |||
367 | audit_log_format(ab, "av boundary violation: " | ||
368 | "source=%s target=%s tclass=%s", | ||
369 | stype_name, ttype_name, tclass_name); | ||
370 | avc_dump_av(ab, tclass, masked); | ||
371 | audit_log_end(ab); | ||
372 | } | 450 | } |
373 | } | 451 | } |
374 | 452 | ||
@@ -480,7 +558,7 @@ static int context_struct_compute_av(struct context *scontext, | |||
480 | if ((constraint->permissions & (avd->allowed)) && | 558 | if ((constraint->permissions & (avd->allowed)) && |
481 | !constraint_expr_eval(scontext, tcontext, NULL, | 559 | !constraint_expr_eval(scontext, tcontext, NULL, |
482 | constraint->expr)) { | 560 | constraint->expr)) { |
483 | avd->allowed = (avd->allowed) & ~(constraint->permissions); | 561 | avd->allowed &= ~(constraint->permissions); |
484 | } | 562 | } |
485 | constraint = constraint->next; | 563 | constraint = constraint->next; |
486 | } | 564 | } |
@@ -499,8 +577,8 @@ static int context_struct_compute_av(struct context *scontext, | |||
499 | break; | 577 | break; |
500 | } | 578 | } |
501 | if (!ra) | 579 | if (!ra) |
502 | avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | | 580 | avd->allowed &= ~(PROCESS__TRANSITION | |
503 | PROCESS__DYNTRANSITION); | 581 | PROCESS__DYNTRANSITION); |
504 | } | 582 | } |
505 | 583 | ||
506 | /* | 584 | /* |
@@ -687,6 +765,26 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) | |||
687 | } | 765 | } |
688 | index = type->bounds; | 766 | index = type->bounds; |
689 | } | 767 | } |
768 | |||
769 | if (rc) { | ||
770 | char *old_name = NULL; | ||
771 | char *new_name = NULL; | ||
772 | int length; | ||
773 | |||
774 | if (!context_struct_to_string(old_context, | ||
775 | &old_name, &length) && | ||
776 | !context_struct_to_string(new_context, | ||
777 | &new_name, &length)) { | ||
778 | audit_log(current->audit_context, | ||
779 | GFP_ATOMIC, AUDIT_SELINUX_ERR, | ||
780 | "op=security_bounded_transition " | ||
781 | "result=denied " | ||
782 | "oldcontext=%s newcontext=%s", | ||
783 | old_name, new_name); | ||
784 | } | ||
785 | kfree(new_name); | ||
786 | kfree(old_name); | ||
787 | } | ||
690 | out: | 788 | out: |
691 | read_unlock(&policy_rwlock); | 789 | read_unlock(&policy_rwlock); |
692 | 790 | ||
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 72b18452e1a1..f3cb9ed731a9 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -401,7 +401,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x) | |||
401 | * gone thru the IPSec process. | 401 | * gone thru the IPSec process. |
402 | */ | 402 | */ |
403 | int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, | 403 | int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, |
404 | struct avc_audit_data *ad) | 404 | struct common_audit_data *ad) |
405 | { | 405 | { |
406 | int i, rc = 0; | 406 | int i, rc = 0; |
407 | struct sec_path *sp; | 407 | struct sec_path *sp; |
@@ -442,7 +442,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, | |||
442 | * checked in the selinux_xfrm_state_pol_flow_match hook above. | 442 | * checked in the selinux_xfrm_state_pol_flow_match hook above. |
443 | */ | 443 | */ |
444 | int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, | 444 | int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, |
445 | struct avc_audit_data *ad, u8 proto) | 445 | struct common_audit_data *ad, u8 proto) |
446 | { | 446 | { |
447 | struct dst_entry *dst; | 447 | struct dst_entry *dst; |
448 | int rc = 0; | 448 | int rc = 0; |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 243bec175be0..c6e9acae72e4 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -275,7 +275,7 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, | |||
275 | { | 275 | { |
276 | memset(a, 0, sizeof(*a)); | 276 | memset(a, 0, sizeof(*a)); |
277 | a->a.type = type; | 277 | a->a.type = type; |
278 | a->a.function = func; | 278 | a->a.smack_audit_data.function = func; |
279 | } | 279 | } |
280 | 280 | ||
281 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, | 281 | static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, |
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 513dc1aa16dd..0f9ac8146900 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c | |||
@@ -240,8 +240,9 @@ static inline void smack_str_from_perm(char *string, int access) | |||
240 | static void smack_log_callback(struct audit_buffer *ab, void *a) | 240 | static void smack_log_callback(struct audit_buffer *ab, void *a) |
241 | { | 241 | { |
242 | struct common_audit_data *ad = a; | 242 | struct common_audit_data *ad = a; |
243 | struct smack_audit_data *sad = &ad->lsm_priv.smack_audit_data; | 243 | struct smack_audit_data *sad = &ad->smack_audit_data; |
244 | audit_log_format(ab, "lsm=SMACK fn=%s action=%s", ad->function, | 244 | audit_log_format(ab, "lsm=SMACK fn=%s action=%s", |
245 | ad->smack_audit_data.function, | ||
245 | sad->result ? "denied" : "granted"); | 246 | sad->result ? "denied" : "granted"); |
246 | audit_log_format(ab, " subject="); | 247 | audit_log_format(ab, " subject="); |
247 | audit_log_untrustedstring(ab, sad->subject); | 248 | audit_log_untrustedstring(ab, sad->subject); |
@@ -274,11 +275,11 @@ void smack_log(char *subject_label, char *object_label, int request, | |||
274 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) | 275 | if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) |
275 | return; | 276 | return; |
276 | 277 | ||
277 | if (a->function == NULL) | 278 | if (a->smack_audit_data.function == NULL) |
278 | a->function = "unknown"; | 279 | a->smack_audit_data.function = "unknown"; |
279 | 280 | ||
280 | /* end preparing the audit data */ | 281 | /* end preparing the audit data */ |
281 | sad = &a->lsm_priv.smack_audit_data; | 282 | sad = &a->smack_audit_data; |
282 | smack_str_from_perm(request_buffer, request); | 283 | smack_str_from_perm(request_buffer, request); |
283 | sad->subject = subject_label; | 284 | sad->subject = subject_label; |
284 | sad->object = object_label; | 285 | sad->object = object_label; |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 0023182078c7..c243a2b25832 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -91,7 +91,7 @@ struct inode_smack *new_inode_smack(char *smack) | |||
91 | */ | 91 | */ |
92 | 92 | ||
93 | /** | 93 | /** |
94 | * smack_ptrace_may_access - Smack approval on PTRACE_ATTACH | 94 | * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH |
95 | * @ctp: child task pointer | 95 | * @ctp: child task pointer |
96 | * @mode: ptrace attachment mode | 96 | * @mode: ptrace attachment mode |
97 | * | 97 | * |
@@ -99,13 +99,13 @@ struct inode_smack *new_inode_smack(char *smack) | |||
99 | * | 99 | * |
100 | * Do the capability checks, and require read and write. | 100 | * Do the capability checks, and require read and write. |
101 | */ | 101 | */ |
102 | static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) | 102 | static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) |
103 | { | 103 | { |
104 | int rc; | 104 | int rc; |
105 | struct smk_audit_info ad; | 105 | struct smk_audit_info ad; |
106 | char *sp, *tsp; | 106 | char *sp, *tsp; |
107 | 107 | ||
108 | rc = cap_ptrace_may_access(ctp, mode); | 108 | rc = cap_ptrace_access_check(ctp, mode); |
109 | if (rc != 0) | 109 | if (rc != 0) |
110 | return rc; | 110 | return rc; |
111 | 111 | ||
@@ -2464,7 +2464,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, | |||
2464 | /* | 2464 | /* |
2465 | * Perfectly reasonable for this to be NULL | 2465 | * Perfectly reasonable for this to be NULL |
2466 | */ | 2466 | */ |
2467 | if (sip == NULL || sip->sin_family != PF_INET) | 2467 | if (sip == NULL || sip->sin_family != AF_INET) |
2468 | return 0; | 2468 | return 0; |
2469 | 2469 | ||
2470 | return smack_netlabel_send(sock->sk, sip); | 2470 | return smack_netlabel_send(sock->sk, sip); |
@@ -3032,7 +3032,7 @@ static void smack_release_secctx(char *secdata, u32 seclen) | |||
3032 | struct security_operations smack_ops = { | 3032 | struct security_operations smack_ops = { |
3033 | .name = "smack", | 3033 | .name = "smack", |
3034 | 3034 | ||
3035 | .ptrace_may_access = smack_ptrace_may_access, | 3035 | .ptrace_access_check = smack_ptrace_access_check, |
3036 | .ptrace_traceme = smack_ptrace_traceme, | 3036 | .ptrace_traceme = smack_ptrace_traceme, |
3037 | .syslog = smack_syslog, | 3037 | .syslog = smack_syslog, |
3038 | 3038 | ||
diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c index fdd1f4b8c448..3c8bd8ee0b95 100644 --- a/security/tomoyo/common.c +++ b/security/tomoyo/common.c | |||
@@ -1285,6 +1285,36 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, | |||
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | /** | 1287 | /** |
1288 | * tomoyo_delete_domain - Delete a domain. | ||
1289 | * | ||
1290 | * @domainname: The name of domain. | ||
1291 | * | ||
1292 | * Returns 0. | ||
1293 | */ | ||
1294 | static int tomoyo_delete_domain(char *domainname) | ||
1295 | { | ||
1296 | struct tomoyo_domain_info *domain; | ||
1297 | struct tomoyo_path_info name; | ||
1298 | |||
1299 | name.name = domainname; | ||
1300 | tomoyo_fill_path_info(&name); | ||
1301 | down_write(&tomoyo_domain_list_lock); | ||
1302 | /* Is there an active domain? */ | ||
1303 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | ||
1304 | /* Never delete tomoyo_kernel_domain */ | ||
1305 | if (domain == &tomoyo_kernel_domain) | ||
1306 | continue; | ||
1307 | if (domain->is_deleted || | ||
1308 | tomoyo_pathcmp(domain->domainname, &name)) | ||
1309 | continue; | ||
1310 | domain->is_deleted = true; | ||
1311 | break; | ||
1312 | } | ||
1313 | up_write(&tomoyo_domain_list_lock); | ||
1314 | return 0; | ||
1315 | } | ||
1316 | |||
1317 | /** | ||
1288 | * tomoyo_write_domain_policy - Write domain policy. | 1318 | * tomoyo_write_domain_policy - Write domain policy. |
1289 | * | 1319 | * |
1290 | * @head: Pointer to "struct tomoyo_io_buffer". | 1320 | * @head: Pointer to "struct tomoyo_io_buffer". |
diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 6d6ba09af457..31df541911f7 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h | |||
@@ -339,8 +339,6 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); | |||
339 | const char *tomoyo_get_msg(const bool is_enforce); | 339 | const char *tomoyo_get_msg(const bool is_enforce); |
340 | /* Convert single path operation to operation name. */ | 340 | /* Convert single path operation to operation name. */ |
341 | const char *tomoyo_sp2keyword(const u8 operation); | 341 | const char *tomoyo_sp2keyword(const u8 operation); |
342 | /* Delete a domain. */ | ||
343 | int tomoyo_delete_domain(char *data); | ||
344 | /* Create "alias" entry in exception policy. */ | 342 | /* Create "alias" entry in exception policy. */ |
345 | int tomoyo_write_alias_policy(char *data, const bool is_delete); | 343 | int tomoyo_write_alias_policy(char *data, const bool is_delete); |
346 | /* | 344 | /* |
diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index 1d8b16960576..fcf52accce2b 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c | |||
@@ -717,38 +717,6 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete) | |||
717 | return tomoyo_update_alias_entry(data, cp, is_delete); | 717 | return tomoyo_update_alias_entry(data, cp, is_delete); |
718 | } | 718 | } |
719 | 719 | ||
720 | /* Domain create/delete handler. */ | ||
721 | |||
722 | /** | ||
723 | * tomoyo_delete_domain - Delete a domain. | ||
724 | * | ||
725 | * @domainname: The name of domain. | ||
726 | * | ||
727 | * Returns 0. | ||
728 | */ | ||
729 | int tomoyo_delete_domain(char *domainname) | ||
730 | { | ||
731 | struct tomoyo_domain_info *domain; | ||
732 | struct tomoyo_path_info name; | ||
733 | |||
734 | name.name = domainname; | ||
735 | tomoyo_fill_path_info(&name); | ||
736 | down_write(&tomoyo_domain_list_lock); | ||
737 | /* Is there an active domain? */ | ||
738 | list_for_each_entry(domain, &tomoyo_domain_list, list) { | ||
739 | /* Never delete tomoyo_kernel_domain */ | ||
740 | if (domain == &tomoyo_kernel_domain) | ||
741 | continue; | ||
742 | if (domain->is_deleted || | ||
743 | tomoyo_pathcmp(domain->domainname, &name)) | ||
744 | continue; | ||
745 | domain->is_deleted = true; | ||
746 | break; | ||
747 | } | ||
748 | up_write(&tomoyo_domain_list_lock); | ||
749 | return 0; | ||
750 | } | ||
751 | |||
752 | /** | 720 | /** |
753 | * tomoyo_find_or_assign_new_domain - Create a domain. | 721 | * tomoyo_find_or_assign_new_domain - Create a domain. |
754 | * | 722 | * |
@@ -818,13 +786,11 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * | |||
818 | /** | 786 | /** |
819 | * tomoyo_find_next_domain - Find a domain. | 787 | * tomoyo_find_next_domain - Find a domain. |
820 | * | 788 | * |
821 | * @bprm: Pointer to "struct linux_binprm". | 789 | * @bprm: Pointer to "struct linux_binprm". |
822 | * @next_domain: Pointer to pointer to "struct tomoyo_domain_info". | ||
823 | * | 790 | * |
824 | * Returns 0 on success, negative value otherwise. | 791 | * Returns 0 on success, negative value otherwise. |
825 | */ | 792 | */ |
826 | int tomoyo_find_next_domain(struct linux_binprm *bprm, | 793 | int tomoyo_find_next_domain(struct linux_binprm *bprm) |
827 | struct tomoyo_domain_info **next_domain) | ||
828 | { | 794 | { |
829 | /* | 795 | /* |
830 | * This function assumes that the size of buffer returned by | 796 | * This function assumes that the size of buffer returned by |
@@ -946,9 +912,11 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm, | |||
946 | tomoyo_set_domain_flag(old_domain, false, | 912 | tomoyo_set_domain_flag(old_domain, false, |
947 | TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED); | 913 | TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED); |
948 | out: | 914 | out: |
915 | if (!domain) | ||
916 | domain = old_domain; | ||
917 | bprm->cred->security = domain; | ||
949 | tomoyo_free(real_program_name); | 918 | tomoyo_free(real_program_name); |
950 | tomoyo_free(symlink_program_name); | 919 | tomoyo_free(symlink_program_name); |
951 | *next_domain = domain ? domain : old_domain; | ||
952 | tomoyo_free(tmp); | 920 | tomoyo_free(tmp); |
953 | return retval; | 921 | return retval; |
954 | } | 922 | } |
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c index 3194d09fe0f4..35a13e7915e4 100644 --- a/security/tomoyo/tomoyo.c +++ b/security/tomoyo/tomoyo.c | |||
@@ -61,14 +61,8 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm) | |||
61 | * Execute permission is checked against pathname passed to do_execve() | 61 | * Execute permission is checked against pathname passed to do_execve() |
62 | * using current domain. | 62 | * using current domain. |
63 | */ | 63 | */ |
64 | if (!domain) { | 64 | if (!domain) |
65 | struct tomoyo_domain_info *next_domain = NULL; | 65 | return tomoyo_find_next_domain(bprm); |
66 | int retval = tomoyo_find_next_domain(bprm, &next_domain); | ||
67 | |||
68 | if (!retval) | ||
69 | bprm->cred->security = next_domain; | ||
70 | return retval; | ||
71 | } | ||
72 | /* | 66 | /* |
73 | * Read permission is checked against interpreters using next domain. | 67 | * Read permission is checked against interpreters using next domain. |
74 | * '1' is the result of open_to_namei_flags(O_RDONLY). | 68 | * '1' is the result of open_to_namei_flags(O_RDONLY). |
diff --git a/security/tomoyo/tomoyo.h b/security/tomoyo/tomoyo.h index 0fd588a629cf..cd6ba0bf7069 100644 --- a/security/tomoyo/tomoyo.h +++ b/security/tomoyo/tomoyo.h | |||
@@ -31,8 +31,7 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info *domain, | |||
31 | struct path *path2); | 31 | struct path *path2); |
32 | int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, | 32 | int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, |
33 | struct file *filp); | 33 | struct file *filp); |
34 | int tomoyo_find_next_domain(struct linux_binprm *bprm, | 34 | int tomoyo_find_next_domain(struct linux_binprm *bprm); |
35 | struct tomoyo_domain_info **next_domain); | ||
36 | 35 | ||
37 | /* Index numbers for Access Controls. */ | 36 | /* Index numbers for Access Controls. */ |
38 | 37 | ||