[PATCH 3/3] Thread/Child-Domain Assignment

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

 



[3/3] thread-context-libsepol.1.patch
  This patch add support of new policy version of POLICYDB_VERSION_HIERARCHY.
  It keeps child-parent relationship between two types, and used to make
  a decision whether required dynamic type transition within multithreaded
  process can be allowed, or not, in the kernel space.

Signed-off-by: KaiGai Kohei <kaigai@xxxxxxxxxxxxx>
----
 include/sepol/policydb/policydb.h |    7 +++-
 src/expand.c                      |   33 +++++++++++++++++++++
 src/hierarchy.c                   |   50 ++++++++++++++++++++++++++------
 src/link.c                        |   33 +++++++++++++++++++++
 src/policydb.c                    |   59 +++++++++++++++++++++++++++++---------
 src/write.c                       |    9 +++++
 6 files changed, 166 insertions(+), 25 deletions(-)

Index: libsepol/include/sepol/policydb/policydb.h
===================================================================
--- libsepol/include/sepol/policydb/policydb.h	(revision 2928)
+++ libsepol/include/sepol/policydb/policydb.h	(working copy)
@@ -145,6 +145,7 @@
 	ebitmap_t types;	/* types with this attribute */
 #define TYPE_FLAGS_PERMISSIVE	0x01
 	uint32_t flags;
+	uint32_t parent;	/* parent type in hierarchical representation */
 } type_datum_t;

 /* User attributes */
@@ -595,10 +596,11 @@
 #define POLICYDB_VERSION_RANGETRANS	21
 #define POLICYDB_VERSION_POLCAP		22
 #define POLICYDB_VERSION_PERMISSIVE	23
+#define POLICYDB_VERSION_HIERARCHY	24

 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_HIERARCHY

 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE	   4
@@ -608,9 +610,10 @@
 #define MOD_POLICYDB_VERSION_MLS_USERS	   6
 #define MOD_POLICYDB_VERSION_POLCAP	   7
 #define MOD_POLICYDB_VERSION_PERMISSIVE	   8
+#define MOD_POLICYDB_VERSION_HIERARCHY	   9

 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_PERMISSIVE
+#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_HIERARCHY

 #define POLICYDB_CONFIG_MLS    1

Index: libsepol/src/policydb.c
===================================================================
--- libsepol/src/policydb.c	(revision 2928)
+++ libsepol/src/policydb.c	(working copy)
@@ -111,6 +111,12 @@
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
+	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_HIERARCHY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = OCON_NODE6 + 1,
+	 },
+	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM,
@@ -141,6 +147,12 @@
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
+	 .type = POLICY_BASE,
+	 .version = MOD_POLICYDB_VERSION_HIERARCHY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = OCON_NODE6 + 1,
+	},
+	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM,
@@ -170,6 +182,12 @@
 	 .sym_num = SYM_NUM,
 	 .ocon_num = 0
 	 },
+	{
+	 .type = POLICY_MOD,
+	 .version = MOD_POLICYDB_VERSION_HIERARCHY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = 0
+	},
 };

 #if 0
@@ -1918,30 +1936,45 @@
 	type_datum_t *typdatum;
 	uint32_t buf[5];
 	size_t len;
-	int rc, to_read;
+	int rc, items, to_read;

 	typdatum = calloc(1, sizeof(type_datum_t));
 	if (!typdatum)
 		return -1;

-	if (p->policy_type == POLICY_KERN)
-		to_read = 3;
-	else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
-		to_read = 5;
-	else
-		to_read = 4;
+	if (p->policy_type == POLICY_KERN) {
+		if (p->policyvers >= POLICYDB_VERSION_HIERARCHY)
+			to_read = 4;
+		else
+			to_read = 3;
+	} else {
+		if (p->policyvers >= MOD_POLICYDB_VERSION_HIERARCHY)
+			to_read = 6;
+		else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
+			to_read = 5;
+		else
+			to_read = 4;
+	}

 	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
 	if (rc < 0)
 		goto bad;

