diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-03 00:51:47 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-08-03 00:51:47 +0300 |
commit | 79802ada87faeb28cfa2bd36e17591e7b8c6ba72 (patch) | |
tree | b573ba522d599c670f79c461461f90c1fdf39581 | |
parent | 6991a564f59742a0926be7421dff370135c44a97 (diff) | |
parent | ef54ccb61616d8293bc68220d88a8e74271141b5 (diff) | |
download | linux-79802ada87faeb28cfa2bd36e17591e7b8c6ba72.tar.xz |
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
-rw-r--r-- | Documentation/admin-guide/kernel-parameters.txt | 4 | ||||
-rw-r--r-- | mm/secretmem.c | 9 | ||||
-rw-r--r-- | security/selinux/hooks.c | 17 | ||||
-rw-r--r-- | security/selinux/include/audit.h | 2 | ||||
-rw-r--r-- | security/selinux/include/avc.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 9 |
7 files changed, 30 insertions, 15 deletions
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 5e9147fe8968..a79b1b367e66 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -556,7 +556,7 @@ nosocket -- Disable socket memory accounting. nokmem -- Disable kernel memory accounting. - checkreqprot [SELINUX] Set initial checkreqprot flag value. + checkreqprot= [SELINUX] Set initial checkreqprot flag value. Format: { "0" | "1" } See security/selinux/Kconfig help text. 0 -- check protection applied by kernel (includes @@ -1445,7 +1445,7 @@ (in particular on some ATI chipsets). The kernel tries to set a reasonable default. - enforcing [SELINUX] Set initial enforcing status. + enforcing= [SELINUX] Set initial enforcing status. Format: {"0" | "1"} See security/selinux/Kconfig help text. 0 -- permissive (log only, no denials). diff --git a/mm/secretmem.c b/mm/secretmem.c index f06279d6190a..71fb78f59d72 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -199,11 +199,20 @@ static struct file *secretmem_file_create(unsigned long flags) { struct file *file = ERR_PTR(-ENOMEM); struct inode *inode; + const char *anon_name = "[secretmem]"; + const struct qstr qname = QSTR_INIT(anon_name, strlen(anon_name)); + int err; inode = alloc_anon_inode(secretmem_mnt->mnt_sb); if (IS_ERR(inode)) return ERR_CAST(inode); + err = security_inode_init_security_anon(inode, &qname, NULL); + if (err) { + file = ERR_PTR(err); + goto err_free_inode; + } + file = alloc_file_pseudo(inode, secretmem_mnt, "secretmem", O_RDWR, &secretmem_fops); if (IS_ERR(file)) 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; } |