diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-13 09:32:05 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-12-13 09:32:05 -0800 |
commit | 57888f7b952d3f2696f82a701f1b3d9de7e346d3 (patch) | |
tree | 431172a2adad36b038c0782773009dbf49494826 | |
parent | bbdf4d54618ca1d4af304eab6631d68fd2d6ce39 (diff) | |
parent | 048be156491ff1aeb0fe5ff0862644d38cd39015 (diff) |
Merge tag 'selinux-pr-20221212' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore:
"Two SELinux patches: one increases the sleep time on deprecated
functionality, and one removes the indirect calls in the sidtab
context conversion code"
* tag 'selinux-pr-20221212' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
selinux: remove the sidtab context conversion indirect calls
selinux: increase the deprecation sleep for checkreqprot and runtime disable
-rw-r--r-- | security/selinux/selinuxfs.c | 4 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 54 | ||||
-rw-r--r-- | security/selinux/ss/services.h | 15 | ||||
-rw-r--r-- | security/selinux/ss/sidtab.c | 23 | ||||
-rw-r--r-- | security/selinux/ss/sidtab.h | 3 |
5 files changed, 52 insertions, 47 deletions
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index a00d19139436..0a6894cdc54d 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -294,7 +294,7 @@ static ssize_t sel_write_disable(struct file *file, const char __user *buf, */ pr_err("SELinux: Runtime disable is deprecated, use selinux=0 on the kernel cmdline.\n"); pr_err("SELinux: https://github.com/SELinuxProject/selinux-kernel/wiki/DEPRECATE-runtime-disable\n"); - ssleep(5); + ssleep(15); if (count >= PAGE_SIZE) return -ENOMEM; @@ -763,7 +763,7 @@ static ssize_t sel_write_checkreqprot(struct file *file, const char __user *buf, checkreqprot_set(fsi->state, (new_value ? 1 : 0)); if (new_value) - ssleep(5); + ssleep(15); length = count; selinux_ima_measure_state(fsi->state); diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 64a6a37dc36d..0092b29022f5 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -68,12 +68,6 @@ #include "policycap_names.h" #include "ima.h" -struct convert_context_args { - struct selinux_state *state; - struct policydb *oldp; - struct policydb *newp; -}; - struct selinux_policy_convert_data { struct convert_context_args args; struct sidtab_convert_params sidtab_params; @@ -2014,18 +2008,22 @@ static inline int convert_context_handle_invalid_context( return 0; } -/* - * Convert the values in the security context - * structure `oldc' from the values specified - * in the policy `p->oldp' to the values specified - * in the policy `p->newp', storing the new context - * in `newc'. Verify that the context is valid - * under the new policy. +/** + * services_convert_context - Convert a security context across policies. + * @args: populated convert_context_args struct + * @oldc: original context + * @newc: converted context + * @gfp_flags: allocation flags + * + * Convert the values in the security context structure @oldc from the values + * specified in the policy @args->oldp to the values specified in the policy + * @args->newp, storing the new context in @newc, and verifying that the + * context is valid under the new policy. */ -static int convert_context(struct context *oldc, struct context *newc, void *p, - gfp_t gfp_flags) +int services_convert_context(struct convert_context_args *args, + struct context *oldc, struct context *newc, + gfp_t gfp_flags) { - struct convert_context_args *args; struct ocontext *oc; struct role_datum *role; struct type_datum *typdatum; @@ -2034,15 +2032,12 @@ static int convert_context(struct context *oldc, struct context *newc, void *p, u32 len; int rc; - args = p; - if (oldc->str) { s = kstrdup(oldc->str, gfp_flags); if (!s) return -ENOMEM; - rc = string_to_context_struct(args->newp, NULL, s, - newc, SECSID_NULL); + rc = string_to_context_struct(args->newp, NULL, s, newc, SECSID_NULL); if (rc == -EINVAL) { /* * Retain string representation for later mapping. @@ -2073,8 +2068,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p, /* Convert the user. */ usrdatum = symtab_search(&args->newp->p_users, - sym_name(args->oldp, - SYM_USERS, oldc->user - 1)); + sym_name(args->oldp, SYM_USERS, oldc->user - 1)); if (!usrdatum) goto bad; newc->user = usrdatum->value; @@ -2088,8 +2082,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p, /* Convert the type. */ typdatum = symtab_search(&args->newp->p_types, - sym_name(args->oldp, - SYM_TYPES, oldc->type - 1)); + sym_name(args->oldp, SYM_TYPES, oldc->type - 1)); if (!typdatum) goto bad; newc->type = typdatum->value; @@ -2123,8 +2116,7 @@ static int convert_context(struct context *oldc, struct context *newc, void *p, /* Check the validity of the new context. */ if (!policydb_context_isvalid(args->newp, newc)) { rc = convert_context_handle_invalid_context(args->state, - args->oldp, - oldc); + args->oldp, oldc); if (rc) goto bad; } @@ -2333,21 +2325,21 @@ int security_load_policy(struct selinux_state *state, void *data, size_t len, goto err_free_isids; } + /* + * Convert the internal representations of contexts + * in the new SID table. + */ + convert_data = kmalloc(sizeof(*convert_data), GFP_KERNEL); if (!convert_data) { rc = -ENOMEM; goto err_free_isids; } - /* - * Convert the internal representations of contexts - * in the new SID table. - */ convert_data->args.state = state; convert_data->args.oldp = &oldpolicy->policydb; convert_data->args.newp = &newpolicy->policydb; - convert_data->sidtab_params.func = convert_context; convert_data->sidtab_params.args = &convert_data->args; convert_data->sidtab_params.target = newpolicy->sidtab; diff --git a/security/selinux/ss/services.h b/security/selinux/ss/services.h index 9555ad074303..c4301626487f 100644 --- a/security/selinux/ss/services.h +++ b/security/selinux/ss/services.h @@ -29,10 +29,19 @@ struct selinux_policy { u32 latest_granting; } __randomize_layout; -void services_compute_xperms_drivers(struct extended_perms *xperms, - struct avtab_node *node); +struct convert_context_args { + struct selinux_state *state; + struct policydb *oldp; + struct policydb *newp; +}; +void services_compute_xperms_drivers(struct extended_perms *xperms, + struct avtab_node *node); void services_compute_xperms_decision(struct extended_perms_decision *xpermd, - struct avtab_node *node); + struct avtab_node *node); + +int services_convert_context(struct convert_context_args *args, + struct context *oldc, struct context *newc, + gfp_t gfp_flags); #endif /* _SS_SERVICES_H_ */ diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c index db5cce385bf8..38d25173aebd 100644 --- a/security/selinux/ss/sidtab.c +++ b/security/selinux/ss/sidtab.c @@ -18,6 +18,7 @@ #include "flask.h" #include "security.h" #include "sidtab.h" +#include "services.h" struct sidtab_str_cache { struct rcu_head rcu_member; @@ -292,7 +293,6 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, } count = s->count; - convert = s->convert; /* bail out if we already reached max entries */ rc = -EOVERFLOW; @@ -316,25 +316,29 @@ int sidtab_context_to_sid(struct sidtab *s, struct context *context, * if we are building a new sidtab, we need to convert the context * and insert it there as well */ + convert = s->convert; if (convert) { + struct sidtab *target = convert->target; + rc = -ENOMEM; - dst_convert = sidtab_do_lookup(convert->target, count, 1); + dst_convert = sidtab_do_lookup(target, count, 1); if (!dst_convert) { context_destroy(&dst->context); goto out_unlock; } - rc = convert->func(context, &dst_convert->context, - convert->args, GFP_ATOMIC); + rc = services_convert_context(convert->args, + context, &dst_convert->context, + GFP_ATOMIC); if (rc) { context_destroy(&dst->context); goto out_unlock; } dst_convert->sid = index_to_sid(count); dst_convert->hash = context_compute_hash(&dst_convert->context); - convert->target->count = count + 1; + target->count = count + 1; - hash_add_rcu(convert->target->context_to_sid, + hash_add_rcu(target->context_to_sid, &dst_convert->list, dst_convert->hash); } @@ -402,9 +406,10 @@ static int sidtab_convert_tree(union sidtab_entry_inner *edst, } i = 0; while (i < SIDTAB_LEAF_ENTRIES && *pos < count) { - rc = convert->func(&esrc->ptr_leaf->entries[i].context, - &edst->ptr_leaf->entries[i].context, - convert->args, GFP_KERNEL); + rc = services_convert_context(convert->args, + &esrc->ptr_leaf->entries[i].context, + &edst->ptr_leaf->entries[i].context, + GFP_KERNEL); if (rc) return rc; (*pos)++; diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h index 9fce0d553fe2..72810a080e77 100644 --- a/security/selinux/ss/sidtab.h +++ b/security/selinux/ss/sidtab.h @@ -65,8 +65,7 @@ struct sidtab_isid_entry { }; struct sidtab_convert_params { - int (*func)(struct context *oldc, struct context *newc, void *args, gfp_t gfp_flags); - void *args; + struct convert_context_args *args; struct sidtab *target; }; |