Re: SELinux: Update policy version to support constraints info

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

 



Here is my go at another kernel patch. I've done most of what you asked
except I could not work out this  comment:

"Couldn't we avoid the need for passing down the policydb and checking
the version just by ensuring e->type_names gets initialized to NULL and
then the type_set_destroy() and kfree() calls degenerate to no-ops?  I
suppose this works, but it complicates the code a bit."

I've used the /sys/fs/selinux/policy facility to dump policy and loaded many
different policy types/versions and the kernel still lives.
Richard
 
----- Original Message -----
> From: Stephen Smalley <sds@xxxxxxxxxxxxx>
> To: Eric Paris <eparis@xxxxxxxxxx>
> Cc: selinux@xxxxxxxxxxxxx; Richard Haines <richard_c_haines@xxxxxxxxxxxxxx>; Paul Moore <paul@xxxxxxxxxxxxxx>
> Sent: Wednesday, 30 October 2013, 20:27
> Subject: Re: SELinux: Update policy version to support constraints info
> 
> On 10/21/2013 07:32 PM, Eric Paris wrote:
>>  From: Richard Haines <richard_c_haines@xxxxxxxxxxxxxx>
>>  Date: Tue, 18 Dec 2012 19:37:46 +0000
>> 
>>  Update the policy version (POLICYDB_VERSION_CONSTRAINT_NAMES) to allow
>>  holding of policy source info for constraints.
>> 
>>  Signed-off-by: Richard Haines <richard_c_haines@xxxxxxxxxxxxxx>
> 
> Can we get an updated version of this patch with my comments addressed
> so we can get this queued for mainline?  The libsepol/checkpolicy I just
> released includes the userspace support, so it would be nice if the
> kernel support could become available in the not-too-distant future.
> 
> 
>>  ---
>>   security/selinux/include/security.h |    3 +-
>>   security/selinux/ss/constraint.h    |    1 +
>>   security/selinux/ss/policydb.c      |  100 
> ++++++++++++++++++++++++++++++++---
>>   security/selinux/ss/policydb.h      |   11 ++++
>>   4 files changed, 107 insertions(+), 8 deletions(-)
>> 
>>  diff --git a/security/selinux/include/security.h 
> b/security/selinux/include/security.h
>>  index 927fc14..bdf0a56 100644
>>  --- a/security/selinux/include/security.h
>>  +++ b/security/selinux/include/security.h
>>  @@ -33,13 +33,14 @@
>>   #define POLICYDB_VERSION_ROLETRANS    26
>>   #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS    27
>>   #define POLICYDB_VERSION_DEFAULT_TYPE    28
>>  +#define POLICYDB_VERSION_CONSTRAINT_NAMES    29
>>   
>>   /* Range of policy versions we understand*/
>>   #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
>>   #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
>>   #define POLICYDB_VERSION_MAX    
> CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
>>   #else
>>  -#define POLICYDB_VERSION_MAX    POLICYDB_VERSION_DEFAULT_TYPE
>>  +#define POLICYDB_VERSION_MAX    POLICYDB_VERSION_CONSTRAINT_NAMES
>>   #endif
>>   
>>   /* Mask for just the mount related flags */
>>  diff --git a/security/selinux/ss/constraint.h 
> b/security/selinux/ss/constraint.h
>>  index 149dda7..3855ea8 100644
>>  --- a/security/selinux/ss/constraint.h
>>  +++ b/security/selinux/ss/constraint.h
>>  @@ -48,6 +48,7 @@ struct constraint_expr {
>>       u32 op;            /* operator */
>>   
>>       struct ebitmap names;    /* names */
>>  +    struct type_set_datum *type_names;
>>   
>>       struct constraint_expr *next;   /* next expression */
>>   };
>>  diff --git a/security/selinux/ss/policydb.c 
> b/security/selinux/ss/policydb.c
>>  index 9cd9b7c..f1b23df 100644
>>  --- a/security/selinux/ss/policydb.c
>>  +++ b/security/selinux/ss/policydb.c
>>  @@ -143,6 +143,11 @@ static struct policydb_compat_info policydb_compat[] = 
> {
>>           .sym_num    = SYM_NUM,
>>           .ocon_num    = OCON_NUM,
>>       },
>>  +    {
>>  +        .version    = POLICYDB_VERSION_CONSTRAINT_NAMES,
>>  +        .sym_num    = SYM_NUM,
>>  +        .ocon_num    = OCON_NUM,
>>  +    },
>>   };
>>   
>>   static struct policydb_compat_info *policydb_lookup_compat(int version)
>>  @@ -613,11 +618,20 @@ static int common_destroy(void *key, void *datum, 
> void *p)
>>       return 0;
>>   }
>>   
>>  -static int cls_destroy(void *key, void *datum, void *p)
>>  +static void type_set_destroy(struct type_set_datum * t)
>>  +{
>>  +    if (t != NULL) {
>>  +        ebitmap_destroy(&t->types);
>>  +        ebitmap_destroy(&t->negset);
>>  +    }
>>  +}
>>  +
>>  +static int cls_destroy(void *key, void *datum, void *datap)
>>   {
>>       struct class_datum *cladatum;
>>       struct constraint_node *constraint, *ctemp;
>>       struct constraint_expr *e, *etmp;
>>  +    struct policydb *p = datap;
>>   
>>       kfree(key);
>>       if (datum) {
>>  @@ -629,6 +643,10 @@ static int cls_destroy(void *key, void *datum, void 
> *p)
>>               e = constraint->expr;
>>               while (e) {
>>                   ebitmap_destroy(&e->names);
>>  +                if (p->policyvers >= 
> POLICYDB_VERSION_CONSTRAINT_NAMES) {
>>  +                    type_set_destroy(e->type_names);
>>  +                    kfree(e->type_names);
>>  +                }
>>                   etmp = e;
>>                   e = e->next;
>>                   kfree(etmp);
>>  @@ -643,6 +661,10 @@ static int cls_destroy(void *key, void *datum, void 
> *p)
>>               e = constraint->expr;
>>               while (e) {
>>                   ebitmap_destroy(&e->names);
>>  +                if (p->policyvers >= 
> POLICYDB_VERSION_CONSTRAINT_NAMES) {
>>  +                    type_set_destroy(e->type_names);
>>  +                    kfree(e->type_names);
>>  +                }
>>                   etmp = e;
>>                   e = e->next;
>>                   kfree(etmp);
>>  @@ -775,7 +797,7 @@ void policydb_destroy(struct policydb *p)
>>   
>>       for (i = 0; i < SYM_NUM; i++) {
>>           cond_resched();
>>  -        hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
>>  +        hashtab_map(p->symtab[i].table, destroy_f[i], p);
>>           hashtab_destroy(p->symtab[i].table);
>>       }
>>   
>>  @@ -1156,8 +1178,34 @@ bad:
>>       return rc;
>>   }
>>   
>>  -static int read_cons_helper(struct constraint_node **nodep, int ncons,
>>  -                int allowxtarget, void *fp)
>>  +static void type_set_init(struct type_set_datum * t)
>>  +{
>>  +    ebitmap_init(&t->types);
>>  +    ebitmap_init(&t->negset);
>>  +}
>>  +
>>  +static int type_set_read(struct type_set_datum * t, void *fp)
>>  +{
>>  +    __le32 buf[1];
>>  +    int rc;
>>  +
>>  +    if (ebitmap_read(&t->types, fp))
>>  +        return -EINVAL;
>>  +    if (ebitmap_read(&t->negset, fp))
>>  +        return -EINVAL;
>>  +
>>  +    rc = next_entry(buf, fp, sizeof(u32));
>>  +    if (rc < 0)
>>  +        return -EINVAL;
>>  +    t->flags = le32_to_cpu(buf[0]);
>>  +
>>  +    return 0;
>>  +}
>>  +
>>  +
>>  +static int read_cons_helper(struct policydb *p,
>>  +                struct constraint_node **nodep,
>>  +                int ncons, int allowxtarget, void *fp)
>>   {
>>       struct constraint_node *c, *lc;
>>       struct constraint_expr *e, *le;
>>  @@ -1196,6 +1244,7 @@ static int read_cons_helper(struct constraint_node 
> **nodep, int ncons,
>>               rc = next_entry(buf, fp, (sizeof(u32) * 3));
>>               if (rc)
>>                   return rc;
>>  +
>>               e->expr_type = le32_to_cpu(buf[0]);
>>               e->attr = le32_to_cpu(buf[1]);
>>               e->op = le32_to_cpu(buf[2]);
>>  @@ -1225,6 +1274,17 @@ static int read_cons_helper(struct constraint_node 
> **nodep, int ncons,
>>                   rc = ebitmap_read(&e->names, fp);
>>                   if (rc)
>>                       return rc;
>>  +
>>  +                if (p->policyvers >= 
> POLICYDB_VERSION_CONSTRAINT_NAMES) {
>>  +                    e->type_names = kzalloc(sizeof(*e->type_names), 
> GFP_KERNEL);
>>  +                    if (!e->type_names)
>>  +                        return -ENOMEM;
>>  +
>>  +                    type_set_init(e->type_names);
>>  +                    rc = type_set_read(e->type_names, fp);
>>  +                    if (rc)
>>  +                        return rc;
>>  +                }
>>                   break;
>>               default:
>>                   return -EINVAL;
>>  @@ -1233,6 +1293,7 @@ static int read_cons_helper(struct constraint_node 
> **nodep, int ncons,
>>           }
>>           if (depth != 0)
>>               return -EINVAL;
>>  +
>>           lc = c;
>>       }
>>   
>>  @@ -1301,7 +1362,7 @@ static int class_read(struct policydb *p, struct 
> hashtab *h, void *fp)
>>               goto bad;
>>       }
>>   
>>  -    rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp);
>>  +    rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp);
>>       if (rc)
>>           goto bad;
>>   
>>  @@ -1311,7 +1372,7 @@ static int class_read(struct policydb *p, struct 
> hashtab *h, void *fp)
>>           if (rc)
>>               goto bad;
>>           ncons = le32_to_cpu(buf[0]);
>>  -        rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, 
> fp);
>>  +        rc = read_cons_helper(p, &cladatum->validatetrans, ncons, 
> 1, fp);
>>           if (rc)
>>               goto bad;
>>       }
>>  @@ -1339,7 +1400,7 @@ static int class_read(struct policydb *p, struct 
> hashtab *h, void *fp)
>>   
>>       return 0;
>>   bad:
>>  -    cls_destroy(key, cladatum, NULL);
>>  +    cls_destroy(key, cladatum, p);
>>       return rc;
>>   }
>>   
>>  @@ -2750,6 +2811,24 @@ static int common_write(void *vkey, void *datum, 
> void *ptr)
>>       return 0;
>>   }
>>   
>>  +static int type_set_write(struct type_set_datum * t, void *fp)
>>  +{
>>  +    int rc;
>>  +    __le32 buf[1];
>>  +
>>  +    if (ebitmap_write(&t->types, fp))
>>  +        return -EINVAL;
>>  +    if (ebitmap_write(&t->negset, fp))
>>  +        return -EINVAL;
>>  +
>>  +    buf[0] = cpu_to_le32(t->flags);
>>  +    rc = put_entry(buf, sizeof(u32), 1, fp);
>>  +    if (rc)
>>  +        return -EINVAL;
>>  +
>>  +    return 0;
>>  +}
>>  +
>>   static int write_cons_helper(struct policydb *p, struct constraint_node 
> *node,
>>                    void *fp)
>>   {
>>  @@ -2781,6 +2860,13 @@ static int write_cons_helper(struct policydb *p, 
> struct constraint_node *node,
>>                   rc = ebitmap_write(&e->names, fp);
>>                   if (rc)
>>                       return rc;
>>  +
>>  +                if (p->policyvers >= 
> POLICYDB_VERSION_CONSTRAINT_NAMES) {
>>  +                    rc = type_set_write(e->type_names, fp);
>>  +                    if (rc)
>>  +                        return rc;
>>  +                }
>>  +
>>                   break;
>>               default:
>>                   break;
>>  diff --git a/security/selinux/ss/policydb.h 
> b/security/selinux/ss/policydb.h
>>  index da63747..c0bb6cb 100644
>>  --- a/security/selinux/ss/policydb.h
>>  +++ b/security/selinux/ss/policydb.h
>>  @@ -154,6 +154,17 @@ struct cond_bool_datum {
>>   struct cond_node;
>>   
>>   /*
>>  + * type set preserves data needed to determine constraint info from
>>  + * policy source. This is not used by the kernel policy but allows
>>  + * utilities such as audit2allow to determine constraint denials.
>>  + */
>>  +struct type_set_datum {
>>  +    struct ebitmap types;
>>  +    struct ebitmap negset;
>>  +    u32 flags;
>>  +};
>>  +
>>  +/*
>>    * The configuration data includes security contexts for
>>    * initial SIDs, unlabeled file systems, TCP and UDP port numbers,
>>    * network interfaces, and nodes.  This structure stores the
>> 
> 
> 
> --
> 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.
>  
From bba97b7724ca62d8db95ae9b74193161c8385e4b Mon Sep 17 00:00:00 2001
From: Richard Haines <richard_c_haines@xxxxxxxxxxxxxx>
Date: Sat, 26 Oct 2013 15:39:10 +0100
Subject: [PATCH] SELinux: Update policy version to support constraints info

Update the policy version (POLICYDB_VERSION_CONSTRAINT_NAMES) to allow
holding of policy source info for constraints.

Signed-off-by: Richard Haines <richard_c_haines@xxxxxxxxxxxxxx>
---
 security/selinux/include/security.h |  3 +-
 security/selinux/ss/constraint.h    |  1 +
 security/selinux/ss/policydb.c      | 95 ++++++++++++++++++++++++++++++++-----
 security/selinux/ss/policydb.h      | 11 +++++
 4 files changed, 98 insertions(+), 12 deletions(-)

diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 927fc14..bdf0a56 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -33,13 +33,14 @@
 #define POLICYDB_VERSION_ROLETRANS	26
 #define POLICYDB_VERSION_NEW_OBJECT_DEFAULTS	27
 #define POLICYDB_VERSION_DEFAULT_TYPE	28
+#define POLICYDB_VERSION_CONSTRAINT_NAMES	29
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX	CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_DEFAULT_TYPE
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_CONSTRAINT_NAMES
 #endif
 
 /* Mask for just the mount related flags */
diff --git a/security/selinux/ss/constraint.h b/security/selinux/ss/constraint.h
index 149dda7..96fd947 100644
--- a/security/selinux/ss/constraint.h
+++ b/security/selinux/ss/constraint.h
@@ -48,6 +48,7 @@ struct constraint_expr {
 	u32 op;			/* operator */
 
 	struct ebitmap names;	/* names */
+	struct type_set *type_names;
 
 	struct constraint_expr *next;   /* next expression */
 };
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c
index 9cd9b7c..3fcd75d 100644
--- a/security/selinux/ss/policydb.c
+++ b/security/selinux/ss/policydb.c
@@ -143,6 +143,11 @@ static struct policydb_compat_info policydb_compat[] = {
 		.sym_num	= SYM_NUM,
 		.ocon_num	= OCON_NUM,
 	},
+	{
+		.version	= POLICYDB_VERSION_CONSTRAINT_NAMES,
+		.sym_num	= SYM_NUM,
+		.ocon_num	= OCON_NUM,
+	},
 };
 
 static struct policydb_compat_info *policydb_lookup_compat(int version)
@@ -613,6 +618,19 @@ static int common_destroy(void *key, void *datum, void *p)
 	return 0;
 }
 
+static void constraint_expr_destroy(struct constraint_expr *expr)
+{
+	if (expr != NULL) {
+		ebitmap_destroy(&expr->names);
+		if (expr->type_names != NULL) {
+			ebitmap_destroy(&expr->type_names->types);
+			ebitmap_destroy(&expr->type_names->negset);
+			kfree(expr->type_names);
+		}
+		kfree(expr);
+	}
+}
+
 static int cls_destroy(void *key, void *datum, void *p)
 {
 	struct class_datum *cladatum;
@@ -628,10 +646,9 @@ static int cls_destroy(void *key, void *datum, void *p)
 		while (constraint) {
 			e = constraint->expr;
 			while (e) {
-				ebitmap_destroy(&e->names);
 				etmp = e;
 				e = e->next;
-				kfree(etmp);
+				constraint_expr_destroy(etmp);
 			}
 			ctemp = constraint;
 			constraint = constraint->next;
@@ -642,16 +659,14 @@ static int cls_destroy(void *key, void *datum, void *p)
 		while (constraint) {
 			e = constraint->expr;
 			while (e) {
-				ebitmap_destroy(&e->names);
 				etmp = e;
 				e = e->next;
-				kfree(etmp);
+				constraint_expr_destroy(etmp);
 			}
 			ctemp = constraint;
 			constraint = constraint->next;
 			kfree(ctemp);
 		}
-
 		kfree(cladatum->comkey);
 	}
 	kfree(datum);
@@ -775,7 +790,7 @@ void policydb_destroy(struct policydb *p)
 
 	for (i = 0; i < SYM_NUM; i++) {
 		cond_resched();
-		hashtab_map(p->symtab[i].table, destroy_f[i], NULL);
+		hashtab_map(p->symtab[i].table, destroy_f[i], p);
 		hashtab_destroy(p->symtab[i].table);
 	}
 
@@ -1156,8 +1171,34 @@ bad:
 	return rc;
 }
 
-static int read_cons_helper(struct constraint_node **nodep, int ncons,
-			    int allowxtarget, void *fp)
+static void type_set_init(struct type_set *t)
+{
+	ebitmap_init(&t->types);
+	ebitmap_init(&t->negset);
+}
+
+static int type_set_read(struct type_set *t, void *fp)
+{
+	__le32 buf[1];
+	int rc;
+
+	if (ebitmap_read(&t->types, fp))
+		return -EINVAL;
+	if (ebitmap_read(&t->negset, fp))
+		return -EINVAL;
+
+	rc = next_entry(buf, fp, sizeof(u32));
+	if (rc < 0)
+		return -EINVAL;
+	t->flags = le32_to_cpu(buf[0]);
+
+	return 0;
+}
+
+
+static int read_cons_helper(struct policydb *p,
+				struct constraint_node **nodep,
+				int ncons, int allowxtarget, void *fp)
 {
 	struct constraint_node *c, *lc;
 	struct constraint_expr *e, *le;
@@ -1225,6 +1266,15 @@ static int read_cons_helper(struct constraint_node **nodep, int ncons,
 				rc = ebitmap_read(&e->names, fp);
 				if (rc)
 					return rc;
+				if (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) {
+					e->type_names = kzalloc(sizeof(*e->type_names), GFP_KERNEL);
+					if (!e->type_names)
+						return -ENOMEM;
+					type_set_init(e->type_names);
+					rc = type_set_read(e->type_names, fp);
+					if (rc)
+						return rc;
+				}
 				break;
 			default:
 				return -EINVAL;
@@ -1301,7 +1351,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
 			goto bad;
 	}
 
-	rc = read_cons_helper(&cladatum->constraints, ncons, 0, fp);
+	rc = read_cons_helper(p, &cladatum->constraints, ncons, 0, fp);
 	if (rc)
 		goto bad;
 
@@ -1311,7 +1361,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
 		if (rc)
 			goto bad;
 		ncons = le32_to_cpu(buf[0]);
-		rc = read_cons_helper(&cladatum->validatetrans, ncons, 1, fp);
+		rc = read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp);
 		if (rc)
 			goto bad;
 	}