-	len = le32_to_cpu(buf[0]);
-	typdatum->s.value = le32_to_cpu(buf[1]);
-	typdatum->primary = le32_to_cpu(buf[2]);
-	if (p->policy_type != POLICY_KERN) {
-		typdatum->flavor = le32_to_cpu(buf[3]);
+	items = 0;
+	len = le32_to_cpu(buf[items++]);
+	typdatum->s.value = le32_to_cpu(buf[items++]);
+	typdatum->primary = le32_to_cpu(buf[items++]);
+
+	if (p->policy_type == POLICY_KERN) {
+		if (p->policyvers >= POLICYDB_VERSION_HIERARCHY)
+			typdatum->parent = le32_to_cpu(buf[items++]);
+	} else {
+		if (p->policyvers >= MOD_POLICYDB_VERSION_HIERARCHY)
+			typdatum->parent = le32_to_cpu(buf[items++]);
+
+		typdatum->flavor = le32_to_cpu(buf[items++]);
 		if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
-			typdatum->flags = le32_to_cpu(buf[4]);
+			typdatum->flags = le32_to_cpu(buf[items++]);
 		if (ebitmap_read(&typdatum->types, fp))
 			goto bad;
 	}
Index: libsepol/src/hierarchy.c
===================================================================
--- libsepol/src/hierarchy.c	(revision 2928)
+++ libsepol/src/hierarchy.c	(working copy)
@@ -47,7 +47,7 @@
  *
  * Caller must free parent after use.
  */
-static int find_parent(char *type, char **parent)
+static int find_parent_namebased(char *type, char **parent)
 {
 	char *tmp;
 	int len;
@@ -73,6 +73,34 @@
 	return 0;
 }

+static int find_parent(policydb_t *p, char *child, char **parent)
+{
+	type_datum_t *child_type;
+
+	/* legacy name based hierarchy relationship */
+	if ((p->policy_type == POLICY_KERN
+	     && p->policyvers < POLICYDB_VERSION_HIERARCHY) ||
+	    (p->policy_type != POLICY_KERN
+	     && p->policyvers < MOD_POLICYDB_VERSION_HIERARCHY))
+		return find_parent_namebased(child, parent);
+
+	child_type = hashtab_search(p->p_types.table, child);
+	if (!child_type)
+		return -1;
+
+	/* no hierarchy relationship */
+	if (!child_type->parent) {
+		*parent = NULL;
+		return 0;
+	}
+
+	*parent = strdup(p->p_type_val_to_name[child_type->parent - 1]);
+	if (!(*parent))
+		return -1;
+
+	return 0;
+}
+
 /* This function verifies that the type passed in either has a parent or is in the
  * root of the namespace, 0 on success, 1 on orphan and -1 on error
  */
@@ -93,7 +121,7 @@
 		return 0;
 	}

-	if (find_parent(key, &parent))
+	if (find_parent(a->p, key, &parent))
 		return -1;

 	if (!parent) {
@@ -126,7 +154,7 @@
 static int check_avtab_hierarchy_callback(avtab_key_t * k, avtab_datum_t * d,
 					  void *args)
 {
-	char *parent;
+	char *type_name, *parent;
 	avtab_key_t key;
 	avtab_datum_t *avdatump;
 	hierarchy_args_t *a;
@@ -139,7 +167,8 @@
 	}

 	a = (hierarchy_args_t *) args;
-	if (find_parent(a->p->p_type_val_to_name[k->source_type - 1], &parent))
+	type_name = a->p->p_type_val_to_name[k->source_type - 1];
+	if (find_parent(a->p, type_name, &parent))
 		return -1;

 	/* search for parent first */
@@ -178,7 +207,8 @@
 	}

 	/* next we try type 1 and type 2's parent */
