[PATCH 07/10 v3] libsepol/cil: Track number of classes and number of types and attributes.

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

 



These values are stored in the CIL db so they can be used to
determine how much memory is needed for mapping libsepol values
to CIL data.

Signed-off-by: James Carter <jwcart2@xxxxxxxxxxxxx>
---
 libsepol/cil/src/cil.c          |  3 +-
 libsepol/cil/src/cil_binary.c   | 73 +++++++++++++++++++++++++++++++++--------
 libsepol/cil/src/cil_binary.h   |  4 +--
 libsepol/cil/src/cil_internal.h |  2 ++
 libsepol/cil/src/cil_post.c     | 26 +++++++++++----
 5 files changed, 85 insertions(+), 23 deletions(-)

diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 5c53bf3..be070de 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -257,7 +257,8 @@ void cil_db_init(struct cil_db **db)
 	cil_type_init(&(*db)->selftype);
 	(*db)->selftype->datum.name = CIL_KEY_SELF;
 	(*db)->selftype->datum.fqn = CIL_KEY_SELF;
-
+	(*db)->num_types_and_attrs = 0;
+	(*db)->num_classes = 0;
 	(*db)->num_types = 0;
 	(*db)->num_roles = 0;
 	(*db)->num_cats = 0;
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
index fd5983a..066184a 100644
--- a/libsepol/cil/src/cil_binary.c
+++ b/libsepol/cil/src/cil_binary.c
@@ -55,6 +55,7 @@
 #define FILENAME_TRANS_TABLE_SIZE 1 << 16
 #define RANGE_TRANS_TABLE_SIZE 1 << 13
 #define ROLE_TRANS_TABLE_SIZE 1 << 10
+#define PERMS_PER_CLASS 32
 
 struct cil_args_binary {
 	const struct cil_db *db;
@@ -64,6 +65,7 @@ struct cil_args_binary {
 	hashtab_t filename_trans_table;
 	hashtab_t range_trans_table;
 	hashtab_t role_trans_table;
+	void **type_value_to_cil;
 };
 
 struct cil_args_booleanif {
@@ -303,7 +305,7 @@ exit:
 	return rc;
 }
 
-int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
+int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 	struct cil_list_item *curr_class;
@@ -312,8 +314,8 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
 		struct cil_class *cil_class = curr_class->data;
 		uint32_t value = 0;
 		char *key = NULL;
-		struct cil_tree_node *node = cil_class->datum.nodes->head->data;
-		struct cil_tree_node *cil_perm = node->cl_head;
+		int class_index;
+		struct cil_tree_node *curr;
 		common_datum_t *sepol_common = NULL;
 		class_datum_t *sepol_class = cil_malloc(sizeof(*sepol_class));
 		memset(sepol_class, 0, sizeof(class_datum_t));
@@ -326,6 +328,8 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
 			goto exit;
 		}
 		sepol_class->s.value = value;
+		class_index = value;
+		class_value_to_cil[class_index] = cil_class;
 
 		rc = symtab_init(&sepol_class->permissions, PERM_SYMTAB_SIZE);
 		if (rc != SEPOL_OK) {
@@ -333,6 +337,7 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
 		}
 
 		if (cil_class->common != NULL) {
+			int i;
 			struct cil_class *cil_common = cil_class->common;
 
 			key = cil_class->common->datum.fqn;
@@ -346,14 +351,19 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
 			sepol_class->comdatum = sepol_common;
 			sepol_class->comkey = cil_strdup(key);
 			sepol_class->permissions.nprim += sepol_common->permissions.nprim;
+
+			for (curr = NODE(cil_class->common)->cl_head, i = 1; curr; curr = curr->next, i++) {
+				struct cil_perm *cil_perm = curr->data;
+				perm_value_to_cil[class_index][i] = cil_perm;
+			}
 		}
 
-		while (cil_perm != NULL) {
-			struct cil_perm *curr_perm = cil_perm->data;
+		for (curr = NODE(cil_class)->cl_head; curr; curr = curr->next) {
+			struct cil_perm *cil_perm = curr->data;
 			perm_datum_t *sepol_perm = cil_malloc(sizeof(*sepol_perm));
 			memset(sepol_perm, 0, sizeof(perm_datum_t));
 
-			key = cil_strdup(curr_perm->datum.fqn);
+			key = cil_strdup(cil_perm->datum.fqn);
 			rc = hashtab_insert(sepol_class->permissions.table, key, sepol_perm);
 			if (rc != SEPOL_OK) {
 				free(sepol_perm);
@@ -362,7 +372,7 @@ int cil_classorder_to_policydb(policydb_t *pdb, const struct cil_db *db)
 			}
 			sepol_perm->s.value = sepol_class->permissions.nprim + 1;
 			sepol_class->permissions.nprim++;
-			cil_perm = cil_perm->next;
+			perm_value_to_cil[class_index][sepol_perm->s.value] = cil_perm;
 		}
 	}
 
