Re: [PATCH] selinux: remove the sidtab context conversion indirect calls

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/8/2022 8:00 PM, Paul Moore wrote:
> The sidtab conversion code has support for multiple context
> conversion routines through the use of function pointers and
> indirect calls.  However, the reality is that all current users rely
> on the same conversion routine: convert_context().  This patch does
> away with this extra complexity and replaces the indirect calls
> with direct function calls; allowing us to remove a layer of
> obfuscation and create cleaner, more maintainable code.
>
> Signed-off-by: Paul Moore <paul@xxxxxxxxxxxxxx>

The SELinux code is enhanced by this sort of clean-up.

Reviewed-by: Casey Schaufler <casey@xxxxxxxxxxxxxxxx>

> ---
>  security/selinux/ss/services.c | 51 ++++++++++++++--------------------
>  security/selinux/ss/services.h | 14 ++++++++--
>  security/selinux/ss/sidtab.c   | 21 ++++++++------
>  security/selinux/ss/sidtab.h   |  3 +-
>  4 files changed, 45 insertions(+), 44 deletions(-)
>
> diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
> index fe5fcf571c564..e63c4f942fd6a 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,17 +2008,20 @@ 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
> + *
> + * 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)
> +int services_convert_context(struct convert_context_args *args,
> +			     struct context *oldc, struct context *newc)
>  {
> -	struct convert_context_args *args;
>  	struct ocontext *oc;
>  	struct role_datum *role;
>  	struct type_datum *typdatum;
> @@ -2033,15 +2030,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_KERNEL);
>  		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.
> @@ -2072,8 +2066,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;
> @@ -2087,8 +2080,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;
> @@ -2122,8 +2114,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;
>  	}
> @@ -2332,21 +2323,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 9555ad074303c..6348c95ff0e52 100644
> --- a/security/selinux/ss/services.h
> +++ b/security/selinux/ss/services.h
> @@ -29,10 +29,18 @@ 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);
>  
>  #endif	/* _SS_SERVICES_H_ */
> diff --git a/security/selinux/ss/sidtab.c b/security/selinux/ss/sidtab.c
> index a54b8652bfb50..1c3d2cda6b92a 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,28 @@ 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);
> +		rc = services_convert_context(convert->args,
> +					      context, &dst_convert->context);
>  		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 +405,9 @@ 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);
> +			rc = services_convert_context(convert->args,
> +					&esrc->ptr_leaf->entries[i].context,
> +					&edst->ptr_leaf->entries[i].context);
>  			if (rc)
>  				return rc;
>  			(*pos)++;
> diff --git a/security/selinux/ss/sidtab.h b/security/selinux/ss/sidtab.h
> index 4eff0e49dcb22..72810a080e77b 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);
> -	void *args;
> +	struct convert_context_args *args;
>  	struct sidtab *target;
>  };
>  



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux