summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/avc.c40
-rw-r--r--security/selinux/hooks.c27
-rw-r--r--security/selinux/include/av_perm_to_string.h2
-rw-r--r--security/selinux/include/av_permissions.h2
-rw-r--r--security/selinux/nlmsgtab.c12
-rw-r--r--security/selinux/selinuxfs.c9
-rw-r--r--security/selinux/ss/conditional.c9
-rw-r--r--security/selinux/ss/policydb.c15
-rw-r--r--security/selinux/ss/services.c10
9 files changed, 74 insertions, 52 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 85a6f66a873..451502467a9 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -242,7 +242,7 @@ void __init avc_init(void)
avc_node_cachep = kmem_cache_create("avc_node", sizeof(struct avc_node),
0, SLAB_PANIC, NULL, NULL);
- audit_log(current->audit_context, "AVC INITIALIZED\n");
+ audit_log(current->audit_context, AUDIT_KERNEL, "AVC INITIALIZED\n");
}
int avc_get_hash_stats(char *page)
@@ -532,6 +532,7 @@ void avc_audit(u32 ssid, u32 tsid,
u16 tclass, u32 requested,
struct av_decision *avd, int result, struct avc_audit_data *a)
{
+ struct task_struct *tsk = current;
struct inode *inode = NULL;
u32 denied, audited;
struct audit_buffer *ab;
@@ -549,12 +550,18 @@ void avc_audit(u32 ssid, u32 tsid,
return;
}
- ab = audit_log_start(current->audit_context);
+ ab = audit_log_start(current->audit_context, AUDIT_AVC);
if (!ab)
return; /* audit_panic has been called */
audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
avc_dump_av(ab, tclass,audited);
audit_log_format(ab, " for ");
+ if (a && a->tsk)
+ tsk = a->tsk;
+ if (tsk && tsk->pid) {
+ audit_log_format(ab, " pid=%d comm=", tsk->pid);
+ audit_log_untrustedstring(ab, tsk->comm);
+ }
if (a) {
switch (a->type) {
case AVC_AUDIT_DATA_IPC:
@@ -566,21 +573,18 @@ void avc_audit(u32 ssid, u32 tsid,
case AVC_AUDIT_DATA_FS:
if (a->u.fs.dentry) {
struct dentry *dentry = a->u.fs.dentry;
- if (a->u.fs.mnt) {
- audit_log_d_path(ab, "path=", dentry,
- a->u.fs.mnt);
- } else {
- audit_log_format(ab, " name=%s",
- dentry->d_name.name);
- }
+ if (a->u.fs.mnt)
+ audit_avc_path(dentry, a->u.fs.mnt);
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab, dentry->d_name.name);
inode = dentry->d_inode;
} else if (a->u.fs.inode) {
struct dentry *dentry;
inode = a->u.fs.inode;
dentry = d_find_alias(inode);
if (dentry) {
- audit_log_format(ab, " name=%s",
- dentry->d_name.name);
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab, dentry->d_name.name);
dput(dentry);
}
}
@@ -623,22 +627,20 @@ void avc_audit(u32 ssid, u32 tsid,
case AF_UNIX:
u = unix_sk(sk);
if (u->dentry) {
- audit_log_d_path(ab, "path=",
- u->dentry, u->mnt);
+ audit_avc_path(u->dentry, u->mnt);
+ audit_log_format(ab, " name=");
+ audit_log_untrustedstring(ab, u->dentry->d_name.name);
break;
}
if (!u->addr)
break;
len = u->addr->len-sizeof(short);
p = &u->addr->name->sun_path[0];
+ audit_log_format(ab, " path=");
if (*p)
- audit_log_format(ab,
- "path=%*.*s", len,
- len, p);
+ audit_log_untrustedstring(ab, p);
else
- audit_log_format(ab,
- "path=@%*.*s", len-1,
- len-1, p+1);
+ audit_log_hex(ab, p, len);
break;
}
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index aae1e794fe4..17a1189f1ff 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1658,9 +1658,8 @@ static int selinux_bprm_secureexec (struct linux_binprm *bprm)
static void selinux_bprm_free_security(struct linux_binprm *bprm)
{
- struct bprm_security_struct *bsec = bprm->security;
+ kfree(bprm->security);
bprm->security = NULL;
- kfree(bsec);
}
extern struct vfsmount *selinuxfs_mount;
@@ -1945,6 +1944,7 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void
} while (*in_end++);
copy_page(in_save, nosec_save);
+ free_page((unsigned long)nosec_save);
out:
return rc;
}
@@ -2476,6 +2476,17 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
prot = reqprot;
#ifndef CONFIG_PPC32
+ if ((prot & PROT_EXEC) && !(vma->vm_flags & VM_EXECUTABLE) &&
+ (vma->vm_start >= vma->vm_mm->start_brk &&
+ vma->vm_end <= vma->vm_mm->brk)) {
+ /*
+ * We are making an executable mapping in the brk region.
+ * This has an additional execheap check.
+ */
+ rc = task_has_perm(current, current, PROCESS__EXECHEAP);
+ if (rc)
+ return rc;
+ }
if (vma->vm_file != NULL && vma->anon_vma != NULL && (prot & PROT_EXEC)) {
/*
* We are making executable a file mapping that has
@@ -2487,6 +2498,16 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
if (rc)
return rc;
}
+ if (!vma->vm_file && (prot & PROT_EXEC) &&
+ vma->vm_start <= vma->vm_mm->start_stack &&
+ vma->vm_end >= vma->vm_mm->start_stack) {
+ /* Attempt to make the process stack executable.
+ * This has an additional execstack check.
+ */
+ rc = task_has_perm(current, current, PROCESS__EXECSTACK);
+ if (rc)
+ return rc;
+ }
#endif
return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
@@ -3419,7 +3440,7 @@ static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb)
err = selinux_nlmsg_lookup(isec->sclass, nlh->nlmsg_type, &perm);
if (err) {
if (err == -EINVAL) {
- audit_log(current->audit_context,
+ audit_log(current->audit_context, AUDIT_SELINUX_ERR,
"SELinux: unrecognized netlink message"
" type=%hu for sclass=%hu\n",
nlh->nlmsg_type, isec->sclass);
diff --git a/security/selinux/include/av_perm_to_string.h b/security/selinux/include/av_perm_to_string.h
index 8928bb4d3c5..1deb59e1b76 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -70,6 +70,8 @@
S_(SECCLASS_PROCESS, PROCESS__DYNTRANSITION, "dyntransition")
S_(SECCLASS_PROCESS, PROCESS__SETCURRENT, "setcurrent")
S_(SECCLASS_PROCESS, PROCESS__EXECMEM, "execmem")
+ S_(SECCLASS_PROCESS, PROCESS__EXECSTACK, "execstack")
+ S_(SECCLASS_PROCESS, PROCESS__EXECHEAP, "execheap")
S_(SECCLASS_MSGQ, MSGQ__ENQUEUE, "enqueue")
S_(SECCLASS_MSG, MSG__SEND, "send")
S_(SECCLASS_MSG, MSG__RECEIVE, "receive")
diff --git a/security/selinux/include/av_permissions.h b/security/selinux/include/av_permissions.h
index bdfce4ca8f8..a78b5d59c9f 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -465,6 +465,8 @@
#define PROCESS__DYNTRANSITION 0x00800000UL
#define PROCESS__SETCURRENT 0x01000000UL
#define PROCESS__EXECMEM 0x02000000UL
+#define PROCESS__EXECSTACK 0x04000000UL
+#define PROCESS__EXECHEAP 0x08000000UL
#define IPC__CREATE 0x00000001UL
#define IPC__DESTROY 0x00000002UL
diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c
index b3adb481bc2..92b057becb4 100644
--- a/security/selinux/nlmsgtab.c
+++ b/security/selinux/nlmsgtab.c
@@ -63,6 +63,8 @@ static struct nlmsg_perm nlmsg_route_perms[] =
{ RTM_GETPREFIX, NETLINK_ROUTE_SOCKET__NLMSG_READ },
{ RTM_GETMULTICAST, NETLINK_ROUTE_SOCKET__NLMSG_READ },
{ RTM_GETANYCAST, NETLINK_ROUTE_SOCKET__NLMSG_READ },
+ { RTM_GETNEIGHTBL, NETLINK_ROUTE_SOCKET__NLMSG_READ },
+ { RTM_SETNEIGHTBL, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
};
static struct nlmsg_perm nlmsg_firewall_perms[] =
@@ -97,6 +99,7 @@ static struct nlmsg_perm nlmsg_audit_perms[] =
{ AUDIT_ADD, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_DEL, NETLINK_AUDIT_SOCKET__NLMSG_WRITE },
{ AUDIT_USER, NETLINK_AUDIT_SOCKET__NLMSG_RELAY },
+ { AUDIT_SIGNAL_INFO, NETLINK_AUDIT_SOCKET__NLMSG_READ },
};
@@ -141,8 +144,13 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
break;
case SECCLASS_NETLINK_AUDIT_SOCKET:
- err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
- sizeof(nlmsg_audit_perms));
+ if (nlmsg_type >= AUDIT_FIRST_USER_MSG &&
+ nlmsg_type <= AUDIT_LAST_USER_MSG) {
+ *perm = NETLINK_AUDIT_SOCKET__NLMSG_RELAY;
+ } else {
+ err = nlmsg_perm(nlmsg_type, perm, nlmsg_audit_perms,
+ sizeof(nlmsg_audit_perms));
+ }
break;
/* No messaging from userspace, or class unknown/unhandled */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 07221568b50..8eb140dd2e4 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -951,8 +951,7 @@ static int sel_make_bools(void)
u32 sid;
/* remove any existing files */
- if (bool_pending_values)
- kfree(bool_pending_values);
+ kfree(bool_pending_values);
sel_remove_bools(dir);
@@ -997,10 +996,8 @@ static int sel_make_bools(void)
out:
free_page((unsigned long)page);
if (names) {
- for (i = 0; i < num; i++) {
- if (names[i])
- kfree(names[i]);
- }
+ for (i = 0; i < num; i++)
+ kfree(names[i]);
kfree(names);
}
return ret;
diff --git a/security/selinux/ss/conditional.c b/security/selinux/ss/conditional.c
index b53441184ac..e2057f5a411 100644
--- a/security/selinux/ss/conditional.c
+++ b/security/selinux/ss/conditional.c
@@ -166,16 +166,14 @@ static void cond_list_destroy(struct cond_node *list)
void cond_policydb_destroy(struct policydb *p)
{
- if (p->bool_val_to_struct != NULL)
- kfree(p->bool_val_to_struct);
+ kfree(p->bool_val_to_struct);
avtab_destroy(&p->te_cond_avtab);
cond_list_destroy(p->cond_list);
}
int cond_init_bool_indexes(struct policydb *p)
{
- if (p->bool_val_to_struct)
- kfree(p->bool_val_to_struct);
+ kfree(p->bool_val_to_struct);
p->bool_val_to_struct = (struct cond_bool_datum**)
kmalloc(p->p_bools.nprim * sizeof(struct cond_bool_datum*), GFP_KERNEL);
if (!p->bool_val_to_struct)
@@ -185,8 +183,7 @@ int cond_init_bool_indexes(struct policydb *p)
int cond_destroy_bool(void *key, void *datum, void *p)
{
- if (key)
- kfree(key);
+ kfree(key);
kfree(datum);
return 0;
}
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 14190efbf33..785c33cf486 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -590,17 +590,12 @@ void policydb_destroy(struct policydb *p)
hashtab_destroy(p->symtab[i].table);
}
- for (i = 0; i < SYM_NUM; i++) {
- if (p->sym_val_to_name[i])
- kfree(p->sym_val_to_name[i]);
- }
+ for (i = 0; i < SYM_NUM; i++)
+ kfree(p->sym_val_to_name[i]);
- if (p->class_val_to_struct)
- kfree(p->class_val_to_struct);
- if (p->role_val_to_struct)
- kfree(p->role_val_to_struct);
- if (p->user_val_to_struct)
- kfree(p->user_val_to_struct);
+ kfree(p->class_val_to_struct);
+ kfree(p->role_val_to_struct);
+ kfree(p->user_val_to_struct);
avtab_destroy(&p->te_avtab);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 8449d667b06..922bb45054a 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -365,7 +365,7 @@ static int security_validtrans_handle_fail(struct context *ocontext,
goto out;
if (context_struct_to_string(tcontext, &t, &tlen) < 0)
goto out;
- audit_log(current->audit_context,
+ audit_log(current->audit_context, AUDIT_SELINUX_ERR,
"security_validate_transition: denied for"
" oldcontext=%s newcontext=%s taskcontext=%s tclass=%s",
o, n, t, policydb.p_class_val_to_name[tclass-1]);
@@ -742,7 +742,7 @@ static int compute_sid_handle_invalid_context(
goto out;
if (context_struct_to_string(newcontext, &n, &nlen) < 0)
goto out;
- audit_log(current->audit_context,
+ audit_log(current->audit_context, AUDIT_SELINUX_ERR,
"security_compute_sid: invalid context %s"
" for scontext=%s"
" tcontext=%s"
@@ -1705,11 +1705,9 @@ out:
err:
if (*names) {
for (i = 0; i < *len; i++)
- if ((*names)[i])
- kfree((*names)[i]);
+ kfree((*names)[i]);
}
- if (*values)
- kfree(*values);
+ kfree(*values);
goto out;
}