Re: [PATCH] Allowing MLS->non-MLS and vice versa upon policy reload

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

 



On Wed, 2010-02-03 at 16:40 +0100, Guido Trentalancia wrote:
> Author: Guido Trentalancia <guido@xxxxxxxxxxxxxxxx>
> Date:   Mon Feb 02 23:11:07 2010 +0100
> 
>     Allow runtime switching between different policy types (e.g. from a MLS/MCS
>     policy to a non-MLS/non-MCS policy or viceversa).
> 
>     Signed-off-by: Guido Trentalancia <guido@xxxxxxxxxxxxxxxx>

Acked-by: Stephen Smalley <sds@xxxxxxxxxxxxx>

> 
> ---
> 
>  security/selinux/include/security.h |    3 -
>  security/selinux/selinuxfs.c        |    3 -
>  security/selinux/ss/context.h       |   12 -----
>  security/selinux/ss/mls.c           |   26 +++++-----
>  security/selinux/ss/mls.h           |    2 
>  security/selinux/ss/mls_types.h     |    7 --
>  security/selinux/ss/policydb.c      |   24 +---------
>  security/selinux/ss/policydb.h      |    4 +
>  security/selinux/ss/services.c      |   62 +++++++++++++++++++++++---
>  9 files changed, 84 insertions(+), 59 deletions(-)
> 
> diff -pruN security-testing-2.6/security/selinux/include/security.h security-testing-2.6-new/security/selinux/include/security.h
> --- security-testing-2.6/security/selinux/include/security.h	2010-01-29 02:02:47.737045258 +0100
> +++ security-testing-2.6-new/security/selinux/include/security.h	2010-02-01 23:12:28.898233272 +0100
> @@ -57,7 +57,6 @@
>  struct netlbl_lsm_secattr;
>  
>  extern int selinux_enabled;
> -extern int selinux_mls_enabled;
>  
>  /* Policy capabilities */
>  enum {
> @@ -80,6 +79,8 @@ extern int selinux_policycap_openperm;
>  /* limitation of boundary depth  */
>  #define POLICYDB_BOUNDS_MAXDEPTH	4
>  
> +int security_mls_enabled(void);
> +
>  int security_load_policy(void *data, size_t len);
>  
>  int security_policycap_supported(unsigned int req_cap);
> diff -pruN security-testing-2.6/security/selinux/selinuxfs.c security-testing-2.6-new/security/selinux/selinuxfs.c
> --- security-testing-2.6/security/selinux/selinuxfs.c	2010-01-29 02:02:47.738046835 +0100
> +++ security-testing-2.6-new/security/selinux/selinuxfs.c	2010-02-01 22:06:21.709234039 +0100
> @@ -282,7 +282,8 @@ static ssize_t sel_read_mls(struct file 
>  	char tmpbuf[TMPBUFLEN];
>  	ssize_t length;
>  
> -	length = scnprintf(tmpbuf, TMPBUFLEN, "%d", selinux_mls_enabled);
> +	length = scnprintf(tmpbuf, TMPBUFLEN, "%d",
> +			   security_mls_enabled());
>  	return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
>  }
>  
> diff -pruN security-testing-2.6/security/selinux/ss/context.h security-testing-2.6-new/security/selinux/ss/context.h
> --- security-testing-2.6/security/selinux/ss/context.h	2010-01-29 01:06:42.160060332 +0100
> +++ security-testing-2.6-new/security/selinux/ss/context.h	2010-02-02 21:49:41.210011207 +0100
> @@ -41,9 +41,6 @@ static inline int mls_context_cpy(struct
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> -		return 0;
> -
>  	dst->range.level[0].sens = src->range.level[0].sens;
>  	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
>  	if (rc)
> @@ -64,9 +61,6 @@ static inline int mls_context_cpy_low(st
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> -		return 0;
> -
>  	dst->range.level[0].sens = src->range.level[0].sens;
>  	rc = ebitmap_cpy(&dst->range.level[0].cat, &src->range.level[0].cat);
>  	if (rc)
> @@ -82,9 +76,6 @@ out:
>  
>  static inline int mls_context_cmp(struct context *c1, struct context *c2)
>  {
> -	if (!selinux_mls_enabled)
> -		return 1;
> -
>  	return ((c1->range.level[0].sens == c2->range.level[0].sens) &&
>  		ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) &&
>  		(c1->range.level[1].sens == c2->range.level[1].sens) &&
> @@ -93,9 +84,6 @@ static inline int mls_context_cmp(struct
>  
>  static inline void mls_context_destroy(struct context *c)
>  {
> -	if (!selinux_mls_enabled)
> -		return;
> -
>  	ebitmap_destroy(&c->range.level[0].cat);
>  	ebitmap_destroy(&c->range.level[1].cat);
>  	mls_context_init(c);
> diff -pruN security-testing-2.6/security/selinux/ss/mls.c security-testing-2.6-new/security/selinux/ss/mls.c
> --- security-testing-2.6/security/selinux/ss/mls.c	2010-01-29 02:02:47.739046177 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.c	2010-02-01 22:15:48.062233721 +0100
> @@ -39,7 +39,7 @@ int mls_compute_context_len(struct conte
>  	struct ebitmap *e;
>  	struct ebitmap_node *node;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	len = 1; /* for the beginning ":" */
> @@ -93,7 +93,7 @@ void mls_sid_to_context(struct context *
>  	struct ebitmap *e;
>  	struct ebitmap_node *node;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	scontextp = *scontext;
> @@ -200,7 +200,7 @@ int mls_context_isvalid(struct policydb 
>  {
>  	struct user_datum *usrdatum;
>  
> -	if (!selinux_mls_enabled)
> +	if (!p->mls_enabled)
>  		return 1;
>  
>  	if (!mls_range_isvalid(p, &c->range))
> @@ -253,7 +253,7 @@ int mls_context_to_sid(struct policydb *
>  	struct cat_datum *catdatum, *rngdatum;
>  	int l, rc = -EINVAL;
>  
> -	if (!selinux_mls_enabled) {
> +	if (!pol->mls_enabled) {
>  		if (def_sid != SECSID_NULL && oldc)
>  			*scontext += strlen(*scontext)+1;
>  		return 0;
> @@ -387,7 +387,7 @@ int mls_from_string(char *str, struct co
>  	char *tmpstr, *freestr;
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return -EINVAL;
>  
>  	/* we need freestr because mls_context_to_sid will change
> @@ -407,7 +407,7 @@ int mls_from_string(char *str, struct co
>  /*
>   * Copies the MLS range `range' into `context'.
>   */
> -static inline int mls_range_set(struct context *context,
> +int mls_range_set(struct context *context,
>  				struct mls_range *range)
>  {
>  	int l, rc = 0;
> @@ -427,7 +427,7 @@ static inline int mls_range_set(struct c
>  int mls_setup_user_range(struct context *fromcon, struct user_datum *user,
>  			 struct context *usercon)
>  {
> -	if (selinux_mls_enabled) {
> +	if (policydb.mls_enabled) {
>  		struct mls_level *fromcon_sen = &(fromcon->range.level[0]);
>  		struct mls_level *fromcon_clr = &(fromcon->range.level[1]);
>  		struct mls_level *user_low = &(user->range.level[0]);
> @@ -477,7 +477,7 @@ int mls_convert_context(struct policydb 
>  	struct ebitmap_node *node;
>  	int l, i;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	for (l = 0; l < 2; l++) {
> @@ -516,7 +516,7 @@ int mls_compute_sid(struct context *scon
>  	struct range_trans rtr;
>  	struct mls_range *r;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	switch (specified) {
> @@ -559,7 +559,7 @@ int mls_compute_sid(struct context *scon
>  void mls_export_netlbl_lvl(struct context *context,
>  			   struct netlbl_lsm_secattr *secattr)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	secattr->attr.mls.lvl = context->range.level[0].sens - 1;
> @@ -579,7 +579,7 @@ void mls_export_netlbl_lvl(struct contex
>  void mls_import_netlbl_lvl(struct context *context,
>  			   struct netlbl_lsm_secattr *secattr)
>  {
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return;
>  
>  	context->range.level[0].sens = secattr->attr.mls.lvl + 1;
> @@ -601,7 +601,7 @@ int mls_export_netlbl_cat(struct context
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	rc = ebitmap_netlbl_export(&context->range.level[0].cat,
> @@ -629,7 +629,7 @@ int mls_import_netlbl_cat(struct context
>  {
>  	int rc;
>  
> -	if (!selinux_mls_enabled)
> +	if (!policydb.mls_enabled)
>  		return 0;
>  
>  	rc = ebitmap_netlbl_import(&context->range.level[0].cat,
> diff -pruN security-testing-2.6/security/selinux/ss/mls.h security-testing-2.6-new/security/selinux/ss/mls.h
> --- security-testing-2.6/security/selinux/ss/mls.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls.h	2010-02-01 23:17:31.025223083 +0100
> @@ -39,6 +39,8 @@ int mls_context_to_sid(struct policydb *
>  
>  int mls_from_string(char *str, struct context *context, gfp_t gfp_mask);
>  
> +int mls_range_set(struct context *context, struct mls_range *range);
> +
>  int mls_convert_context(struct policydb *oldp,
>  			struct policydb *newp,
>  			struct context *context);
> diff -pruN security-testing-2.6/security/selinux/ss/mls_types.h security-testing-2.6-new/security/selinux/ss/mls_types.h
> --- security-testing-2.6/security/selinux/ss/mls_types.h	2010-01-29 01:06:42.168051431 +0100
> +++ security-testing-2.6-new/security/selinux/ss/mls_types.h	2010-02-02 21:49:54.108993602 +0100
> @@ -15,6 +15,7 @@
>  #define _SS_MLS_TYPES_H_
>  
>  #include "security.h"
> +#include "ebitmap.h"
>  
>  struct mls_level {
>  	u32 sens;		/* sensitivity */
> @@ -27,18 +28,12 @@ struct mls_range {
>  
>  static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2)
>  {
> -	if (!selinux_mls_enabled)
> -		return 1;
> -
>  	return ((l1->sens == l2->sens) &&
>  		ebitmap_cmp(&l1->cat, &l2->cat));
>  }
>  
>  static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2)
>  {
> -	if (!selinux_mls_enabled)
> -		return 1;
> -
>  	return ((l1->sens >= l2->sens) &&
>  		ebitmap_contains(&l1->cat, &l2->cat));
>  }
> diff -pruN security-testing-2.6/security/selinux/ss/policydb.c security-testing-2.6-new/security/selinux/ss/policydb.c
> --- security-testing-2.6/security/selinux/ss/policydb.c	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.c	2010-02-01 22:12:18.601226073 +0100
> @@ -52,8 +52,6 @@ static char *symtab_name[SYM_NUM] = {
>  };
>  #endif
>  
> -int selinux_mls_enabled;
> -
>  static unsigned int symtab_sizes[SYM_NUM] = {
>  	2,
>  	32,
> @@ -455,7 +453,7 @@ static int policydb_index_others(struct 
>  
>  	printk(KERN_DEBUG "SELinux:  %d users, %d roles, %d types, %d bools",
>  	       p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim, p->p_bools.nprim);
> -	if (selinux_mls_enabled)
> +	if (p->mls_enabled)
>  		printk(", %d sens, %d cats", p->p_levels.nprim,
>  		       p->p_cats.nprim);
>  	printk("\n");
> @@ -1717,14 +1715,12 @@ int policydb_read(struct policydb *p, vo
>  	int i, j, rc;
>  	__le32 buf[4];
>  	u32 nodebuf[8];
> -	u32 len, len2, config, nprim, nel, nel2;
> +	u32 len, len2, nprim, nel, nel2;
>  	char *policydb_str;
>  	struct policydb_compat_info *info;
>  	struct range_trans *rt;
>  	struct mls_range *r;
>  
> -	config = 0;
> -
>  	rc = policydb_init(p);
>  	if (rc)
>  		goto out;
> @@ -1772,7 +1768,7 @@ int policydb_read(struct policydb *p, vo
>  	kfree(policydb_str);
>  	policydb_str = NULL;
>  
> -	/* Read the version, config, and table sizes. */
> +	/* Read the version and table sizes. */
>  	rc = next_entry(buf, fp, sizeof(u32)*4);
>  	if (rc < 0)
>  		goto bad;
> @@ -1787,13 +1783,7 @@ int policydb_read(struct policydb *p, vo
>  	}
>  
>  	if ((le32_to_cpu(buf[1]) & POLICYDB_CONFIG_MLS)) {
> -		if (ss_initialized && !selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between non-MLS"
> -				" and MLS policies\n");
> -			goto bad;
> -		}
> -		selinux_mls_enabled = 1;
> -		config |= POLICYDB_CONFIG_MLS;
> +		p->mls_enabled = 1;
>  
>  		if (p->policyvers < POLICYDB_VERSION_MLS) {
>  			printk(KERN_ERR "SELinux: security policydb version %d "
> @@ -1801,12 +1791,6 @@ int policydb_read(struct policydb *p, vo
>  				p->policyvers);
>  			goto bad;
>  		}
> -	} else {
> -		if (ss_initialized && selinux_mls_enabled) {
> -			printk(KERN_ERR "SELinux: Cannot switch between MLS and"
> -				" non-MLS policies\n");
> -			goto bad;
> -		}
>  	}
>  	p->reject_unknown = !!(le32_to_cpu(buf[1]) & REJECT_UNKNOWN);
>  	p->allow_unknown = !!(le32_to_cpu(buf[1]) & ALLOW_UNKNOWN);
> diff -pruN security-testing-2.6/security/selinux/ss/policydb.h security-testing-2.6-new/security/selinux/ss/policydb.h
> --- security-testing-2.6/security/selinux/ss/policydb.h	2010-01-29 02:02:47.740046077 +0100
> +++ security-testing-2.6-new/security/selinux/ss/policydb.h	2010-02-01 20:47:08.352232380 +0100
> @@ -27,6 +27,8 @@
>  #include "symtab.h"
>  #include "avtab.h"
>  #include "sidtab.h"
> +#include "ebitmap.h"
> +#include "mls_types.h"
>  #include "context.h"
>  #include "constraint.h"
>  
> @@ -185,6 +187,8 @@ struct genfs {
>  
>  /* The policy database */
>  struct policydb {
> +	int mls_enabled;
> +
>  	/* symbol tables */
>  	struct symtab symtab[SYM_NUM];
>  #define p_commons symtab[SYM_COMMONS]
> diff -pruN security-testing-2.6/security/selinux/ss/services.c security-testing-2.6-new/security/selinux/ss/services.c
> --- security-testing-2.6/security/selinux/ss/services.c	2010-01-29 02:02:47.742042805 +0100
> +++ security-testing-2.6-new/security/selinux/ss/services.c	2010-02-02 23:48:07.637994777 +0100
> @@ -26,6 +26,10 @@
>   *
>   *  Added support for bounds domain and audit messaged on masked permissions
>   *
> + * Updated: Guido Trentalancia <guido@xxxxxxxxxxxxxxxx>
> + *
> + *  Added support for runtime switching of the policy type
> + *
>   * Copyright (C) 2008, 2009 NEC Corporation
>   * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
>   * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc.
> @@ -232,6 +236,10 @@ static void map_decision(u16 tclass, str
>  	}
>  }
>  
> +int security_mls_enabled(void)
> +{
> +	return policydb.mls_enabled;
> +}
>  
>  /*
>   * Return the boolean value of a constraint expression
> @@ -1547,6 +1555,8 @@ static int convert_context(u32 key,
>  {
>  	struct convert_context_args *args;
>  	struct context oldc;
> +	struct ocontext *oc;
> +	struct mls_range *range;
>  	struct role_datum *role;
>  	struct type_datum *typdatum;
>  	struct user_datum *usrdatum;
> @@ -1614,9 +1624,39 @@ static int convert_context(u32 key,
>  		goto bad;
>  	c->type = typdatum->value;
>  
> -	rc = mls_convert_context(args->oldp, args->newp, c);
> -	if (rc)
> -		goto bad;
> +	/* Convert the MLS fields if dealing with MLS policies */
> +	if (args->oldp->mls_enabled && args->newp->mls_enabled) {
> +		rc = mls_convert_context(args->oldp, args->newp, c);
> +		if (rc)
> +			goto bad;
> +	} else if (args->oldp->mls_enabled && !args->newp->mls_enabled) {
> +		/*
> +		 * Switching between MLS and non-MLS policy:
> +		 * free any storage used by the MLS fields in the
> +		 * context for all existing entries in the sidtab.
> +		 */
> +		mls_context_destroy(c);
> +	} else if (!args->oldp->mls_enabled && args->newp->mls_enabled) {
> +		/*
> +		 * Switching between non-MLS and MLS policy:
> +		 * ensure that the MLS fields of the context for all
> +		 * existing entries in the sidtab are filled in with a
> +		 * suitable default value, likely taken from one of the
> +		 * initial SIDs.
> +		 */
> +		oc = args->newp->ocontexts[OCON_ISID];
> +		while (oc && oc->sid[0] != SECINITSID_UNLABELED)
> +			oc = oc->next;
> +		if (!oc) {
> +			printk(KERN_ERR "SELinux:  unable to look up"
> +				" the initial SIDs list\n");
> +			goto bad;
> +		}
> +		range = &oc->context[0].range;
> +		rc = mls_range_set(c, range);
> +		if (rc)
> +			goto bad;
> +	}
>  
>  	/* Check the validity of the new context. */
>  	if (!policydb_context_isvalid(args->newp, c)) {
> @@ -1712,6 +1752,12 @@ int security_load_policy(void *data, siz
>  	if (policydb_read(&newpolicydb, fp))
>  		return -EINVAL;
>  
> +	/* If switching between different policy types, log MLS status */
> +	if (policydb.mls_enabled && !newpolicydb.mls_enabled)
> +		printk(KERN_INFO "SELinux: Disabling MLS support...\n");
> +	else if (!policydb.mls_enabled && newpolicydb.mls_enabled)
> +		printk(KERN_INFO "SELinux: Enabling MLS support...\n");
> +
>  	if (sidtab_init(&newsidtab)) {
>  		policydb_destroy(&newpolicydb);
>  		return -ENOMEM;
> @@ -1741,8 +1787,12 @@ int security_load_policy(void *data, siz
>  	args.oldp = &policydb;
>  	args.newp = &newpolicydb;
>  	rc = sidtab_map(&newsidtab, convert_context, &args);
> -	if (rc)
> +	if (rc) {
> +		printk(KERN_ERR "SELinux:  unable to convert the internal"
> +			" representation of contexts in the new SID"
> +			" table\n");
>  		goto err;
> +	}
>  
>  	/* Save the old policydb and SID table to free later. */
>  	memcpy(&oldpolicydb, &policydb, sizeof policydb);
> @@ -2338,7 +2388,7 @@ int security_sid_mls_copy(u32 sid, u32 m
>  	u32 len;
>  	int rc = 0;
>  
> -	if (!ss_initialized || !selinux_mls_enabled) {
> +	if (!ss_initialized || !policydb.mls_enabled) {
>  		*new_sid = sid;
>  		goto out;
>  	}
> @@ -2439,7 +2489,7 @@ int security_net_peersid_resolve(u32 nlb
>  	/* we don't need to check ss_initialized here since the only way both
>  	 * nlbl_sid and xfrm_sid are not equal to SECSID_NULL would be if the
>  	 * security server was initialized and ss_initialized was true */
> -	if (!selinux_mls_enabled) {
> +	if (!policydb.mls_enabled) {
>  		*peer_sid = SECSID_NULL;
>  		return 0;
>  	}
> 
> 
> 
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
> the words "unsubscribe selinux" without quotes as the message.
-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
the words "unsubscribe selinux" without quotes as the message.

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

  Powered by Linux