aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c14
-rw-r--r--security/selinux/hooks.c98
-rw-r--r--security/selinux/nlmsgtab.c9
-rw-r--r--security/selinux/selinuxfs.c11
-rw-r--r--security/selinux/ss/services.c15
5 files changed, 86 insertions, 61 deletions
diff --git a/security/dummy.c b/security/dummy.c
index a678f094b72d..fd99429278e9 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -378,7 +378,7 @@ static int dummy_inode_removexattr (struct dentry *dentry, char *name)
378 return 0; 378 return 0;
379} 379}
380 380
381static int dummy_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 381static int dummy_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
382{ 382{
383 return -EOPNOTSUPP; 383 return -EOPNOTSUPP;
384} 384}
@@ -393,6 +393,11 @@ static int dummy_inode_listsecurity(struct inode *inode, char *buffer, size_t bu
393 return 0; 393 return 0;
394} 394}
395 395
396static const char *dummy_inode_xattr_getsuffix(void)
397{
398 return NULL;
399}
400
396static int dummy_file_permission (struct file *file, int mask) 401static int dummy_file_permission (struct file *file, int mask)
397{ 402{
398 return 0; 403 return 0;
@@ -558,6 +563,11 @@ static int dummy_ipc_permission (struct kern_ipc_perm *ipcp, short flag)
558 return 0; 563 return 0;
559} 564}
560 565
566static int dummy_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
567{
568 return -EOPNOTSUPP;
569}
570
561static int dummy_msg_msg_alloc_security (struct msg_msg *msg) 571static int dummy_msg_msg_alloc_security (struct msg_msg *msg)
562{ 572{
563 return 0; 573 return 0;
@@ -931,6 +941,7 @@ void security_fixup_ops (struct security_operations *ops)
931 set_to_dummy_if_null(ops, inode_getxattr); 941 set_to_dummy_if_null(ops, inode_getxattr);
932 set_to_dummy_if_null(ops, inode_listxattr); 942 set_to_dummy_if_null(ops, inode_listxattr);
933 set_to_dummy_if_null(ops, inode_removexattr); 943 set_to_dummy_if_null(ops, inode_removexattr);
944 set_to_dummy_if_null(ops, inode_xattr_getsuffix);
934 set_to_dummy_if_null(ops, inode_getsecurity); 945 set_to_dummy_if_null(ops, inode_getsecurity);
935 set_to_dummy_if_null(ops, inode_setsecurity); 946 set_to_dummy_if_null(ops, inode_setsecurity);
936 set_to_dummy_if_null(ops, inode_listsecurity); 947 set_to_dummy_if_null(ops, inode_listsecurity);
@@ -965,6 +976,7 @@ void security_fixup_ops (struct security_operations *ops)
965 set_to_dummy_if_null(ops, task_reparent_to_init); 976 set_to_dummy_if_null(ops, task_reparent_to_init);
966 set_to_dummy_if_null(ops, task_to_inode); 977 set_to_dummy_if_null(ops, task_to_inode);
967 set_to_dummy_if_null(ops, ipc_permission); 978 set_to_dummy_if_null(ops, ipc_permission);
979 set_to_dummy_if_null(ops, ipc_getsecurity);
968 set_to_dummy_if_null(ops, msg_msg_alloc_security); 980 set_to_dummy_if_null(ops, msg_msg_alloc_security);
969 set_to_dummy_if_null(ops, msg_msg_free_security); 981 set_to_dummy_if_null(ops, msg_msg_free_security);
970 set_to_dummy_if_null(ops, msg_queue_alloc_security); 982 set_to_dummy_if_null(ops, msg_queue_alloc_security);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ccaf988f3729..b61b9554bc27 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -119,6 +119,32 @@ static DEFINE_SPINLOCK(sb_security_lock);
119 119
120static kmem_cache_t *sel_inode_cache; 120static kmem_cache_t *sel_inode_cache;
121 121
122/* Return security context for a given sid or just the context
123 length if the buffer is null or length is 0 */
124static int selinux_getsecurity(u32 sid, void *buffer, size_t size)
125{
126 char *context;
127 unsigned len;
128 int rc;
129
130 rc = security_sid_to_context(sid, &context, &len);
131 if (rc)
132 return rc;
133
134 if (!buffer || !size)
135 goto getsecurity_exit;
136
137 if (size < len) {
138 len = -ERANGE;
139 goto getsecurity_exit;
140 }
141 memcpy(buffer, context, len);
142
143getsecurity_exit:
144 kfree(context);
145 return len;
146}
147
122/* Allocate and free functions for each kind of security blob. */ 148/* Allocate and free functions for each kind of security blob. */
123 149
124static int task_alloc_security(struct task_struct *task) 150static int task_alloc_security(struct task_struct *task)
@@ -2210,6 +2236,11 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2210 return -EACCES; 2236 return -EACCES;
2211} 2237}
2212 2238
2239static const char *selinux_inode_xattr_getsuffix(void)
2240{
2241 return XATTR_SELINUX_SUFFIX;
2242}
2243
2213/* 2244/*
2214 * Copy the in-core inode security context value to the user. If the 2245 * Copy the in-core inode security context value to the user. If the
2215 * getxattr() prior to this succeeded, check to see if we need to 2246 * getxattr() prior to this succeeded, check to see if we need to
@@ -2217,47 +2248,14 @@ static int selinux_inode_removexattr (struct dentry *dentry, char *name)
2217 * 2248 *
2218 * Permission check is handled by selinux_inode_getxattr hook. 2249 * Permission check is handled by selinux_inode_getxattr hook.
2219 */ 2250 */
2220static int selinux_inode_getsecurity(struct inode *inode, const char *name, void *buffer, size_t size, int err) 2251static int selinux_inode_getsecurity(const struct inode *inode, const char *name, void *buffer, size_t size, int err)
2221{ 2252{
2222 struct inode_security_struct *isec = inode->i_security; 2253 struct inode_security_struct *isec = inode->i_security;
2223 char *context;
2224 unsigned len;
2225 int rc;
2226
2227 if (strcmp(name, XATTR_SELINUX_SUFFIX)) {
2228 rc = -EOPNOTSUPP;
2229 goto out;
2230 }
2231
2232 rc = security_sid_to_context(isec->sid, &context, &len);
2233 if (rc)
2234 goto out;
2235
2236 /* Probe for required buffer size */
2237 if (!buffer || !size) {
2238 rc = len;
2239 goto out_free;
2240 }
2241 2254
2242 if (size < len) { 2255 if (strcmp(name, XATTR_SELINUX_SUFFIX))
2243 rc = -ERANGE; 2256 return -EOPNOTSUPP;
2244 goto out_free;
2245 }
2246 2257
2247 if (err > 0) { 2258 return selinux_getsecurity(isec->sid, buffer, size);
2248 if ((len == err) && !(memcmp(context, buffer, len))) {
2249 /* Don't need to canonicalize value */
2250 rc = err;
2251 goto out_free;
2252 }
2253 memset(buffer, 0, size);
2254 }
2255 memcpy(buffer, context, len);
2256 rc = len;
2257out_free:
2258 kfree(context);
2259out:
2260 return rc;
2261} 2259}
2262 2260
2263static int selinux_inode_setsecurity(struct inode *inode, const char *name, 2261static int selinux_inode_setsecurity(struct inode *inode, const char *name,
@@ -4054,6 +4052,13 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
4054 return ipc_has_perm(ipcp, av); 4052 return ipc_has_perm(ipcp, av);
4055} 4053}
4056 4054
4055static int selinux_ipc_getsecurity(struct kern_ipc_perm *ipcp, void *buffer, size_t size)
4056{
4057 struct ipc_security_struct *isec = ipcp->security;
4058
4059 return selinux_getsecurity(isec->sid, buffer, size);
4060}
4061
4057/* module stacking operations */ 4062/* module stacking operations */
4058static int selinux_register_security (const char *name, struct security_operations *ops) 4063static int selinux_register_security (const char *name, struct security_operations *ops)
4059{ 4064{
@@ -4095,8 +4100,7 @@ static int selinux_getprocattr(struct task_struct *p,
4095 char *name, void *value, size_t size) 4100 char *name, void *value, size_t size)
4096{ 4101{
4097 struct task_security_struct *tsec; 4102 struct task_security_struct *tsec;
4098 u32 sid, len; 4103 u32 sid;
4099 char *context;
4100 int error; 4104 int error;
4101 4105
4102 if (current != p) { 4106 if (current != p) {
@@ -4105,9 +4109,6 @@ static int selinux_getprocattr(struct task_struct *p,
4105 return error; 4109 return error;
4106 } 4110 }
4107 4111
4108 if (!size)
4109 return -ERANGE;
4110
4111 tsec = p->security; 4112 tsec = p->security;
4112 4113
4113 if (!strcmp(name, "current")) 4114 if (!strcmp(name, "current"))
@@ -4124,16 +4125,7 @@ static int selinux_getprocattr(struct task_struct *p,
4124 if (!sid) 4125 if (!sid)
4125 return 0; 4126 return 0;
4126 4127
4127 error = security_sid_to_context(sid, &context, &len); 4128 return selinux_getsecurity(sid, value, size);
4128 if (error)
4129 return error;
4130 if (len > size) {
4131 kfree(context);
4132 return -ERANGE;
4133 }
4134 memcpy(value, context, len);
4135 kfree(context);
4136 return len;
4137} 4129}
4138 4130
4139static int selinux_setprocattr(struct task_struct *p, 4131static int selinux_setprocattr(struct task_struct *p,
@@ -4291,6 +4283,7 @@ static struct security_operations selinux_ops = {
4291 .inode_getxattr = selinux_inode_getxattr, 4283 .inode_getxattr = selinux_inode_getxattr,
4292 .inode_listxattr = selinux_inode_listxattr, 4284 .inode_listxattr = selinux_inode_listxattr,
4293 .inode_removexattr = selinux_inode_removexattr, 4285 .inode_removexattr = selinux_inode_removexattr,
4286 .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix,
4294 .inode_getsecurity = selinux_inode_getsecurity, 4287 .inode_getsecurity = selinux_inode_getsecurity,
4295 .inode_setsecurity = selinux_inode_setsecurity, 4288 .inode_setsecurity = selinux_inode_setsecurity,
4296 .inode_listsecurity = selinux_inode_listsecurity, 4289 .inode_listsecurity = selinux_inode_listsecurity,
@@ -4328,6 +4321,7 @@ static struct security_operations selinux_ops = {
4328 .task_to_inode = selinux_task_to_inode, 4321 .task_to_inode = selinux_task_to_inode,
4329 4322
4330 .ipc_permission = selinux_ipc_permission, 4323 .ipc_permission = selinux_ipc_permission,
4324 .ipc_getsecurity = selinux_ipc_getsecurity,
4331 4325
4332 .msg_msg_alloc_security = selinux_msg_msg_alloc_security, 4326 .msg_msg_alloc_security = selinux_msg_msg_alloc_security,
4333 .msg_msg_free_security = selinux_msg_msg_free_security, 4327 .msg_msg_free_security = selinux_msg_msg_free_security,
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index 85e399259832..b8f4d25cf335 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -106,6 +106,9 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
106 { AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV }, 106 { AUDIT_LIST, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV },
107 { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 107 { AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
108 { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE }, 108 { AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
109 { AUDIT_LIST_RULES, NETLINK_AUDIT_SOCKET__NLMSG_READPRIV },
110 { AUDIT_ADD_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
111 { AUDIT_DEL_RULE, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
109 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY }, 112 { AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
110 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ }, 113 { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
111}; 114};
@@ -152,8 +155,10 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
152 break; 155 break;
153 156
154 case SECCLASS_NETLINK_AUDIT_SOCKET: 157 case SECCLASS_NETLINK_AUDIT_SOCKET:
155 if (nlmsg_type >= AUDIT_FIRST_USER_MSG && 158 if ((nlmsg_type >= AUDIT_FIRST_USER_MSG &&
156 nlmsg_type <= AUDIT_LAST_USER_MSG) { 159 nlmsg_type <= AUDIT_LAST_USER_MSG) ||
160 (nlmsg_type >= AUDIT_FIRST_USER_MSG2 &&
161 nlmsg_type <= AUDIT_LAST_USER_MSG2)) {
157 *perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY; 162 *perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY;
158 } else { 163 } else {
159 err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms, 164 err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index f5d78365488f..a4efc966f065 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -22,6 +22,7 @@
22#include <linux/major.h> 22#include <linux/major.h>
23#include <linux/seq_file.h> 23#include <linux/seq_file.h>
24#include <linux/percpu.h> 24#include <linux/percpu.h>
25#include <linux/audit.h>
25#include <asm/uaccess.h> 26#include <asm/uaccess.h>
26#include <asm/semaphore.h> 27#include <asm/semaphore.h>
27 28
@@ -127,6 +128,10 @@ static ssize_t sel_write_enforce(struct file * file, const char __user * buf,
127 length = task_has_security(current, SECURITY__SETENFORCE); 128 length = task_has_security(current, SECURITY__SETENFORCE);
128 if (length) 129 if (length)
129 goto out; 130 goto out;
131 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
132 "enforcing=%d old_enforcing=%d auid=%u", new_value,
133 selinux_enforcing,
134 audit_get_loginuid(current->audit_context));
130 selinux_enforcing = new_value; 135 selinux_enforcing = new_value;
131 if (selinux_enforcing) 136 if (selinux_enforcing)
132 avc_ss_reset(0); 137 avc_ss_reset(0);
@@ -177,6 +182,9 @@ static ssize_t sel_write_disable(struct file * file, const char __user * buf,
177 length = selinux_disable(); 182 length = selinux_disable();
178 if (length < 0) 183 if (length < 0)
179 goto out; 184 goto out;
185 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_STATUS,
186 "selinux=0 auid=%u",
187 audit_get_loginuid(current->audit_context));
180 } 188 }
181 189
182 length = count; 190 length = count;
@@ -262,6 +270,9 @@ static ssize_t sel_write_load(struct file * file, const char __user * buf,
262 length = ret; 270 length = ret;
263 else 271 else
264 length = count; 272 length = count;
273 audit_log(current->audit_context, GFP_KERNEL, AUDIT_MAC_POLICY_LOAD,
274 "policy loaded auid=%u",
275 audit_get_loginuid(current->audit_context));
265out: 276out:
266 mutex_unlock(&sel_mutex); 277 mutex_unlock(&sel_mutex);
267 vfree(data); 278 vfree(data);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 63e0b7f29cb5..61492485de84 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -1759,19 +1759,22 @@ int security_set_bools(int len, int *values)
1759 goto out; 1759 goto out;
1760 } 1760 }
1761 1761
1762 printk(KERN_INFO "security: committed booleans { ");
1763 for (i = 0; i < len; i++) { 1762 for (i = 0; i < len; i++) {
1763 if (!!values[i] != policydb.bool_val_to_struct[i]->state) {
1764 audit_log(current->audit_context, GFP_ATOMIC,
1765 AUDIT_MAC_CONFIG_CHANGE,
1766 "bool=%s val=%d old_val=%d auid=%u",
1767 policydb.p_bool_val_to_name[i],
1768 !!values[i],
1769 policydb.bool_val_to_struct[i]->state,
1770 audit_get_loginuid(current->audit_context));
1771 }
1764 if (values[i]) { 1772 if (values[i]) {
1765 policydb.bool_val_to_struct[i]->state = 1; 1773 policydb.bool_val_to_struct[i]->state = 1;
1766 } else { 1774 } else {
1767 policydb.bool_val_to_struct[i]->state = 0; 1775 policydb.bool_val_to_struct[i]->state = 0;
1768 } 1776 }
1769 if (i != 0)
1770 printk(", ");
1771 printk("%s:%d", policydb.p_bool_val_to_name[i],
1772 policydb.bool_val_to_struct[i]->state);
1773 } 1777 }
1774 printk(" }\n");
1775 1778
1776 for (cur = policydb.cond_list; cur != NULL; cur = cur->next) { 1779 for (cur = policydb.cond_list; cur != NULL; cur = cur->next) {
1777 rc = evaluate_cond_node(&policydb, cur); 1780 rc = evaluate_cond_node(&policydb, cur);