@@ -463,7 +473,7 @@ exit:
 	return rc;
 }
 
-int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
+int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 	uint32_t value = 0;
@@ -481,6 +491,8 @@ int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type)
 	sepol_type->s.value = value;
 	sepol_type->primary = 1;
 
+	type_value_to_cil[value] = cil_type;
+
 	return SEPOL_OK;
 
 exit:
@@ -564,7 +576,7 @@ exit:
 
 }
 
-int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr)
+int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 	uint32_t value = 0;
@@ -588,6 +600,8 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil
 	sepol_attr->s.value = value;
 	sepol_attr->primary = 1;
 
+	type_value_to_cil[value] = cil_attr;
+
 	return SEPOL_OK;
 
 exit:
@@ -2998,12 +3012,15 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
 	hashtab_t filename_trans_table;
 	hashtab_t range_trans_table;
 	hashtab_t role_trans_table;
+	void **type_value_to_cil;
+
 	db = args->db;
 	pdb = args->pdb;
 	pass = args->pass;
 	filename_trans_table = args->filename_trans_table;
 	range_trans_table = args->range_trans_table;
 	role_trans_table = args->role_trans_table;
+	type_value_to_cil = args->type_value_to_cil;
 
 	if (node->flavor >= CIL_MIN_DECLARATIVE) {
 		if (node != DATUM(node->data)->nodes->head->data) {
@@ -3018,10 +3035,10 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
 			rc = cil_role_to_policydb(pdb, node->data);
 			break;
 		case CIL_TYPE:
-			rc = cil_type_to_policydb(pdb, node->data);
+			rc = cil_type_to_policydb(pdb, node->data, type_value_to_cil);
 			break;
 		case CIL_TYPEATTRIBUTE:
-			rc = cil_typeattribute_to_policydb(pdb, node->data);
+			rc = cil_typeattribute_to_policydb(pdb, node->data, type_value_to_cil);
 			break;
 		case CIL_POLICYCAP:
 			rc = cil_policycap_to_policydb(pdb, node->data);
@@ -3483,7 +3500,7 @@ exit:
 }
 
 
-int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
+int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
 {
 	int rc = SEPOL_ERR;
 
@@ -3493,7 +3510,7 @@ int __cil_policydb_init(policydb_t *pdb, const struct cil_db *db)
 	pdb->handle_unknown = db->handle_unknown;
 	pdb->mls = db->mls;
 
-	rc = cil_classorder_to_policydb(pdb, db);
+	rc = cil_classorder_to_policydb(pdb, db, class_value_to_cil, perm_value_to_cil);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3898,6 +3915,9 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
 	hashtab_t filename_trans_table = NULL;
 	hashtab_t range_trans_table = NULL;
 	hashtab_t role_trans_table = NULL;
+	void **type_value_to_cil = NULL;
+	struct cil_class **class_value_to_cil = NULL;
+	struct cil_perm ***perm_value_to_cil = NULL;
 
 	if (db == NULL || policydb == NULL) {
 		if (db == NULL) {
@@ -3908,7 +3928,23 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
 		return SEPOL_ERR;
 	}
 
-	rc = __cil_policydb_init(pdb, db);
+	/* libsepol values start at 1. Just allocate extra memory rather than
+	 * subtract 1 from the sepol value.
+	 */
+	type_value_to_cil = calloc(db->num_types_and_attrs+1, sizeof(*type_value_to_cil));
+	if (!type_value_to_cil) goto exit;
+
+	class_value_to_cil = calloc(db->num_classes+1, sizeof(*class_value_to_cil));
+	if (!class_value_to_cil) goto exit;
+
+	perm_value_to_cil = calloc(db->num_classes+1, sizeof(*perm_value_to_cil));
+	if (!perm_value_to_cil) goto exit;
+	for (i=1; i < db->num_classes+1; i++) {
+		perm_value_to_cil[i] = calloc(PERMS_PER_CLASS+1, sizeof(*perm_value_to_cil[i]));
+		if (!perm_value_to_cil[i]) goto exit;
+	}
+
+	rc = __cil_policydb_init(pdb, db, class_value_to_cil, perm_value_to_cil);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_ERR,"Problem in policydb_init\n");
 		goto exit;
@@ -3940,6 +3976,8 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
 	extra_args.filename_trans_table = filename_trans_table;
 	extra_args.range_trans_table = range_trans_table;
 	extra_args.role_trans_table = role_trans_table;
+	extra_args.type_value_to_cil = type_value_to_cil;
+
 	for (i = 1; i <= 3; i++) {
 		extra_args.pass = i;
 
@@ -3992,6 +4030,13 @@ exit:
 	hashtab_destroy(filename_trans_table);
 	hashtab_destroy(range_trans_table);
 	hashtab_destroy(role_trans_table);
+	free(type_value_to_cil);
+	free(class_value_to_cil);
+	/* Range is because libsepol values start at 1. */
+	for (i=1; i < db->num_classes+1; i++) {
+		free(perm_value_to_cil[i]);
+	}
+	free(perm_value_to_cil);
 	cil_list_destroy(&neverallows, CIL_FALSE);
 
 	return rc;
diff --git a/libsepol/cil/src/cil_binary.h b/libsepol/cil/src/cil_binary.h
index 72c0f95..33b43f9 100644
--- a/libsepol/cil/src/cil_binary.h
+++ b/libsepol/cil/src/cil_binary.h
@@ -112,7 +112,7 @@ int cil_roletype_to_policydb(policydb_t *pdb, const struct cil_db *db, struct ci
  *
  * @return SEPOL_OK upon success or an error otherwise.
  */
-int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type);
+int cil_type_to_policydb(policydb_t *pdb, struct cil_type *cil_type, void *type_value_to_cil[]);
 
 /**
  * Insert cil typealias structure into sepol policydb.
@@ -144,7 +144,7 @@ int cil_typepermissive_to_policydb(policydb_t *pdb, struct cil_typepermissive *c
  *
  * @return SEPOL_OK upon success or an error otherwise.
  */
-int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr);
+int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil_attr, void *type_value_to_cil[]);
 
 /**
  * Insert cil attribute structure into sepol type->attribute bitmap.
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index a43d111..abe52de 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -279,6 +279,8 @@ struct cil_db {
 	struct cil_list *userprefixes;
 	struct cil_list *selinuxusers;
 	struct cil_list *names;
+	int num_types_and_attrs;
+	int num_classes;
 	int num_cats;
 	int num_types;
 	int num_roles;
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index f91727f..e69b5a4 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -339,23 +339,37 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini
 	case CIL_MACRO:
 		*finished = CIL_TREE_SKIP_HEAD;
 		break;
+	case CIL_CLASS: {
+		struct cil_class *class = node->data;
+		if (class->datum.nodes->head->data == node) {
+			// Multiple nodes can point to the same datum. Only count once.
+			db->num_classes++;
+		}
+		break;
+	}
 	case CIL_TYPE: {
 		struct cil_type *type = node->data;
 		if (type->datum.nodes->head->data == node) {
-			// multiple AST nodes can point to the same cil_type data (like if
-			// copied from a macro). This check ensures we only count the
-			// duplicates once
+			// Multiple nodes can point to the same datum. Only count once.
 			type->value = db->num_types;
 			db->num_types++;
+			db->num_types_and_attrs++;
 		}
 		break;
 	}
+	case CIL_TYPEATTRIBUTE: {
+		struct cil_typeattribute *attr = node->data;
+		if (attr->datum.nodes->head->data == node) {
+			// Multiple nodes can point to the same datum. Only count once.
+			db->num_types_and_attrs++;
+		}
+		break;
+	}
+
 	case CIL_ROLE: {
 		struct cil_role *role = node->data;
 		if (role->datum.nodes->head->data == node) {
-			// multiple AST nodes can point to the same cil_role data (like if
-			// copied from a macro). This check ensures we only count the
-			// duplicates once
+			// Multiple nodes can point to the same datum. Only count once.
 			role->value = db->num_roles;
 			db->num_roles++;
 		}
-- 
1.9.3

_______________________________________________
Selinux mailing list
Selinux@xxxxxxxxxxxxx
To unsubscribe, send email to Selinux-leave@xxxxxxxxxxxxx.
To get help, send an email containing "help" to Selinux-request@xxxxxxxxxxxxx.



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

  Powered by Linux