diff options
Diffstat (limited to 'security/selinux/ss')
| -rw-r--r-- | security/selinux/ss/mls.c | 71 | ||||
| -rw-r--r-- | security/selinux/ss/mls.h | 4 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 55 | 
3 files changed, 93 insertions, 37 deletions
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 756036bcc24..d4c32c39ccc 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -15,6 +15,7 @@  #include <linux/slab.h>  #include <linux/string.h>  #include <linux/errno.h> +#include "sidtab.h"  #include "mls.h"  #include "policydb.h"  #include "services.h" @@ -208,6 +209,26 @@ int mls_context_isvalid(struct policydb *p, struct context *c)  }  /* + * Copies the MLS range from `src' into `dst'. + */ +static inline int mls_copy_context(struct context *dst, +				   struct context *src) +{ +	int l, rc = 0; + +	/* Copy the MLS range from the source context */ +	for (l = 0; l < 2; l++) { +		dst->range.level[l].sens = src->range.level[l].sens; +		rc = ebitmap_cpy(&dst->range.level[l].cat, +				 &src->range.level[l].cat); +		if (rc) +			break; +	} + +	return rc; +} + +/*   * Set the MLS fields in the security context structure   * `context' based on the string representation in   * the string `*scontext'.  Update `*scontext' to @@ -216,10 +237,20 @@ int mls_context_isvalid(struct policydb *p, struct context *c)   *   * This function modifies the string in place, inserting   * NULL characters to terminate the MLS fields. + * + * If a def_sid is provided and no MLS field is present, + * copy the MLS field of the associated default context. + * Used for upgraded to MLS systems where objects may lack + * MLS fields. + * + * Policy read-lock must be held for sidtab lookup. + *   */  int mls_context_to_sid(char oldc,  		       char **scontext, -		       struct context *context) +		       struct context *context, +		       struct sidtab *s, +		       u32 def_sid)  {  	char delim; @@ -231,9 +262,23 @@ int mls_context_to_sid(char oldc,  	if (!selinux_mls_enabled)  		return 0; -	/* No MLS component to the security context. */ -	if (!oldc) +	/* +	 * No MLS component to the security context, try and map to +	 * default if provided. +	 */ +	if (!oldc) { +		struct context *defcon; + +		if (def_sid == SECSID_NULL) +			goto out; + +		defcon = sidtab_search(s, def_sid); +		if (!defcon) +			goto out; + +		rc = mls_copy_context(context, defcon);  		goto out; +	}  	/* Extract low sensitivity. */  	scontextp = p = *scontext; @@ -334,26 +379,6 @@ out:  }  /* - * Copies the MLS range from `src' into `dst'. - */ -static inline int mls_copy_context(struct context *dst, -				   struct context *src) -{ -	int l, rc = 0; - -	/* Copy the MLS range from the source context */ -	for (l = 0; l < 2; l++) { -		dst->range.level[l].sens = src->range.level[l].sens; -		rc = ebitmap_cpy(&dst->range.level[l].cat, -				 &src->range.level[l].cat); -		if (rc) -			break; -	} - -	return rc; -} - -/*   * Copies the effective MLS range from `src' into `dst'.   */  static inline int mls_scopy_context(struct context *dst, diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index 0d37beaa85e..03de697c805 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -23,7 +23,9 @@ int mls_context_isvalid(struct policydb *p, struct context *c);  int mls_context_to_sid(char oldc,  	               char **scontext, -		       struct context *context); +		       struct context *context, +		       struct sidtab *s, +		       u32 def_sid);  int mls_convert_context(struct policydb *oldp,  			struct policydb *newp, diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 922bb45054a..014120474e6 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -601,18 +601,7 @@ out:  } -/** - * security_context_to_sid - Obtain a SID for a given security context. - * @scontext: security context - * @scontext_len: length in bytes - * @sid: security identifier, SID - * - * Obtains a SID associated with the security context that - * has the string representation specified by @scontext. - * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient - * memory is available, or 0 on success. - */ -int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) +static int security_context_to_sid_core(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid)  {  	char *scontext2;  	struct context context; @@ -703,7 +692,7 @@ int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid)  	context.type = typdatum->value; -	rc = mls_context_to_sid(oldc, &p, &context); +	rc = mls_context_to_sid(oldc, &p, &context, &sidtab, def_sid);  	if (rc)  		goto out_unlock; @@ -727,6 +716,46 @@ out:  	return rc;  } +/** + * security_context_to_sid - Obtain a SID for a given security context. + * @scontext: security context + * @scontext_len: length in bytes + * @sid: security identifier, SID + * + * Obtains a SID associated with the security context that + * has the string representation specified by @scontext. + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient + * memory is available, or 0 on success. + */ +int security_context_to_sid(char *scontext, u32 scontext_len, u32 *sid) +{ +	return security_context_to_sid_core(scontext, scontext_len, +	                                    sid, SECSID_NULL); +} + +/** + * security_context_to_sid_default - Obtain a SID for a given security context, + * falling back to specified default if needed. + * + * @scontext: security context + * @scontext_len: length in bytes + * @sid: security identifier, SID + * @def_sid: default SID to assign on errror + * + * Obtains a SID associated with the security context that + * has the string representation specified by @scontext. + * The default SID is passed to the MLS layer to be used to allow + * kernel labeling of the MLS field if the MLS field is not present + * (for upgrading to MLS without full relabel). + * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient + * memory is available, or 0 on success. + */ +int security_context_to_sid_default(char *scontext, u32 scontext_len, u32 *sid, u32 def_sid) +{ +	return security_context_to_sid_core(scontext, scontext_len, +	                                    sid, def_sid); +} +  static int compute_sid_handle_invalid_context(  	struct context *scontext,  	struct context *tcontext,  |