@@ -1339,7 +1389,7 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
 
 	return 0;
 bad:
-	cls_destroy(key, cladatum, NULL);
+	cls_destroy(key, cladatum, p);
 	return rc;
 }
 
@@ -2750,6 +2800,24 @@ static int common_write(void *vkey, void *datum, void *ptr)
 	return 0;
 }
 
+static int type_set_write(struct type_set *t, void *fp)
+{
+	int rc;
+	__le32 buf[1];
+
+	if (ebitmap_write(&t->types, fp))
+		return -EINVAL;
+	if (ebitmap_write(&t->negset, fp))
+		return -EINVAL;
+
+	buf[0] = cpu_to_le32(t->flags);
+	rc = put_entry(buf, sizeof(u32), 1, fp);
+	if (rc)
+		return -EINVAL;
+
+	return 0;
+}
+
 static int write_cons_helper(struct policydb *p, struct constraint_node *node,
 			     void *fp)
 {
@@ -2781,6 +2849,11 @@ static int write_cons_helper(struct policydb *p, struct constraint_node *node,
 				rc = ebitmap_write(&e->names, fp);
 				if (rc)
 					return rc;
+				if (p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) {
+					rc = type_set_write(e->type_names, fp);
+					if (rc)
+						return rc;
+				}
 				break;
 			default:
 				break;
diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h
index da63747..725d594 100644
--- a/security/selinux/ss/policydb.h
+++ b/security/selinux/ss/policydb.h
@@ -154,6 +154,17 @@ struct cond_bool_datum {
 struct cond_node;
 
 /*
+ * type set preserves data needed to determine constraint info from
+ * policy source. This is not used by the kernel policy but allows
+ * utilities such as audit2allow to determine constraint denials.
+ */
+struct type_set {
+	struct ebitmap types;
+	struct ebitmap negset;
+	u32 flags;
+};
+
+/*
  * The configuration data includes security contexts for
  * initial SIDs, unlabeled file systems, TCP and UDP port numbers,
  * network interfaces, and nodes.  This structure stores the
-- 
1.8.3.1


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

  Powered by Linux