aboutsummaryrefslogtreecommitdiff
path: root/security/selinux
diff options
context:
space:
mode:
authorLinus Torvalds2022-08-02 14:51:47 -0700
committerLinus Torvalds2022-08-02 14:51:47 -0700
commit79802ada87faeb28cfa2bd36e17591e7b8c6ba72 (patch)
treeb573ba522d599c670f79c461461f90c1fdf39581 /security/selinux
parent6991a564f59742a0926be7421dff370135c44a97 (diff)
parentef54ccb61616d8293bc68220d88a8e74271141b5 (diff)
Merge tag 'selinux-pr-20220801' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore: "A relatively small set of patches for SELinux this time, eight patches in total with really only one significant change. The highlights are: - Add support for proper labeling of memfd_secret anonymous inodes. This will allow LSMs that implement the anonymous inode hooks to apply security policy to memfd_secret() fds. - Various small improvements to memory management: fixed leaks, freed memory when needed, boundary checks. - Hardened the selinux_audit_data struct with __randomize_layout. - A minor documentation tweak to fix a formatting/style issue" * tag 'selinux-pr-20220801' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: selinux_add_opt() callers free memory selinux: Add boundary check in put_entry() selinux: fix memleak in security_read_state_kernel() docs: selinux: add '=' signs to kernel boot options mm: create security context for memfd_secret inodes selinux: fix typos in comments selinux: drop unnecessary NULL check selinux: add __randomize_layout to selinux_audit_data
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/hooks.c17
-rw-r--r--security/selinux/include/audit.h2
-rw-r--r--security/selinux/include/avc.h2
-rw-r--r--security/selinux/ss/policydb.h2
-rw-r--r--security/selinux/ss/services.c9
5 files changed, 19 insertions, 13 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1bbd53321d13..79573504783b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -640,7 +640,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
* we need to skip the double mount verification.
*
* This does open a hole in which we will not notice if the first
- * mount using this sb set explict options and a second mount using
+ * mount using this sb set explicit options and a second mount using
* this sb does not set any security options. (The first options
* will be used for both mounts)
*/
@@ -944,10 +944,12 @@ out:
return rc;
}
+/*
+ * NOTE: the caller is resposible for freeing the memory even if on error.
+ */
static int selinux_add_opt(int token, const char *s, void **mnt_opts)
{
struct selinux_mnt_opts *opts = *mnt_opts;
- bool is_alloc_opts = false;
u32 *dst_sid;
int rc;
@@ -955,7 +957,7 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
/* eaten and completely ignored */
return 0;
if (!s)
- return -ENOMEM;
+ return -EINVAL;
if (!selinux_initialized(&selinux_state)) {
pr_warn("SELinux: Unable to set superblock options before the security server is initialized\n");
@@ -967,7 +969,6 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
if (!opts)
return -ENOMEM;
*mnt_opts = opts;
- is_alloc_opts = true;
}
switch (token) {
@@ -1002,10 +1003,6 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts)
return rc;
err:
- if (is_alloc_opts) {
- kfree(opts);
- *mnt_opts = NULL;
- }
pr_warn(SEL_MOUNT_FAIL_MSG);
return -EINVAL;
}
@@ -1019,7 +1016,7 @@ static int show_sid(struct seq_file *m, u32 sid)
rc = security_sid_to_context(&selinux_state, sid,
&context, &len);
if (!rc) {
- bool has_comma = context && strchr(context, ',');
+ bool has_comma = strchr(context, ',');
seq_putc(m, '=');
if (has_comma)
@@ -6792,7 +6789,7 @@ static u32 bpf_map_fmode_to_av(fmode_t fmode)
}
/* This function will check the file pass through unix socket or binder to see
- * if it is a bpf related object. And apply correspinding checks on the bpf
+ * if it is a bpf related object. And apply corresponding checks on the bpf
* object based on the type. The bpf maps and programs, not like other files and
* socket, are using a shared anonymous inode inside the kernel as their inode.
* So checking that inode cannot identify if the process have privilege to
diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h
index 1cba83d17f41..406bceb90c6c 100644
--- a/security/selinux/include/audit.h
+++ b/security/selinux/include/audit.h
@@ -18,7 +18,7 @@
/**
* selinux_audit_rule_init - alloc/init an selinux audit rule structure.
* @field: the field this rule refers to
- * @op: the operater the rule uses
+ * @op: the operator the rule uses
* @rulestr: the text "target" of the rule
* @rule: pointer to the new rule structure returned via this
*
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 2b372f98f2d7..5525b94fd266 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -53,7 +53,7 @@ struct selinux_audit_data {
u32 denied;
int result;
struct selinux_state *state;
-};
+} __randomize_layout;
/*
* AVC operations
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index c24d4e1063ea..ffc4e7bad205 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -370,6 +370,8 @@ static inline int put_entry(const void *buf, size_t bytes, int num, struct polic
{
size_t len = bytes * num;
+ if (len > fp->len)
+ return -EINVAL;
memcpy(fp->data, buf, len);
fp->data += len;
fp->len -= len;
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 69b2734311a6..fe5fcf571c56 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -4048,6 +4048,7 @@ int security_read_policy(struct selinux_state *state,
int security_read_state_kernel(struct selinux_state *state,
void **data, size_t *len)
{
+ int err;
struct selinux_policy *policy;
policy = rcu_dereference_protected(
@@ -4060,5 +4061,11 @@ int security_read_state_kernel(struct selinux_state *state,
if (!*data)
return -ENOMEM;
- return __security_read_policy(policy, *data, len);
+ err = __security_read_policy(policy, *data, len);
+ if (err) {
+ vfree(*data);
+ *data = NULL;
+ *len = 0;
+ }
+ return err;
}