summaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2022-12-13 09:32:05 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2022-12-13 09:32:05 -0800
commit57888f7b952d3f2696f82a701f1b3d9de7e346d3 (patch)
tree431172a2adad36b038c0782773009dbf49494826 /security/selinux
parentbbdf4d54618ca1d4af304eab6631d68fd2d6ce39 (diff)
parent048be156491ff1aeb0fe5ff0862644d38cd39015 (diff)
downloadlinux-stable-57888f7b952d3f2696f82a701f1b3d9de7e346d3.tar.gz
linux-stable-57888f7b952d3f2696f82a701f1b3d9de7e346d3.tar.bz2
linux-stable-57888f7b952d3f2696f82a701f1b3d9de7e346d3.zip
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
Diffstat (limited to 'security/selinux')
-rw-r--r--security/selinux/selinuxfs.c4
-rw-r--r--security/selinux/ss/services.c54
-rw-r--r--security/selinux/ss/services.h15
-rw-r--r--security/selinux/ss/sidtab.c23
-rw-r--r--security/selinux/ss/sidtab.h3
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;
};