-	if (find_parent(a->p->p_type_val_to_name[k->target_type - 1], &parent))
+	type_name = a->p->p_type_val_to_name[k->target_type - 1];
+	if (find_parent(a->p, type_name, &parent))
 		return -1;

 	if (parent) {
@@ -317,14 +347,15 @@
 					 __attribute__ ((unused)),
 					 hashtab_datum_t d, void *args)
 {
-	char *parent;
+	char *role_name, *parent;
 	hierarchy_args_t *a;
 	role_datum_t *r, *rp;

 	a = (hierarchy_args_t *) args;
 	r = (role_datum_t *) d;

-	if (find_parent(a->p->p_role_val_to_name[r->s.value - 1], &parent))
+	role_name = a->p->p_role_val_to_name[r->s.value - 1];
+	if (find_parent_namebased(role_name, &parent))
 		return -1;

 	if (!parent) {
@@ -362,14 +393,15 @@
 					 __attribute__ ((unused)),
 					 hashtab_datum_t d, void *args)
 {
-	char *parent;
+	char *user_name, *parent;
 	hierarchy_args_t *a;
 	user_datum_t *u, *up;

 	a = (hierarchy_args_t *) args;
 	u = (user_datum_t *) d;

-	if (find_parent(a->p->p_user_val_to_name[u->s.value - 1], &parent))
+	user_name = a->p->p_user_val_to_name[u->s.value - 1];
+	if (find_parent_namebased(user_name, &parent))
 		return -1;

 	if (!parent) {
Index: libsepol/src/expand.c
===================================================================
--- libsepol/src/expand.c	(revision 2928)
+++ libsepol/src/expand.c	(working copy)
@@ -538,6 +538,35 @@
 	return 0;
 }

+static int hierarchy_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
+{
+	expand_state_t *state = (expand_state_t *) data;
+	type_datum_t *type = (type_datum_t *) datum;
+	type_datum_t *target;
+	uint32_t parent_val;
+
+	if (!type->parent)
+		return 0;
+
+	if (!is_id_enabled((char *)key, state->base, SYM_TYPES))
+		return 0;
+
+	parent_val = state->typemap[type->parent - 1];
+
+	target = hashtab_search(state->out->p_types.table, (char *)key);
+	if (!target) {
+		ERR(state->handle, "Type lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (target->parent > 0 && target->parent != parent_val) {
+		ERR(state->handle, "Inconsistent hierarchy for %s", (char *)key);
+		return -1;
+	}
+	target->parent = parent_val;
+
+	return 0;
+}
+
 static int role_remap_dominates(hashtab_key_t key __attribute__ ((unused)), hashtab_datum_t datum, void *data)
 {
 	ebitmap_t mapped_roles;
@@ -2393,6 +2422,10 @@
 		goto cleanup;
 	}

+	/* copy hierarchy */
+	if (hashtab_map(state.base->p_types.table, hierarchy_type_callback, &state))
+		goto cleanup;
+
 	/* copy aliases */
 	if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state))
 		goto cleanup;
Index: libsepol/src/write.c
===================================================================
--- libsepol/src/write.c	(revision 2928)
+++ libsepol/src/write.c	(working copy)
@@ -957,7 +957,14 @@
 	buf[items++] = cpu_to_le32(len);
 	buf[items++] = cpu_to_le32(typdatum->s.value);
 	buf[items++] = cpu_to_le32(typdatum->primary);
-	if (p->policy_type != POLICY_KERN) {
+
+	if (p->policy_type == POLICY_KERN) {
+		if (p->policyvers >= POLICYDB_VERSION_HIERARCHY)
+			buf[items++] = cpu_to_le32(typdatum->parent);
+	} else {
+		if (p->policyvers >= MOD_POLICYDB_VERSION_HIERARCHY)
+			buf[items++] = cpu_to_le32(typdatum->parent);
+
 		buf[items++] = cpu_to_le32(typdatum->flavor);
 		if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
 			buf[items++] = cpu_to_le32(typdatum->flags);
Index: libsepol/src/link.c
===================================================================
--- libsepol/src/link.c	(revision 2928)
+++ libsepol/src/link.c	(working copy)
@@ -770,6 +770,35 @@
 	return -1;
 }

+static int hierarchy_type_callback(hashtab_key_t key, hashtab_datum_t datum, void *data)
+{
+	link_state_t *state = (link_state_t *) data;
+	type_datum_t *type = (type_datum_t *) datum;
+	type_datum_t *target;
+	uint32_t parent_val;
+
+	if (!type->parent)
+		return 0;
+
+	parent_val = state->cur->map[SYM_TYPES][type->parent - 1];
+
+	target = hashtab_search(state->base->p_types.table, key);
+	if (!target) {
+		ERR(state->handle,
+		    "Type lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (target->parent > 0 && target->parent != parent_val) {
+		ERR(state->handle,
+		    "Inconsistent domain hierarchy for %s", (char *)key);
+		return -1;
+	}
+	target->parent = parent_val;
+
+	return 0;
+}
+
+
 /*********** callbacks that fix bitmaps ***********/

 static int type_set_convert(type_set_t * types, type_set_t * dst,
@@ -1362,6 +1391,10 @@
 		}
 	}

+	if (hashtab_map(src_symtab[SYM_TYPES].table,
+			hierarchy_type_callback, state))
+		return -1;
+
 	if (hashtab_map
 	    (src_symtab[SYM_TYPES].table, alias_copy_callback, state)) {
 		return -1;

-- 
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@xxxxxxxxxxxxx>

--
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