diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 13:03:06 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 13:03:06 -0800 |
commit | a135ce4400bb87f229ab33a663987327d9e0b2a0 (patch) | |
tree | d3ca45420412ad46ee34f189e7902ec45d62f32c /security | |
parent | dabd40ecaf693a18afd4c59c8d7280610d95b66e (diff) | |
parent | 6cd9d4b97891560b61681cad9cc4307ce0719abc (diff) | |
download | linux-a135ce4400bb87f229ab33a663987327d9e0b2a0.tar.bz2 |
Merge tag 'selinux-pr-20220110' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore:
"Nothing too significant, but five SELinux patches for v5.17 that do
the following:
- Harden the code through additional use of the struct_size() macro
- Plug some memory leaks
- Clean up the code via removal of the security_add_mnt_opt() LSM
hook and minor tweaks to selinux_add_opt()
- Rename security_task_getsecid_subj() to better reflect its actual
behavior/use - now called security_current_getsecid_subj()"
* tag 'selinux-pr-20220110' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: minor tweaks to selinux_add_opt()
selinux: fix potential memleak in selinux_add_opt()
security,selinux: remove security_add_mnt_opt()
selinux: Use struct_size() helper in kmalloc()
lsm: security_task_getsecid_subj() -> security_current_getsecid_subj()
Diffstat (limited to 'security')
-rw-r--r-- | security/apparmor/lsm.c | 13 | ||||
-rw-r--r-- | security/integrity/ima/ima_appraise.c | 2 | ||||
-rw-r--r-- | security/integrity/ima/ima_main.c | 14 | ||||
-rw-r--r-- | security/security.c | 14 | ||||
-rw-r--r-- | security/selinux/hooks.c | 84 | ||||
-rw-r--r-- | security/selinux/ss/sidtab.c | 2 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 4 | ||||
-rw-r--r-- | security/smack/smack.h | 16 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 9 |
9 files changed, 49 insertions, 109 deletions
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 0d6585056f3d..4f0eecb67dde 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -728,7 +728,14 @@ static void apparmor_bprm_committed_creds(struct linux_binprm *bprm) return; } -static void apparmor_task_getsecid(struct task_struct *p, u32 *secid) +static void apparmor_current_getsecid_subj(u32 *secid) +{ + struct aa_label *label = aa_get_current_label(); + *secid = label->secid; + aa_put_label(label); +} + +static void apparmor_task_getsecid_obj(struct task_struct *p, u32 *secid) { struct aa_label *label = aa_get_task_label(p); *secid = label->secid; @@ -1252,8 +1259,8 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(task_free, apparmor_task_free), LSM_HOOK_INIT(task_alloc, apparmor_task_alloc), - LSM_HOOK_INIT(task_getsecid_subj, apparmor_task_getsecid), - LSM_HOOK_INIT(task_getsecid_obj, apparmor_task_getsecid), + LSM_HOOK_INIT(current_getsecid_subj, apparmor_current_getsecid_subj), + LSM_HOOK_INIT(task_getsecid_obj, apparmor_task_getsecid_obj), LSM_HOOK_INIT(task_setrlimit, apparmor_task_setrlimit), LSM_HOOK_INIT(task_kill, apparmor_task_kill), diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index dbba51583e7c..17232bbfb9f9 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c @@ -76,7 +76,7 @@ int ima_must_appraise(struct user_namespace *mnt_userns, struct inode *inode, if (!ima_appraise) return 0; - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); return ima_match_policy(mnt_userns, inode, current_cred(), secid, func, mask, IMA_APPRAISE | IMA_HASH, NULL, NULL, NULL, NULL); diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 465865412100..8c6e4514d494 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c @@ -408,7 +408,7 @@ int ima_file_mmap(struct file *file, unsigned long prot) u32 secid; if (file && (prot & PROT_EXEC)) { - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); return process_measurement(file, current_cred(), secid, NULL, 0, MAY_EXEC, MMAP_CHECK); } @@ -446,7 +446,7 @@ int ima_file_mprotect(struct vm_area_struct *vma, unsigned long prot) !(prot & PROT_EXEC) || (vma->vm_flags & VM_EXEC)) return 0; - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); inode = file_inode(vma->vm_file); action = ima_get_action(file_mnt_user_ns(vma->vm_file), inode, current_cred(), secid, MAY_EXEC, MMAP_CHECK, @@ -487,7 +487,7 @@ int ima_bprm_check(struct linux_binprm *bprm) int ret; u32 secid; - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); ret = process_measurement(bprm->file, current_cred(), secid, NULL, 0, MAY_EXEC, BPRM_CHECK); if (ret) @@ -512,7 +512,7 @@ int ima_file_check(struct file *file, int mask) { u32 secid; - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); return process_measurement(file, current_cred(), secid, NULL, 0, mask & (MAY_READ | MAY_WRITE | MAY_EXEC | MAY_APPEND), FILE_CHECK); @@ -709,7 +709,7 @@ int ima_read_file(struct file *file, enum kernel_read_file_id read_id, /* Read entire file for all partial reads. */ func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); return process_measurement(file, current_cred(), secid, NULL, 0, MAY_READ, func); } @@ -752,7 +752,7 @@ int ima_post_read_file(struct file *file, void *buf, loff_t size, } func = read_idmap[read_id] ?: FILE_CHECK; - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); return process_measurement(file, current_cred(), secid, buf, size, MAY_READ, func); } @@ -905,7 +905,7 @@ int process_buffer_measurement(struct user_namespace *mnt_userns, * buffer measurements. */ if (func) { - security_task_getsecid_subj(current, &secid); + security_current_getsecid_subj(&secid); action = ima_get_action(mnt_userns, inode, current_cred(), secid, 0, func, &pcr, &template, func_data, NULL); diff --git a/security/security.c b/security/security.c index c88167a414b4..3d4eb474f35b 100644 --- a/security/security.c +++ b/security/security.c @@ -994,14 +994,6 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb, } EXPORT_SYMBOL(security_sb_clone_mnt_opts); -int security_add_mnt_opt(const char *option, const char *val, int len, - void **mnt_opts) -{ - return call_int_hook(sb_add_mnt_opt, -EINVAL, - option, val, len, mnt_opts); -} -EXPORT_SYMBOL(security_add_mnt_opt); - int security_move_mount(const struct path *from_path, const struct path *to_path) { return call_int_hook(move_mount, 0, from_path, to_path); @@ -1808,12 +1800,12 @@ int security_task_getsid(struct task_struct *p) return call_int_hook(task_getsid, 0, p); } -void security_task_getsecid_subj(struct task_struct *p, u32 *secid) +void security_current_getsecid_subj(u32 *secid) { *secid = 0; - call_void_hook(task_getsecid_subj, p, secid); + call_void_hook(current_getsecid_subj, secid); } -EXPORT_SYMBOL(security_task_getsecid_subj); +EXPORT_SYMBOL(security_current_getsecid_subj); void security_task_getsecid_obj(struct task_struct *p, u32 *secid) { diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index dde4ecc0cd18..5b6895e4fc29 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -230,19 +230,6 @@ static inline u32 cred_sid(const struct cred *cred) } /* - * get the subjective security ID of a task - */ -static inline u32 task_sid_subj(const struct task_struct *task) -{ - u32 sid; - - rcu_read_lock(); - sid = cred_sid(rcu_dereference(task->cred)); - rcu_read_unlock(); - return sid; -} - -/* * get the objective security ID of a task */ static inline u32 task_sid_obj(const struct task_struct *task) @@ -988,82 +975,54 @@ out: 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; - if (token == Opt_seclabel) /* eaten and completely ignored */ + if (token == Opt_seclabel) + /* eaten and completely ignored */ return 0; + if (!s) + return -ENOMEM; if (!opts) { - opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); + opts = kzalloc(sizeof(*opts), GFP_KERNEL); if (!opts) return -ENOMEM; *mnt_opts = opts; + is_alloc_opts = true; } - if (!s) - return -ENOMEM; + switch (token) { case Opt_context: if (opts->context || opts->defcontext) - goto Einval; + goto err; opts->context = s; break; case Opt_fscontext: if (opts->fscontext) - goto Einval; + goto err; opts->fscontext = s; break; case Opt_rootcontext: if (opts->rootcontext) - goto Einval; + goto err; opts->rootcontext = s; break; case Opt_defcontext: if (opts->context || opts->defcontext) - goto Einval; + goto err; opts->defcontext = s; break; } - return 0; -Einval: - pr_warn(SEL_MOUNT_FAIL_MSG); - return -EINVAL; -} - -static int selinux_add_mnt_opt(const char *option, const char *val, int len, - void **mnt_opts) -{ - int token = Opt_error; - int rc, i; - - for (i = 0; i < ARRAY_SIZE(tokens); i++) { - if (strcmp(option, tokens[i].name) == 0) { - token = tokens[i].opt; - break; - } - } - if (token == Opt_error) - return -EINVAL; - - if (token != Opt_seclabel) { - val = kmemdup_nul(val, len, GFP_KERNEL); - if (!val) { - rc = -ENOMEM; - goto free_opt; - } - } - rc = selinux_add_opt(token, val, mnt_opts); - if (unlikely(rc)) { - kfree(val); - goto free_opt; - } - return rc; + return 0; -free_opt: - if (*mnt_opts) { - selinux_free_mnt_opts(*mnt_opts); +err: + if (is_alloc_opts) { + kfree(opts); *mnt_opts = NULL; } - return rc; + pr_warn(SEL_MOUNT_FAIL_MSG); + return -EINVAL; } static int show_sid(struct seq_file *m, u32 sid) @@ -4210,9 +4169,9 @@ static int selinux_task_getsid(struct task_struct *p) PROCESS__GETSESSION, NULL); } -static void selinux_task_getsecid_subj(struct task_struct *p, u32 *secid) +static void selinux_current_getsecid_subj(u32 *secid) { - *secid = task_sid_subj(p); + *secid = current_sid(); } static void selinux_task_getsecid_obj(struct task_struct *p, u32 *secid) @@ -7164,7 +7123,7 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), LSM_HOOK_INIT(task_getsid, selinux_task_getsid), - LSM_HOOK_INIT(task_getsecid_subj, selinux_task_getsecid_subj), + LSM_HOOK_INIT(current_getsecid_subj, selinux_current_getsecid_subj), LSM_HOOK_INIT(task_getsecid_obj, selinux_task_getsecid_obj), LSM_HOOK_INIT(task_setnice, selinux_task_setnice), LSM_HOOK_INIT(task_setioprio, selinux_task_setioprio), @@ -7303,7 +7262,6 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(fs_context_dup, selinux_fs_context_dup), LSM_HOOK_INIT(fs_context_parse_param, selinux_fs_context_parse_param), LSM_HOOK_INIT(sb_eat_lsm_opts, selinux_sb_eat_lsm_opts), - LSM_HOOK_INIT(sb_add_mnt_opt, selinux_add_mnt_opt), #ifdef CONFIG_SECURITY_NETWORK_XFRM LSM_HOOK_INIT(xfrm_policy_clone_security, selinux_xfrm_policy_clone), #endif diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index 656d50b09f76..293ec048af08 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -570,7 +570,7 @@ void sidtab_sid2str_put(struct sidtab *s, struct sidtab_entry *entry, goto out_unlock; } - cache = kmalloc(sizeof(struct sidtab_str_cache) + str_len, GFP_ATOMIC); + cache = kmalloc(struct_size(cache, str, str_len), GFP_ATOMIC); if (!cache) goto out_unlock; diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index be83e5ce4469..90697317895f 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -89,7 +89,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, if (str_len >= PAGE_SIZE) return -ENOMEM; - ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp); + ctx = kmalloc(struct_size(ctx, ctx_str, str_len + 1), gfp); if (!ctx) return -ENOMEM; @@ -360,7 +360,7 @@ int selinux_xfrm_state_alloc_acquire(struct xfrm_state *x, if (rc) return rc; - ctx = kmalloc(sizeof(*ctx) + str_len, GFP_ATOMIC); + ctx = kmalloc(struct_size(ctx, ctx_str, str_len), GFP_ATOMIC); if (!ctx) { rc = -ENOMEM; goto out; diff --git a/security/smack/smack.h b/security/smack/smack.h index 99c3422596ab..fc837dcebf96 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -389,22 +389,6 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp) return tsp->smk_task; } -static inline struct smack_known *smk_of_task_struct_subj( - const struct task_struct *t) -{ - struct smack_known *skp; - const struct cred *cred; - - rcu_read_lock(); - - cred = rcu_dereference(t->cred); - skp = smk_of_task(smack_cred(cred)); - - rcu_read_unlock(); - - return skp; -} - static inline struct smack_known *smk_of_task_struct_obj( const struct task_struct *t) { diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index efd35b07c7f8..14b279cc75c9 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2067,15 +2067,14 @@ static int smack_task_getsid(struct task_struct *p) } /** - * smack_task_getsecid_subj - get the subjective secid of the task - * @p: the task + * smack_current_getsecid_subj - get the subjective secid of the current task * @secid: where to put the result * * Sets the secid to contain a u32 version of the task's subjective smack label. */ -static void smack_task_getsecid_subj(struct task_struct *p, u32 *secid) +static void smack_current_getsecid_subj(u32 *secid) { - struct smack_known *skp = smk_of_task_struct_subj(p); + struct smack_known *skp = smk_of_current(); *secid = skp->smk_secid; } @@ -4807,7 +4806,7 @@ static struct security_hook_list smack_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(task_setpgid, smack_task_setpgid), LSM_HOOK_INIT(task_getpgid, smack_task_getpgid), LSM_HOOK_INIT(task_getsid, smack_task_getsid), - LSM_HOOK_INIT(task_getsecid_subj, smack_task_getsecid_subj), + LSM_HOOK_INIT(current_getsecid_subj, smack_current_getsecid_subj), LSM_HOOK_INIT(task_getsecid_obj, smack_task_getsecid_obj), LSM_HOOK_INIT(task_setnice, smack_task_setnice), LSM_HOOK_INIT(task_setioprio, smack_task_setioprio), |