All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] CIL Cleanups and Improved Argument handling
@ 2023-09-27 19:00 James Carter
  2023-09-27 19:00 ` [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void * James Carter
                   ` (8 more replies)
  0 siblings, 9 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

Patches 1 and 2 are cleanups
Patch 3 allows IP address and mask values to be directly written.
Patches 4 and 7 update and fix the CIL documentation.
Patch 5 improves the handling of strings passed into a call for named
  type transitions.
Patch 6 allows the path of a filecon rule to be passed as an argument
  in a call.
Patch 8 improves writing out statements in macros and macro arguments.
Patch 9 adds a warning when an identifier has the same name as a call
  argument even though it has a different flavor.

See the individual patches for more details.

James Carter (9):
  libsepol/cil: Use struct cil_db * instead of void *
  libsepol/cil: Refactor and improve handling of order rules
  libsepol/cil: Allow IP address and mask values to be directly written
  secilc/docs: Update syntax for IP addresses and nodecon
  libsepol/cil: Refactor Named Type Transition Filename Creation
  libsepol/cil: Allow paths in filecon rules to be passed as arguments
  secilc/docs: Fix and update the documentation for macro parameters
  libsepol/cil: Add pointers to datums to improve writing out AST
  libsepol/cil: Give warning for name that has different flavor

 libsepol/cil/src/cil.c                        |  108 +-
 libsepol/cil/src/cil_build_ast.c              |  461 +++-----
 libsepol/cil/src/cil_build_ast.h              |   13 +-
 libsepol/cil/src/cil_copy_ast.c               |   96 +-
 libsepol/cil/src/cil_copy_ast.h               |    5 +-
 libsepol/cil/src/cil_flavor.h                 |    2 +-
 libsepol/cil/src/cil_fqn.c                    |    2 +-
 libsepol/cil/src/cil_internal.h               |   58 +-
 libsepol/cil/src/cil_policy.c                 |    5 +-
 libsepol/cil/src/cil_post.c                   |   14 +-
 libsepol/cil/src/cil_reset_ast.c              |   16 +-
 libsepol/cil/src/cil_resolve_ast.c            | 1027 +++++++----------
 libsepol/cil/src/cil_resolve_ast.h            |  124 +-
 libsepol/cil/src/cil_verify.c                 |   80 +-
 libsepol/cil/src/cil_verify.h                 |    1 +
 libsepol/cil/src/cil_write_ast.c              |  125 +-
 secilc/docs/cil_call_macro_statements.md      |    6 +-
 .../docs/cil_network_labeling_statements.md   |    6 +-
 18 files changed, 982 insertions(+), 1167 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:27   ` Daniel Burgener
  2023-09-27 19:00 ` [PATCH 2/9] libsepol/cil: Refactor and improve handling of order rules James Carter
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

In the CIL AST resolve phase, the functions all take a void *
and struct cil_args_resolve * is passed in to them. But in almost
all cases, only the cil_db is needed.

Modify the functions to take struct cil_db * and pass in extra
arguments in the few cases where something more is needed.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil_resolve_ast.c | 631 +++++++++++++----------------
 libsepol/cil/src/cil_resolve_ast.h | 124 +++---
 2 files changed, 350 insertions(+), 405 deletions(-)

diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 33b9d321..595bd2b9 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -156,7 +156,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, void *extra_args)
+int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_symtab_datum *datum = NULL;
@@ -167,7 +167,7 @@ int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms
 		return SEPOL_OK;
 	}
 
-	rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, extra_args, &datum);
+	rc = cil_resolve_name(current, cp->class_str, CIL_SYM_CLASSES, db, &datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -191,12 +191,12 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_classperms_set *cp_set, void *extra_args)
+static int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_classperms_set *cp_set, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_symtab_datum *datum = NULL;
 
-	rc = cil_resolve_name(current, cp_set->set_str, CIL_SYM_CLASSPERMSETS, extra_args, &datum);
+	rc = cil_resolve_name(current, cp_set->set_str, CIL_SYM_CLASSPERMSETS, db, &datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -204,7 +204,7 @@ static int cil_resolve_classperms_set(struct cil_tree_node *current, struct cil_
 
 	/* This could be an anonymous classpermission */
 	if (datum->name == NULL) {
-		rc = cil_resolve_classperms_list(current, cp_set->set->classperms, extra_args);
+		rc = cil_resolve_classperms_list(current, cp_set->set->classperms, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -216,19 +216,19 @@ exit:
 	return rc;
 }
 
-int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, void *extra_args)
+int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_list_item *curr;
 
 	cil_list_for_each(curr, cp_list) {
 		if (curr->flavor == CIL_CLASSPERMS) {
-			rc = cil_resolve_classperms(current, curr->data, extra_args);
+			rc = cil_resolve_classperms(current, curr->data, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		} else {
-			rc = cil_resolve_classperms_set(current, curr->data, extra_args);
+			rc = cil_resolve_classperms_set(current, curr->data, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -241,20 +241,19 @@ exit:
 	return rc;
 }
 
-int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, void *extra_args)
+int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
-	struct cil_args_resolve *args = extra_args;
 	struct cil_list_item *curr;
 	struct cil_symtab_datum *datum;
 	struct cil_classpermission *cp;
 
-	rc = cil_resolve_name(current, cps->set_str, CIL_SYM_CLASSPERMSETS, args, &datum);
+	rc = cil_resolve_name(current, cps->set_str, CIL_SYM_CLASSPERMSETS, db, &datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 
-	rc = cil_resolve_classperms_list(current, cps->classperms, extra_args);
+	rc = cil_resolve_classperms_list(current, cps->classperms, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -292,12 +291,12 @@ static void cil_type_used(struct cil_symtab_datum *datum, int used)
 	}
 }
 
-static int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, void *extra_args)
+static int cil_resolve_permissionx(struct cil_tree_node *current, struct cil_permissionx *permx, struct cil_db *db)
 {
 	struct cil_symtab_datum *obj_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+	rc = cil_resolve_name(current, permx->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -309,11 +308,8 @@ exit:
 	return rc;
 }
 
-int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_avrule(struct cil_tree_node *current, struct cil_db *db)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_db *db = NULL;
-
 	struct cil_avrule *rule = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
 	struct cil_symtab_datum *tgt_datum = NULL;
@@ -321,11 +317,7 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args)
 	int used;
 	int rc = SEPOL_ERR;
 
-	if (args != NULL) {
-		db = args->db;
-	}
-
-	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum);
+	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -338,7 +330,7 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args)
 	} else if (rule->tgt_str == CIL_KEY_OTHER) {
 		rule->tgt = db->othertype;
 	} else {
-		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum);
+		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -350,19 +342,19 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args)
 	}
 
 	if (!rule->is_extended) {
-		rc = cil_resolve_classperms_list(current, rule->perms.classperms, extra_args);
+		rc = cil_resolve_classperms_list(current, rule->perms.classperms, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 	} else {
 		if (rule->perms.x.permx_str != NULL) {
-			rc = cil_resolve_name(current, rule->perms.x.permx_str, CIL_SYM_PERMX, args, &permx_datum);
+			rc = cil_resolve_name(current, rule->perms.x.permx_str, CIL_SYM_PERMX, db, &permx_datum);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 			rule->perms.x.permx = (struct cil_permissionx*)permx_datum;
 		} else {
-			rc = cil_resolve_permissionx(current, rule->perms.x.permx, extra_args);
+			rc = cil_resolve_permissionx(current, rule->perms.x.permx, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -375,21 +367,14 @@ exit:
 	return rc;
 }
 
-int cil_resolve_deny_rule(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_deny_rule(struct cil_tree_node *current, struct cil_db *db)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_db *db = NULL;
-
 	struct cil_deny_rule *rule = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
 	struct cil_symtab_datum *tgt_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	if (args != NULL) {
-		db = args->db;
-	}
-
-	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, args, &src_datum);
+	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -402,14 +387,14 @@ int cil_resolve_deny_rule(struct cil_tree_node *current, void *extra_args)
 	} else if (rule->tgt_str == CIL_KEY_OTHER) {
 		rule->tgt = db->othertype;
 	} else {
-		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum);
+		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		rule->tgt = tgt_datum;
 	}
 
-	rc = cil_resolve_classperms_list(current, rule->classperms, extra_args);
+	rc = cil_resolve_classperms_list(current, rule->classperms, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -420,9 +405,8 @@ exit:
 	return rc;
 }
 
-int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_type_rule(struct cil_tree_node *current, struct cil_db *db)
 {
-	struct cil_args_resolve *args = extra_args;
 	struct cil_type_rule *rule = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
 	struct cil_symtab_datum *tgt_datum = NULL;
@@ -431,29 +415,29 @@ int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args)
 	struct cil_tree_node *result_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, extra_args, &src_datum);
+	rc = cil_resolve_name(current, rule->src_str, CIL_SYM_TYPES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	rule->src = src_datum;
 
 	if (rule->tgt_str == CIL_KEY_SELF) {
-		rule->tgt = args->db->selftype;
+		rule->tgt = db->selftype;
 	} else {
-		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum);
+		rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		rule->tgt = tgt_datum;
 	}
 
-	rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+	rc = cil_resolve_name(current, rule->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	rule->obj = (struct cil_class*)obj_datum;
 
-	rc = cil_resolve_name(current, rule->result_str, CIL_SYM_TYPES, extra_args, &result_datum);
+	rc = cil_resolve_name(current, rule->result_str, CIL_SYM_TYPES, db, &result_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -473,7 +457,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_typeattributeset(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_typeattributeset *attrtypes = current->data;
 	struct cil_symtab_datum *attr_datum = NULL;
@@ -481,7 +465,7 @@ int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args
 	struct cil_typeattribute *attr = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, attrtypes->attr_str, CIL_SYM_TYPES, extra_args, &attr_datum);
+	rc = cil_resolve_name(current, attrtypes->attr_str, CIL_SYM_TYPES, db, &attr_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -496,7 +480,7 @@ int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args
 
 	attr = (struct cil_typeattribute*)attr_datum;
 
-	rc = cil_resolve_expr(CIL_TYPEATTRIBUTESET, attrtypes->str_expr, &attrtypes->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_TYPEATTRIBUTESET, attrtypes->str_expr, &attrtypes->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -513,7 +497,7 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_expandtypeattribute(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_expandtypeattribute *expandattr = current->data;
 	struct cil_symtab_datum *attr_datum = NULL;
@@ -525,7 +509,7 @@ static int cil_resolve_expandtypeattribute(struct cil_tree_node *current, void *
 	cil_list_init(&expandattr->attr_datums, CIL_TYPE);
 
 	cil_list_for_each(curr, expandattr->attr_strs) {
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_TYPES, extra_args, &attr_datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_TYPES, db, &attr_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -547,7 +531,7 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor alias_flavor)
+static int cil_resolve_aliasactual(struct cil_tree_node *current, struct cil_db *db, enum cil_flavor flavor, enum cil_flavor alias_flavor)
 {
 	int rc = SEPOL_ERR;
 	enum cil_sym_index sym_index;
@@ -561,7 +545,7 @@ static int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_ar
 		goto exit;
 	}
 
-	rc = cil_resolve_name_keep_aliases(current, aliasactual->alias_str, sym_index, extra_args, &alias_datum);
+	rc = cil_resolve_name_keep_aliases(current, aliasactual->alias_str, sym_index, db, &alias_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -571,7 +555,7 @@ static int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_ar
 		goto exit;
 	}
 
-	rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, extra_args, &actual_datum);
+	rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, db, &actual_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -646,14 +630,14 @@ static int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_f
 	return SEPOL_OK;
 }
 
-int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_typepermissive(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_typepermissive *typeperm = current->data;
 	struct cil_symtab_datum *type_datum = NULL;
 	struct cil_tree_node *type_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
+	rc = cil_resolve_name(current, typeperm->type_str, CIL_SYM_TYPES, db, &type_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -674,9 +658,8 @@ exit:
 	return rc;
 }
 
-int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_nametypetransition(struct cil_tree_node *current, struct cil_db *db)
 {
-	struct cil_args_resolve *args = extra_args;
 	struct cil_nametypetransition *nametypetrans = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
 	struct cil_symtab_datum *tgt_datum = NULL;
@@ -686,38 +669,38 @@ int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_ar
 	struct cil_tree_node *result_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, nametypetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum);
+	rc = cil_resolve_name(current, nametypetrans->src_str, CIL_SYM_TYPES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	nametypetrans->src = src_datum;
 
 	if (nametypetrans->tgt_str == CIL_KEY_SELF) {
-		nametypetrans->tgt = args->db->selftype;
+		nametypetrans->tgt = db->selftype;
 	} else {
-		rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum);
+		rc = cil_resolve_name(current, nametypetrans->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		nametypetrans->tgt = tgt_datum;
 	}
 
-	rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+	rc = cil_resolve_name(current, nametypetrans->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	nametypetrans->obj = (struct cil_class*)obj_datum;
 
-	nametypetrans->name = __cil_insert_name(args->db, nametypetrans->name_str, current);
+	nametypetrans->name = __cil_insert_name(db, nametypetrans->name_str, current);
 	if (nametypetrans->name == NULL) {
-		rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_NAMES, extra_args, &name_datum);
+		rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_NAMES, db, &name_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		nametypetrans->name = (struct cil_name *)name_datum;
 	}
 
-	rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, extra_args, &result_datum);
+	rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, db, &result_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -737,7 +720,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_rangetransition(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_rangetransition *rangetrans = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
@@ -746,26 +729,26 @@ int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args)
 	struct cil_symtab_datum *range_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, rangetrans->src_str, CIL_SYM_TYPES, extra_args, &src_datum);
+	rc = cil_resolve_name(current, rangetrans->src_str, CIL_SYM_TYPES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	rangetrans->src = src_datum;
 
-	rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, extra_args, &exec_datum);
+	rc = cil_resolve_name(current, rangetrans->exec_str, CIL_SYM_TYPES, db, &exec_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	rangetrans->exec = exec_datum;
 
-	rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+	rc = cil_resolve_name(current, rangetrans->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	rangetrans->obj = (struct cil_class*)obj_datum;
 
 	if (rangetrans->range_str != NULL) {
-		rc = cil_resolve_name(current, rangetrans->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum);
+		rc = cil_resolve_name(current, rangetrans->range_str, CIL_SYM_LEVELRANGES, db, &range_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -773,13 +756,13 @@ int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args)
 
 		/* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/
 		if (rangetrans->range->datum.name == NULL) {
-			rc = cil_resolve_levelrange(current, rangetrans->range, extra_args);
+			rc = cil_resolve_levelrange(current, rangetrans->range, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else {
-		rc = cil_resolve_levelrange(current, rangetrans->range, extra_args);
+		rc = cil_resolve_levelrange(current, rangetrans->range, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -800,7 +783,7 @@ static int __class_update_perm_values(__attribute__((unused)) hashtab_key_t k, h
 	return SEPOL_OK;
 }
 
-int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_classcommon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_class *class = NULL;
 	struct cil_class *common = NULL;
@@ -809,7 +792,7 @@ int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args)
 	struct cil_symtab_datum *common_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, clscom->class_str, CIL_SYM_CLASSES, extra_args, &class_datum);
+	rc = cil_resolve_name(current, clscom->class_str, CIL_SYM_CLASSES, db, &class_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -819,7 +802,7 @@ int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args)
 		goto exit;
 	}
 
-	rc = cil_resolve_name(current, clscom->common_str, CIL_SYM_COMMONS, extra_args, &common_datum);
+	rc = cil_resolve_name(current, clscom->common_str, CIL_SYM_COMMONS, db, &common_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -849,7 +832,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_classmapping(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_classmapping *mapping = current->data;
@@ -858,7 +841,7 @@ int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args)
 	struct cil_symtab_datum *datum = NULL;
 	struct cil_list_item *curr;
 
-	rc = cil_resolve_name(current, mapping->map_class_str, CIL_SYM_CLASSES, extra_args, &datum);
+	rc = cil_resolve_name(current, mapping->map_class_str, CIL_SYM_CLASSES, db, &datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -871,7 +854,7 @@ int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args)
 
 	mp = (struct cil_perm*)datum;
 
-	rc = cil_resolve_classperms_list(current, mapping->classperms, extra_args);
+	rc = cil_resolve_classperms_list(current, mapping->classperms, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -890,20 +873,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_userrole(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_userrole *userrole = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_symtab_datum *role_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, userrole->user_str, CIL_SYM_USERS, extra_args, &user_datum);
+	rc = cil_resolve_name(current, userrole->user_str, CIL_SYM_USERS, db, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	userrole->user = (struct cil_user*)user_datum;
 
-	rc = cil_resolve_name(current, userrole->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
+	rc = cil_resolve_name(current, userrole->role_str, CIL_SYM_ROLES, db, &role_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -915,7 +898,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_userlevel(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_userlevel *usrlvl = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
@@ -924,7 +907,7 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
 	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, extra_args, &user_datum);
+	rc = cil_resolve_name(current, usrlvl->user_str, CIL_SYM_USERS, db, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -940,7 +923,7 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
 	user = (struct cil_user*)user_datum;
 
 	if (usrlvl->level_str != NULL) {
-		rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, extra_args, &lvl_datum);
+		rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, db, &lvl_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -949,13 +932,13 @@ int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args)
 
 		/* This could still be an anonymous level even if level_str is set, if level_str is a param_str*/
 		if (user->dftlevel->datum.name == NULL) {
-			rc = cil_resolve_level(current, user->dftlevel, extra_args);
+			rc = cil_resolve_level(current, user->dftlevel, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else if (usrlvl->level != NULL) {
-		rc = cil_resolve_level(current, usrlvl->level, extra_args);
+		rc = cil_resolve_level(current, usrlvl->level, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -968,7 +951,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_userrange(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_userrange *userrange = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
@@ -977,7 +960,7 @@ int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
 	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, extra_args, &user_datum);
+	rc = cil_resolve_name(current, userrange->user_str, CIL_SYM_USERS, db, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -993,7 +976,7 @@ int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
 	user = (struct cil_user*)user_datum;
 
 	if (userrange->range_str != NULL) {
-		rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, extra_args, &range_datum);
+		rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, db, &range_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1002,13 +985,13 @@ int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args)
 
 		/* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/
 		if (user->range->datum.name == NULL) {
-			rc = cil_resolve_levelrange(current, user->range, extra_args);
+			rc = cil_resolve_levelrange(current, user->range, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else if (userrange->range != NULL) {
-		rc = cil_resolve_levelrange(current, userrange->range, extra_args);
+		rc = cil_resolve_levelrange(current, userrange->range, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1021,14 +1004,14 @@ exit:
 	return rc;
 }
 
-int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_userprefix(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_userprefix *userprefix = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, extra_args, &user_datum);
+	rc = cil_resolve_name(current, userprefix->user_str, CIL_SYM_USERS, db, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1047,7 +1030,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_selinuxuser(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_selinuxuser *selinuxuser = current->data;
 	struct cil_symtab_datum *user_datum = NULL;
@@ -1055,7 +1038,7 @@ int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
 	struct cil_tree_node *user_node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, extra_args, &user_datum);
+	rc = cil_resolve_name(current, selinuxuser->user_str, CIL_SYM_USERS, db, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1071,7 +1054,7 @@ int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
 	selinuxuser->user = (struct cil_user*)user_datum;
 
 	if (selinuxuser->range_str != NULL) {
-		rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
+		rc = cil_resolve_name(current, selinuxuser->range_str, CIL_SYM_LEVELRANGES, db, &lvlrange_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1079,13 +1062,13 @@ int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args)
 
 		/* This could still be an anonymous levelrange even if range_str is set, if range_str is a param_str*/
 		if (selinuxuser->range->datum.name == NULL) {
-			rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args);
+			rc = cil_resolve_levelrange(current, selinuxuser->range, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else if (selinuxuser->range != NULL) {
-		rc = cil_resolve_levelrange(current, selinuxuser->range, extra_args);
+		rc = cil_resolve_levelrange(current, selinuxuser->range, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1096,20 +1079,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_roletype(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_roletype *roletype = current->data;
 	struct cil_symtab_datum *role_datum = NULL;
 	struct cil_symtab_datum *type_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, roletype->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
+	rc = cil_resolve_name(current, roletype->role_str, CIL_SYM_ROLES, db, &role_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	roletype->role = (struct cil_role*)role_datum;
 
-	rc = cil_resolve_name(current, roletype->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
+	rc = cil_resolve_name(current, roletype->type_str, CIL_SYM_TYPES, db, &type_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1121,7 +1104,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_roletransition(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_roletransition *roletrans = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
@@ -1131,25 +1114,25 @@ int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args)
 	struct cil_tree_node *node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, roletrans->src_str, CIL_SYM_ROLES, extra_args, &src_datum);
+	rc = cil_resolve_name(current, roletrans->src_str, CIL_SYM_ROLES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	roletrans->src = (struct cil_role*)src_datum;
 
-	rc = cil_resolve_name(current, roletrans->tgt_str, CIL_SYM_TYPES, extra_args, &tgt_datum);
+	rc = cil_resolve_name(current, roletrans->tgt_str, CIL_SYM_TYPES, db, &tgt_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	roletrans->tgt = tgt_datum;
 
-	rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, extra_args, &obj_datum);
+	rc = cil_resolve_name(current, roletrans->obj_str, CIL_SYM_CLASSES, db, &obj_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	roletrans->obj = (struct cil_class*)obj_datum;
 
-	rc = cil_resolve_name(current, roletrans->result_str, CIL_SYM_ROLES, extra_args, &result_datum);
+	rc = cil_resolve_name(current, roletrans->result_str, CIL_SYM_ROLES, db, &result_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1167,20 +1150,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_roleallow(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_roleallow(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_roleallow *roleallow = current->data;
 	struct cil_symtab_datum *src_datum = NULL;
 	struct cil_symtab_datum *tgt_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, roleallow->src_str, CIL_SYM_ROLES, extra_args, &src_datum);
+	rc = cil_resolve_name(current, roleallow->src_str, CIL_SYM_ROLES, db, &src_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	roleallow->src = (struct cil_role*)src_datum;
 
-	rc = cil_resolve_name(current, roleallow->tgt_str, CIL_SYM_ROLES, extra_args, &tgt_datum);
+	rc = cil_resolve_name(current, roleallow->tgt_str, CIL_SYM_ROLES, db, &tgt_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1192,7 +1175,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_roleattributeset(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_roleattributeset *attrroles = current->data;
@@ -1200,7 +1183,7 @@ int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args
 	struct cil_tree_node *attr_node = NULL;
 	struct cil_roleattribute *attr = NULL;
 
-	rc = cil_resolve_name(current, attrroles->attr_str, CIL_SYM_ROLES, extra_args, &attr_datum);
+	rc = cil_resolve_name(current, attrroles->attr_str, CIL_SYM_ROLES, db, &attr_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1213,7 +1196,7 @@ int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args
 	}
 	attr = (struct cil_roleattribute*)attr_datum;
 
-	rc = cil_resolve_expr(CIL_ROLEATTRIBUTESET, attrroles->str_expr, &attrroles->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_ROLEATTRIBUTESET, attrroles->str_expr, &attrroles->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1523,11 +1506,8 @@ exit:
 	return NULL;
 }
 
-int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_classorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *classorder_list, struct cil_list *unordered_classorder_list)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_list *classorder_list = args->classorder_lists;
-	struct cil_list *unordered_classorder_list = args->unordered_classorder_lists;
 	struct cil_classorder *classorder = current->data;
 	struct cil_list *new = NULL;
 	struct cil_list_item *curr = NULL;
@@ -1544,7 +1524,7 @@ int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args)
 			continue;
 		}
 
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, db, &datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve class %s in classorder\n", (char *)curr->data);
 			rc = SEPOL_ERR;
@@ -1574,10 +1554,8 @@ exit:
 	return rc;
 }
 
-int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_sidorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sidorder_list)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_list *sidorder_list = args->sidorder_lists;
 	struct cil_sidorder *sidorder = current->data;
 	struct cil_list *new = NULL;
 	struct cil_list_item *curr = NULL;
@@ -1588,7 +1566,7 @@ int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args)
 	cil_list_init(&new, CIL_SIDORDER);
 
 	cil_list_for_each(curr, sidorder->sid_list_str) {
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, extra_args, &datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, db, &datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data);
 			goto exit;
@@ -1628,10 +1606,8 @@ static void cil_set_cat_values(struct cil_list *ordered_cats, struct cil_db *db)
 	db->num_cats = v;
 }
 
-int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_catorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *catorder_list)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_list *catorder_list = args->catorder_lists;
 	struct cil_catorder *catorder = current->data;
 	struct cil_list *new = NULL;
 	struct cil_list_item *curr = NULL;
@@ -1644,7 +1620,7 @@ int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args)
 
 	cil_list_for_each(curr, catorder->cat_list_str) {
 		struct cil_tree_node *node = NULL;
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, extra_args, &cat_datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, db, &cat_datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data);
 			goto exit;
@@ -1671,10 +1647,8 @@ exit:
 	return rc;
 }
 
-int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_sensitivityorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sensitivityorder_list)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_list *sensitivityorder_list = args->sensitivityorder_lists;
 	struct cil_sensorder *sensorder = current->data;
 	struct cil_list *new = NULL;
 	struct cil_list_item *curr = NULL;
@@ -1685,7 +1659,7 @@ int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args
 	cil_list_init(&new, CIL_LIST_ITEM);
 
 	cil_list_for_each(curr, sensorder->sens_list_str) {
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, extra_args, &datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, db, &datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve sensitivity %s in sensitivityorder\n", (char *)curr->data);
 			goto exit;
@@ -1710,11 +1684,11 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, void *extra_args)
+static int cil_resolve_cats(struct cil_tree_node *current, struct cil_cats *cats, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_CATSET, cats->str_expr, &cats->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1726,25 +1700,25 @@ exit:
 }
 
 
-int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args)
+int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, struct cil_db *db)
 {
-	return cil_resolve_cats(current, catset->cats, extra_args);
+	return cil_resolve_cats(current, catset->cats, db);
 }
 
-int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_senscat(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_senscat *senscat = current->data;
 	struct cil_symtab_datum *sens_datum;
 	struct cil_sens *sens = NULL;
 
-	rc = cil_resolve_name(current, (char*)senscat->sens_str, CIL_SYM_SENS, extra_args, &sens_datum);
+	rc = cil_resolve_name(current, (char*)senscat->sens_str, CIL_SYM_SENS, db, &sens_datum);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_ERR, "Failed to find sensitivity\n");
 		goto exit;
 	}
 
-	rc = cil_resolve_cats(current, senscat->cats, extra_args);
+	rc = cil_resolve_cats(current, senscat->cats, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1763,7 +1737,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, void *extra_args)
+int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, struct cil_db *db)
 {
 	struct cil_symtab_datum *sens_datum = NULL;
 	int rc = SEPOL_ERR;
@@ -1772,7 +1746,7 @@ int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, vo
 		return SEPOL_OK;
 	}
 
-	rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, extra_args, &sens_datum);
+	rc = cil_resolve_name(current, (char*)level->sens_str, CIL_SYM_SENS, db, &sens_datum);
 	if (rc != SEPOL_OK) {
 		cil_log(CIL_ERR, "Failed to find sensitivity\n");
 		goto exit;
@@ -1781,7 +1755,7 @@ int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, vo
 	level->sens = (struct cil_sens *)sens_datum;
 
 	if (level->cats != NULL) {
-		rc = cil_resolve_cats(current, level->cats, extra_args);
+		rc = cil_resolve_cats(current, level->cats, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1793,14 +1767,14 @@ exit:
 	return rc;
 }
 
-int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *lvlrange, void *extra_args)
+int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *lvlrange, struct cil_db *db)
 {
 	struct cil_symtab_datum *low_datum = NULL;
 	struct cil_symtab_datum *high_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (lvlrange->low_str != NULL) {
-		rc = cil_resolve_name(current, lvlrange->low_str, CIL_SYM_LEVELS, extra_args, &low_datum);
+		rc = cil_resolve_name(current, lvlrange->low_str, CIL_SYM_LEVELS, db, &low_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1808,20 +1782,20 @@ int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange
 
 		/* This could still be an anonymous level even if low_str is set, if low_str is a param_str */
 		if (lvlrange->low->datum.name == NULL) {
-			rc = cil_resolve_level(current, lvlrange->low, extra_args);
+			rc = cil_resolve_level(current, lvlrange->low, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else if (lvlrange->low != NULL) {
-		rc = cil_resolve_level(current, lvlrange->low, extra_args);
+		rc = cil_resolve_level(current, lvlrange->low, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 	}
 
 	if (lvlrange->high_str != NULL) {
-		rc = cil_resolve_name(current, lvlrange->high_str, CIL_SYM_LEVELS, extra_args, &high_datum);
+		rc = cil_resolve_name(current, lvlrange->high_str, CIL_SYM_LEVELS, db, &high_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1829,13 +1803,13 @@ int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange
 
 		/* This could still be an anonymous level even if high_str is set, if high_str is a param_str */
 		if (lvlrange->high->datum.name == NULL) {
-			rc = cil_resolve_level(current, lvlrange->high, extra_args);
+			rc = cil_resolve_level(current, lvlrange->high, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else if (lvlrange->high != NULL) {
-		rc = cil_resolve_level(current, lvlrange->high, extra_args);
+		rc = cil_resolve_level(current, lvlrange->high, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1847,17 +1821,17 @@ exit:
 	return rc;
 }
 
-int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_constrain(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_constrain *cons = current->data;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_classperms_list(current, cons->classperms, extra_args);
+	rc = cil_resolve_classperms_list(current, cons->classperms, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 
-	rc = cil_resolve_expr(CIL_CONSTRAIN, cons->str_expr, &cons->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_CONSTRAIN, cons->str_expr, &cons->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1868,20 +1842,19 @@ exit:
 	return rc;
 }
 
-int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_validatetrans(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_validatetrans *validtrans = current->data;
-	struct cil_args_resolve *args = extra_args;
 	struct cil_symtab_datum *class_datum = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, validtrans->class_str, CIL_SYM_CLASSES, args, &class_datum);
+	rc = cil_resolve_name(current, validtrans->class_str, CIL_SYM_CLASSES, db, &class_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	validtrans->class = (struct cil_class*)class_datum;
 
-	rc = cil_resolve_expr(CIL_VALIDATETRANS, validtrans->str_expr, &validtrans->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_VALIDATETRANS, validtrans->str_expr, &validtrans->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1892,7 +1865,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args)
+int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, struct cil_db *db)
 {
 	struct cil_symtab_datum *user_datum = NULL;
 	struct cil_symtab_datum *role_datum = NULL;
@@ -1902,7 +1875,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
 
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, extra_args, &user_datum);
+	rc = cil_resolve_name(current, context->user_str, CIL_SYM_USERS, db, &user_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1917,7 +1890,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
 
 	context->user = (struct cil_user*)user_datum;
 
-	rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, extra_args, &role_datum);
+	rc = cil_resolve_name(current, context->role_str, CIL_SYM_ROLES, db, &role_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1931,7 +1904,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
 
 	context->role = (struct cil_role*)role_datum;
 
-	rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, extra_args, &type_datum);
+	rc = cil_resolve_name(current, context->type_str, CIL_SYM_TYPES, db, &type_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -1946,7 +1919,7 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
 	context->type = type_datum;
 
 	if (context->range_str != NULL) {
-		rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, extra_args, &lvlrange_datum);
+		rc = cil_resolve_name(current, context->range_str, CIL_SYM_LEVELRANGES, db, &lvlrange_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1954,13 +1927,13 @@ int cil_resolve_context(struct cil_tree_node *current, struct cil_context *conte
 
 		/* This could still be an anonymous levelrange even if levelrange_str is set, if levelrange_str is a param_str*/
 		if (context->range->datum.name == NULL) {
-			rc = cil_resolve_levelrange(current, context->range, extra_args);
+			rc = cil_resolve_levelrange(current, context->range, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 		}
 	} else if (context->range != NULL) {
-		rc = cil_resolve_levelrange(current, context->range, extra_args);
+		rc = cil_resolve_levelrange(current, context->range, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -1972,20 +1945,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_filecon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_filecon *filecon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (filecon->context_str != NULL) {
-		rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			return rc;
 		}
 		filecon->context = (struct cil_context*)context_datum;
 	} else if (filecon->context != NULL) {
-		rc = cil_resolve_context(current, filecon->context, extra_args);
+		rc = cil_resolve_context(current, filecon->context, db);
 		if (rc != SEPOL_OK) {
 			return rc;
 		}
@@ -1994,20 +1967,20 @@ int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args)
 	return SEPOL_OK;
 }
 
-int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_ibpkeycon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_ibpkeycon *ibpkeycon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (ibpkeycon->context_str) {
-		rc = cil_resolve_name(current, ibpkeycon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, ibpkeycon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK)
 			goto exit;
 
 		ibpkeycon->context = (struct cil_context *)context_datum;
 	} else {
-		rc = cil_resolve_context(current, ibpkeycon->context, extra_args);
+		rc = cil_resolve_context(current, ibpkeycon->context, db);
 		if (rc != SEPOL_OK)
 			goto exit;
 	}
@@ -2018,20 +1991,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_portcon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_portcon *portcon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (portcon->context_str != NULL) {
-		rc = cil_resolve_name(current, portcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, portcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		portcon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, portcon->context, extra_args);
+		rc = cil_resolve_context(current, portcon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2043,20 +2016,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_genfscon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_genfscon *genfscon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (genfscon->context_str != NULL) {
-		rc = cil_resolve_name(current, genfscon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, genfscon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		genfscon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, genfscon->context, extra_args);
+		rc = cil_resolve_context(current, genfscon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2068,7 +2041,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_nodecon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_nodecon *nodecon = current->data;
 	struct cil_symtab_datum *addr_datum = NULL;
@@ -2077,7 +2050,7 @@ int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args)
 	int rc = SEPOL_ERR;
 
 	if (nodecon->addr_str != NULL) {
-		rc = cil_resolve_name(current, nodecon->addr_str, CIL_SYM_IPADDRS, extra_args, &addr_datum);
+		rc = cil_resolve_name(current, nodecon->addr_str, CIL_SYM_IPADDRS, db, &addr_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2085,7 +2058,7 @@ int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args)
 	}
 
 	if (nodecon->mask_str != NULL) {
-		rc = cil_resolve_name(current, nodecon->mask_str, CIL_SYM_IPADDRS, extra_args, &mask_datum);
+		rc = cil_resolve_name(current, nodecon->mask_str, CIL_SYM_IPADDRS, db, &mask_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2093,13 +2066,13 @@ int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args)
 	}
 
 	if (nodecon->context_str != NULL) {
-		rc = cil_resolve_name(current, nodecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, nodecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		nodecon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, nodecon->context, extra_args);
+		rc = cil_resolve_context(current, nodecon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2118,7 +2091,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_netifcon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_netifcon *netifcon = current->data;
 	struct cil_symtab_datum *ifcon_datum = NULL;
@@ -2127,26 +2100,26 @@ int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args)
 	int rc = SEPOL_ERR;
 
 	if (netifcon->if_context_str != NULL) {
-		rc = cil_resolve_name(current, netifcon->if_context_str, CIL_SYM_CONTEXTS, extra_args, &ifcon_datum);
+		rc = cil_resolve_name(current, netifcon->if_context_str, CIL_SYM_CONTEXTS, db, &ifcon_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		netifcon->if_context = (struct cil_context*)ifcon_datum;
 	} else {
-		rc = cil_resolve_context(current, netifcon->if_context, extra_args);
+		rc = cil_resolve_context(current, netifcon->if_context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 	}
 
 	if (netifcon->packet_context_str != NULL) {
-		rc = cil_resolve_name(current, netifcon->packet_context_str, CIL_SYM_CONTEXTS, extra_args, &packcon_datum);
+		rc = cil_resolve_name(current, netifcon->packet_context_str, CIL_SYM_CONTEXTS, db, &packcon_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		netifcon->packet_context = (struct cil_context*)packcon_datum;
 	} else {
-		rc = cil_resolve_context(current, netifcon->packet_context, extra_args);
+		rc = cil_resolve_context(current, netifcon->packet_context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2157,7 +2130,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_ibendportcon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_ibendportcon *ibendportcon = current->data;
 	struct cil_symtab_datum *con_datum = NULL;
@@ -2165,13 +2138,13 @@ int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args)
 	int rc = SEPOL_ERR;
 
 	if (ibendportcon->context_str) {
-		rc = cil_resolve_name(current, ibendportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &con_datum);
+		rc = cil_resolve_name(current, ibendportcon->context_str, CIL_SYM_CONTEXTS, db, &con_datum);
 		if (rc != SEPOL_OK)
 			goto exit;
 
 		ibendportcon->context = (struct cil_context *)con_datum;
 	} else {
-		rc = cil_resolve_context(current, ibendportcon->context, extra_args);
+		rc = cil_resolve_context(current, ibendportcon->context, db);
 		if (rc != SEPOL_OK)
 			goto exit;
 	}
@@ -2182,20 +2155,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_pirqcon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_pirqcon *pirqcon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (pirqcon->context_str != NULL) {
-		rc = cil_resolve_name(current, pirqcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, pirqcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		pirqcon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, pirqcon->context, extra_args);
+		rc = cil_resolve_context(current, pirqcon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2207,20 +2180,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_iomemcon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_iomemcon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_iomemcon *iomemcon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (iomemcon->context_str != NULL) {
-		rc = cil_resolve_name(current, iomemcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, iomemcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		iomemcon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, iomemcon->context, extra_args);
+		rc = cil_resolve_context(current, iomemcon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2232,20 +2205,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_ioportcon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_ioportcon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_ioportcon *ioportcon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (ioportcon->context_str != NULL) {
-		rc = cil_resolve_name(current, ioportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, ioportcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		ioportcon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, ioportcon->context, extra_args);
+		rc = cil_resolve_context(current, ioportcon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2257,20 +2230,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_pcidevicecon(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_pcidevicecon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_pcidevicecon *pcidevicecon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (pcidevicecon->context_str != NULL) {
-		rc = cil_resolve_name(current, pcidevicecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, pcidevicecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		pcidevicecon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, pcidevicecon->context, extra_args);
+		rc = cil_resolve_context(current, pcidevicecon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2282,20 +2255,20 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_devicetreecon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_devicetreecon *devicetreecon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (devicetreecon->context_str != NULL) {
-		rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		devicetreecon->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, devicetreecon->context, extra_args);
+		rc = cil_resolve_context(current, devicetreecon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2307,20 +2280,20 @@ exit:
 	return rc;
 }
 
-int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_fsuse(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_fsuse *fsuse = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
 	int rc = SEPOL_ERR;
 
 	if (fsuse->context_str != NULL) {
-		rc = cil_resolve_name(current, fsuse->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, fsuse->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		fsuse->context = (struct cil_context*)context_datum;
 	} else {
-		rc = cil_resolve_context(current, fsuse->context, extra_args);
+		rc = cil_resolve_context(current, fsuse->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2332,7 +2305,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_sidcontext(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_sidcontext *sidcon = current->data;
 	struct cil_symtab_datum *sid_datum = NULL;
@@ -2341,20 +2314,20 @@ int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args)
 
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, sidcon->sid_str, CIL_SYM_SIDS, extra_args, &sid_datum);
+	rc = cil_resolve_name(current, sidcon->sid_str, CIL_SYM_SIDS, db, &sid_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
 	sid = (struct cil_sid*)sid_datum;
 
 	if (sidcon->context_str != NULL) {
-		rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum);
+		rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
 		sidcon->context = (struct cil_context*)context_datum;
 	} else if (sidcon->context != NULL) {
-		rc = cil_resolve_context(current, sidcon->context, extra_args);
+		rc = cil_resolve_context(current, sidcon->context, db);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2374,14 +2347,14 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_blockinherit_link(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_blockinherit_link(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_blockinherit *inherit = current->data;
 	struct cil_symtab_datum *block_datum = NULL;
 	struct cil_tree_node *node = NULL;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
+	rc = cil_resolve_name(current, inherit->block_str, CIL_SYM_BLOCKS, db, &block_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -2407,11 +2380,9 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_blockinherit_copy(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_block *block = current->data;
-	struct cil_args_resolve *args = extra_args;
-	struct cil_db *db = NULL;
 	struct cil_list_item *item = NULL;
 	int rc = SEPOL_ERR;
 
@@ -2421,8 +2392,6 @@ static int cil_resolve_blockinherit_copy(struct cil_tree_node *current, void *ex
 		goto exit;
 	}
 
-	db = args->db;
-
 	// Make sure this is the original block and not a merged block from a blockinherit
 	if (current != block->datum.nodes->head->data) {
 		rc = SEPOL_OK;
@@ -2456,15 +2425,14 @@ static void cil_mark_subtree_abstract(struct cil_tree_node *node)
 	}
 }
 
-static int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_blockabstract(struct cil_tree_node *current, struct cil_db *db, struct cil_list *abstract_blocks)
 {
 	struct cil_blockabstract *abstract = current->data;
 	struct cil_symtab_datum *block_datum = NULL;
 	struct cil_tree_node *block_node = NULL;
-	struct cil_args_resolve *args = extra_args;
 	int rc = SEPOL_ERR;
 
-	rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
+	rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, db, &block_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -2476,7 +2444,7 @@ static int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_
 		goto exit;
 	}
 
-	cil_list_append(args->abstract_blocks, CIL_NODE, block_node);
+	cil_list_append(abstract_blocks, CIL_NODE, block_node);
 
 	return SEPOL_OK;
 
@@ -2484,20 +2452,14 @@ exit:
 	return rc;
 }
 
-int cil_resolve_in(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_in(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_in *in = current->data;
-	struct cil_args_resolve *args = extra_args;
-	struct cil_db *db = NULL;
 	struct cil_symtab_datum *block_datum = NULL;
 	struct cil_tree_node *block_node = NULL;
 	int rc = SEPOL_ERR;
 
-	if (args != NULL) {
-		db = args->db;
-	}
-
-	rc = cil_resolve_name(current, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
+	rc = cil_resolve_name(current, in->block_str, CIL_SYM_BLOCKS, db, &block_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -2527,7 +2489,7 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_in_list(struct cil_list *in_list, void *extra_args)
+static int cil_resolve_in_list(struct cil_list *in_list, struct cil_db *db)
 {
 	struct cil_list_item *curr = NULL;
 	struct cil_tree_node *node = NULL;
@@ -2550,12 +2512,12 @@ static int cil_resolve_in_list(struct cil_list *in_list, void *extra_args)
 			node = curr->data;
 			in = node->data;
 
-			rc = cil_resolve_name(node, in->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
+			rc = cil_resolve_name(node, in->block_str, CIL_SYM_BLOCKS, db, &block_datum);
 			if (rc != SEPOL_OK) {
 				unresolved++;
 				last_failed_node = node;
 			} else {
-				rc = cil_resolve_in(node, extra_args);
+				rc = cil_resolve_in(node, db);
 				if (rc != SEPOL_OK) {
 					goto exit;
 				}
@@ -2581,7 +2543,7 @@ exit:
 }
 
 
-static int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor attr_flavor)
+static int cil_resolve_bounds(struct cil_tree_node *current, struct cil_db *db, enum cil_flavor flavor, enum cil_flavor attr_flavor)
 {
 	int rc = SEPOL_ERR;
 	struct cil_bounds *bounds = current->data;
@@ -2594,7 +2556,7 @@ static int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, e
 		goto exit;
 	}
 
-	rc = cil_resolve_name(current, bounds->parent_str, index, extra_args, &parent_datum);
+	rc = cil_resolve_name(current, bounds->parent_str, index, db, &parent_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -2605,7 +2567,7 @@ static int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, e
 	}
 
 
-	rc = cil_resolve_name(current, bounds->child_str, index, extra_args, &child_datum);
+	rc = cil_resolve_name(current, bounds->child_str, index, db, &child_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -2663,7 +2625,7 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_default(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_default(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_default *def = current->data;
@@ -2673,7 +2635,7 @@ static int cil_resolve_default(struct cil_tree_node *current, void *extra_args)
 	cil_list_init(&def->class_datums, def->flavor);
 
 	cil_list_for_each(curr, def->class_strs) {
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, db, &datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2686,7 +2648,7 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_defaultrange(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_defaultrange(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_defaultrange *def = current->data;
@@ -2696,7 +2658,7 @@ static int cil_resolve_defaultrange(struct cil_tree_node *current, void *extra_a
 	cil_list_init(&def->class_datums, CIL_DEFAULTRANGE);
 
 	cil_list_for_each(curr, def->class_strs) {
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, extra_args, &datum);
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CLASSES, db, &datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
@@ -2781,9 +2743,8 @@ exit:
 	return rc;
 }
 
-static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, void *extra_args)
+static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, struct cil_db *db)
 {
-	struct cil_args_resolve *args = extra_args;
 	struct cil_list_item *item;
 	struct cil_args *arg = NULL;
 	struct cil_tree_node *arg_node = NULL;
@@ -2830,7 +2791,7 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
 				rc = SEPOL_ERR;
 				goto exit;
 			}
-			name = __cil_insert_name(args->db, arg_node->data, call_node);
+			name = __cil_insert_name(db, arg_node->data, call_node);
 			if (name != NULL) {
 				arg->arg = (struct cil_symtab_datum *)name;
 			} else {
@@ -3080,10 +3041,9 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_call(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_call(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_call *call = current->data;
-	struct cil_args_resolve *args = extra_args;
 	struct cil_tree_node *macro_node = NULL;
 	struct cil_symtab_datum *macro_datum = NULL;
 	int rc = SEPOL_ERR;
@@ -3092,7 +3052,7 @@ static int cil_resolve_call(struct cil_tree_node *current, void *extra_args)
 		return SEPOL_OK;
 	}
 
-	rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, extra_args, &macro_datum);
+	rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, db, &macro_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3106,7 +3066,7 @@ static int cil_resolve_call(struct cil_tree_node *current, void *extra_args)
 	}
 	call->macro = (struct cil_macro*)macro_datum;
 
-	rc = cil_build_call_args(current, call, call->macro, extra_args);
+	rc = cil_build_call_args(current, call, call->macro, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3116,7 +3076,7 @@ static int cil_resolve_call(struct cil_tree_node *current, void *extra_args)
 		goto exit;
 	}
 
-	rc = cil_copy_ast(args->db, macro_node, current);
+	rc = cil_copy_ast(db, macro_node, current);
 	if (rc != SEPOL_OK) {
 		cil_tree_log(current, CIL_ERR, "Failed to copy macro %s to call", macro_datum->name);
 		goto exit;
@@ -3130,7 +3090,7 @@ exit:
 	return rc;
 }
 
-static int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args)
+static int cil_resolve_call_args(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_call *call = current->data;
 	int rc = SEPOL_ERR;
@@ -3227,7 +3187,7 @@ static int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args
 		if (sym_index != CIL_SYM_UNKNOWN) {
 			struct cil_symtab_datum *datum;
 			struct cil_tree_node *n;
-			rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &datum);
+			rc = cil_resolve_name(current, arg->arg_str, sym_index, db, &datum);
 			if (rc != SEPOL_OK) {
 				cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
 				goto exit;
@@ -3242,7 +3202,7 @@ static int cil_resolve_call_args(struct cil_tree_node *current, void *extra_args
 					 * the call.
 					 */
 					cil_symtab_remove_datum(datum);
-					rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
+					rc = cil_resolve_name(current, arg->arg_str, sym_index, db, &(arg->arg));
 					if (rc != SEPOL_OK) {
 						cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
 						goto exit;
@@ -3297,7 +3257,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, void *extra_args)
+int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_list_item *curr;
@@ -3334,7 +3294,7 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc
 	cil_list_for_each(curr, str_expr) {
 		switch (curr->flavor) {
 		case CIL_STRING:
-			rc = cil_resolve_name(parent, curr->data, sym_index, extra_args, &res_datum);
+			rc = cil_resolve_name(parent, curr->data, sym_index, db, &res_datum);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -3348,7 +3308,7 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc
 				if (!res_datum->name) {
 					/* Anonymous category sets need to be resolved when encountered */
 					if (!catset->cats->datum_expr) {
-						rc = cil_resolve_expr(expr_type, catset->cats->str_expr, &catset->cats->datum_expr, parent, extra_args);
+						rc = cil_resolve_expr(expr_type, catset->cats->str_expr, &catset->cats->datum_expr, parent, db);
 						if (rc != SEPOL_OK) {
 							goto exit;
 						}
@@ -3366,7 +3326,7 @@ int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struc
 			}
 			break;
 		case CIL_LIST: {
-			rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, extra_args);
+			rc = cil_resolve_expr(expr_type, curr->data, &datum_sub_expr, parent, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -3388,12 +3348,12 @@ exit:
 	return rc;
 }
 
-int cil_resolve_boolif(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_boolif(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_booleanif *bif = (struct cil_booleanif*)current->data;
 
-	rc = cil_resolve_expr(CIL_BOOLEANIF, bif->str_expr, &bif->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_BOOLEANIF, bif->str_expr, &bif->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3453,10 +3413,8 @@ static int __cil_evaluate_tunable_expr(struct cil_list_item *curr)
 	}
 }
 
-int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_tunif(struct cil_tree_node *current, struct cil_db *db)
 {
-	struct cil_args_resolve *args = extra_args;
-	struct cil_db *db = NULL;
 	int rc = SEPOL_ERR;
 	struct cil_tunableif *tif = (struct cil_tunableif*)current->data;
 	uint16_t result = CIL_FALSE;
@@ -3464,11 +3422,7 @@ int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args)
 	struct cil_tree_node *false_node = NULL;
 	struct cil_condblock *cb = NULL;
 
-	if (args != NULL) {
-		db = args->db;
-	}
-
-	rc = cil_resolve_expr(CIL_TUNABLEIF, tif->str_expr, &tif->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_TUNABLEIF, tif->str_expr, &tif->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3519,7 +3473,7 @@ exit:
 	return rc;
 }
 
-int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args)
+int cil_resolve_userattributeset(struct cil_tree_node *current, struct cil_db *db)
 {
 	int rc = SEPOL_ERR;
 	struct cil_userattributeset *attrusers = current->data;
@@ -3527,7 +3481,7 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args
 	struct cil_tree_node *attr_node = NULL;
 	struct cil_userattribute *attr = NULL;
 
-	rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, extra_args, &attr_datum);
+	rc = cil_resolve_name(current, attrusers->attr_str, CIL_SYM_USERS, db, &attr_datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3540,7 +3494,7 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args
 	}
 	attr = (struct cil_userattribute*)attr_datum;
 
-	rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, extra_args);
+	rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
 	return rc;
 }
 
-static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
+static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
 {
 	int rc = SEPOL_OK;
-	struct cil_args_resolve *args = extra_args;
+	struct cil_db *db = args->db;
 	enum cil_pass pass = 0;
 
-	if (node == NULL || args == NULL) {
-		goto exit;
-	}
-
 	pass = args->pass;
 	switch (pass) {
 	case CIL_PASS_TIF:
 		if (node->flavor == CIL_TUNABLEIF) {
-			rc = cil_resolve_tunif(node, args);
+			rc = cil_resolve_tunif(node, db);
 		}
 		break;
 	case CIL_PASS_IN_BEFORE:
@@ -3690,17 +3640,17 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 		break;
 	case CIL_PASS_BLKIN_LINK:
 		if (node->flavor == CIL_BLOCKINHERIT) {
-			rc = cil_resolve_blockinherit_link(node, args);
+			rc = cil_resolve_blockinherit_link(node, db);
 		}
 		break;
 	case CIL_PASS_BLKIN_COPY:
 		if (node->flavor == CIL_BLOCK) {
-			rc = cil_resolve_blockinherit_copy(node, args);
+			rc = cil_resolve_blockinherit_copy(node, db);
 		}
 		break;
 	case CIL_PASS_BLKABS:
 		if (node->flavor == CIL_BLOCKABSTRACT) {
-			rc = cil_resolve_blockabstract(node, args);
+			rc = cil_resolve_blockabstract(node, db, args->abstract_blocks);
 		}
 		break;
 	case CIL_PASS_IN_AFTER:
@@ -3715,24 +3665,24 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 		break;
 	case CIL_PASS_CALL1:
 		if (node->flavor == CIL_CALL && args->macro == NULL) {
-			rc = cil_resolve_call(node, args);
+			rc = cil_resolve_call(node, db);
 		}
 		break;
 	case CIL_PASS_CALL2:
 		if (node->flavor == CIL_CALL && args->macro == NULL) {
-			rc = cil_resolve_call_args(node, args);
+			rc = cil_resolve_call_args(node, db);
 		}
 		break;
 	case CIL_PASS_ALIAS1:
 		switch (node->flavor) {
 		case CIL_TYPEALIASACTUAL:
-			rc = cil_resolve_aliasactual(node, args, CIL_TYPE, CIL_TYPEALIAS);
+			rc = cil_resolve_aliasactual(node, db, CIL_TYPE, CIL_TYPEALIAS);
 			break;
 		case CIL_SENSALIASACTUAL:
-			rc = cil_resolve_aliasactual(node, args, CIL_SENS, CIL_SENSALIAS);
+			rc = cil_resolve_aliasactual(node, db, CIL_SENS, CIL_SENSALIAS);
 			break;
 		case CIL_CATALIASACTUAL:
-			rc = cil_resolve_aliasactual(node, args, CIL_CAT, CIL_CATALIAS);
+			rc = cil_resolve_aliasactual(node, db, CIL_CAT, CIL_CATALIAS);
 			break;
 		default: 
 			break;
@@ -3756,19 +3706,19 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 	case CIL_PASS_MISC1:
 		switch (node->flavor) {
 		case CIL_SIDORDER:
-			rc = cil_resolve_sidorder(node, args);
+			rc = cil_resolve_sidorder(node, db, args->sidorder_lists);
 			break;
 		case CIL_CLASSORDER:
-			rc = cil_resolve_classorder(node, args);
+			rc = cil_resolve_classorder(node, db, args->classorder_lists, args->unordered_classorder_lists);
 			break;
 		case CIL_CATORDER:
-			rc = cil_resolve_catorder(node, args);
+			rc = cil_resolve_catorder(node, db, args->catorder_lists);
 			break;
 		case CIL_SENSITIVITYORDER:
-			rc = cil_resolve_sensitivityorder(node, args);
+			rc = cil_resolve_sensitivityorder(node, db, args->sensitivityorder_lists);
 			break;
 		case CIL_BOOLEANIF:
-			rc = cil_resolve_boolif(node, args);
+			rc = cil_resolve_boolif(node, db);
 			break;
 		default:
 			break;
@@ -3777,7 +3727,7 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 	case CIL_PASS_MLS:
 		switch (node->flavor) {
 		case CIL_CATSET:
-			rc = cil_resolve_catset(node, (struct cil_catset*)node->data, args);
+			rc = cil_resolve_catset(node, (struct cil_catset*)node->data, db);
 			break;
 		default:
 			break;
@@ -3786,10 +3736,10 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 	case CIL_PASS_MISC2:
 		switch (node->flavor) {
 		case CIL_SENSCAT:
-			rc = cil_resolve_senscat(node, args);
+			rc = cil_resolve_senscat(node, db);
 			break;
 		case CIL_CLASSCOMMON:
-			rc = cil_resolve_classcommon(node, args);
+			rc = cil_resolve_classcommon(node, db);
 			break;
 		default:
 			break;
@@ -3798,147 +3748,147 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 	case CIL_PASS_MISC3:
 		switch (node->flavor) {
 		case CIL_TYPEATTRIBUTESET:
-			rc = cil_resolve_typeattributeset(node, args);
+			rc = cil_resolve_typeattributeset(node, db);
 			break;
 		case CIL_EXPANDTYPEATTRIBUTE:
-			rc = cil_resolve_expandtypeattribute(node, args);
+			rc = cil_resolve_expandtypeattribute(node, db);
 			break;
 		case CIL_TYPEBOUNDS:
-			rc = cil_resolve_bounds(node, args, CIL_TYPE, CIL_TYPEATTRIBUTE);
+			rc = cil_resolve_bounds(node, db, CIL_TYPE, CIL_TYPEATTRIBUTE);
 			break;
 		case CIL_TYPEPERMISSIVE:
-			rc = cil_resolve_typepermissive(node, args);
+			rc = cil_resolve_typepermissive(node, db);
 			break;
 		case CIL_NAMETYPETRANSITION:
-			rc = cil_resolve_nametypetransition(node, args);
+			rc = cil_resolve_nametypetransition(node, db);
 			break;
 		case CIL_RANGETRANSITION:
-			rc = cil_resolve_rangetransition(node, args);
+			rc = cil_resolve_rangetransition(node, db);
 			break;
 		case CIL_CLASSPERMISSIONSET:
-			rc = cil_resolve_classpermissionset(node, (struct cil_classpermissionset*)node->data, args);
+			rc = cil_resolve_classpermissionset(node, (struct cil_classpermissionset*)node->data, db);
 			break;
 		case CIL_CLASSMAPPING:
-			rc = cil_resolve_classmapping(node, args);
+			rc = cil_resolve_classmapping(node, db);
 			break;
 		case CIL_AVRULE:
 		case CIL_AVRULEX:
-			rc = cil_resolve_avrule(node, args);
+			rc = cil_resolve_avrule(node, db);
 			break;
 		case CIL_PERMISSIONX:
-			rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, args);
+			rc = cil_resolve_permissionx(node, (struct cil_permissionx*)node->data, db);
 			break;
 		case CIL_DENY_RULE:
-			rc = cil_resolve_deny_rule(node, args);
+			rc = cil_resolve_deny_rule(node, db);
 			break;
 		case CIL_TYPE_RULE:
-			rc = cil_resolve_type_rule(node, args);
+			rc = cil_resolve_type_rule(node, db);
 			break;
 		case CIL_USERROLE:
-			rc = cil_resolve_userrole(node, args);
+			rc = cil_resolve_userrole(node, db);
 			break;
 		case CIL_USERLEVEL:
-			rc = cil_resolve_userlevel(node, args);
+			rc = cil_resolve_userlevel(node, db);
 			break;
 		case CIL_USERRANGE:
-			rc = cil_resolve_userrange(node, args);
+			rc = cil_resolve_userrange(node, db);
 			break;
 		case CIL_USERBOUNDS:
-			rc = cil_resolve_bounds(node, args, CIL_USER, CIL_USERATTRIBUTE);
+			rc = cil_resolve_bounds(node, db, CIL_USER, CIL_USERATTRIBUTE);
 			break;
 		case CIL_USERPREFIX:
-			rc = cil_resolve_userprefix(node, args);
+			rc = cil_resolve_userprefix(node, db);
 			break;
 		case CIL_SELINUXUSER:
 		case CIL_SELINUXUSERDEFAULT:
-			rc = cil_resolve_selinuxuser(node, args);
+			rc = cil_resolve_selinuxuser(node, db);
 			break;
 		case CIL_ROLEATTRIBUTESET:
-			rc = cil_resolve_roleattributeset(node, args);
+			rc = cil_resolve_roleattributeset(node, db);
 			break;
 		case CIL_ROLETYPE:
-			rc = cil_resolve_roletype(node, args);
+			rc = cil_resolve_roletype(node, db);
 			break;
 		case CIL_ROLETRANSITION:
-			rc = cil_resolve_roletransition(node, args);
+			rc = cil_resolve_roletransition(node, db);
 			break;
 		case CIL_ROLEALLOW:
-			rc = cil_resolve_roleallow(node, args);
+			rc = cil_resolve_roleallow(node, db);
 			break;
 		case CIL_ROLEBOUNDS:
-			rc = cil_resolve_bounds(node, args, CIL_ROLE, CIL_ROLEATTRIBUTE);
+			rc = cil_resolve_bounds(node, db, CIL_ROLE, CIL_ROLEATTRIBUTE);
 			break;
 		case CIL_LEVEL:
-			rc = cil_resolve_level(node, (struct cil_level*)node->data, args);
+			rc = cil_resolve_level(node, (struct cil_level*)node->data, db);
 			break;
 		case CIL_LEVELRANGE:
-			rc = cil_resolve_levelrange(node, (struct cil_levelrange*)node->data, args);
+			rc = cil_resolve_levelrange(node, (struct cil_levelrange*)node->data, db);
 			break;
 		case CIL_CONSTRAIN:
-			rc = cil_resolve_constrain(node, args);
+			rc = cil_resolve_constrain(node, db);
 			break;
 		case CIL_MLSCONSTRAIN:
-			rc = cil_resolve_constrain(node, args);
+			rc = cil_resolve_constrain(node, db);
 			break;
 		case CIL_VALIDATETRANS:
 		case CIL_MLSVALIDATETRANS:
-			rc = cil_resolve_validatetrans(node, args);
+			rc = cil_resolve_validatetrans(node, db);
 			break;
 		case CIL_CONTEXT:
-			rc = cil_resolve_context(node, (struct cil_context*)node->data, args);
+			rc = cil_resolve_context(node, (struct cil_context*)node->data, db);
 			break;
 		case CIL_FILECON:
-			rc = cil_resolve_filecon(node, args);
+			rc = cil_resolve_filecon(node, db);
 			break;
 		case CIL_IBPKEYCON:
-			rc = cil_resolve_ibpkeycon(node, args);
+			rc = cil_resolve_ibpkeycon(node, db);
 			break;
 		case CIL_PORTCON:
-			rc = cil_resolve_portcon(node, args);
+			rc = cil_resolve_portcon(node, db);
 			break;
 		case CIL_NODECON:
-			rc = cil_resolve_nodecon(node, args);
+			rc = cil_resolve_nodecon(node, db);
 			break;
 		case CIL_GENFSCON:
-			rc = cil_resolve_genfscon(node, args);
+			rc = cil_resolve_genfscon(node, db);
 			break;
 		case CIL_NETIFCON:
-			rc = cil_resolve_netifcon(node, args);
+			rc = cil_resolve_netifcon(node, db);
 			break;
 		case CIL_IBENDPORTCON:
-			rc = cil_resolve_ibendportcon(node, args);
+			rc = cil_resolve_ibendportcon(node, db);
 			break;
 		case CIL_PIRQCON:
-			rc = cil_resolve_pirqcon(node, args);
+			rc = cil_resolve_pirqcon(node, db);
 			break;
 		case CIL_IOMEMCON:
-			rc = cil_resolve_iomemcon(node, args);
+			rc = cil_resolve_iomemcon(node, db);
 			break;
 		case CIL_IOPORTCON:
-			rc = cil_resolve_ioportcon(node, args);
+			rc = cil_resolve_ioportcon(node, db);
 			break;
 		case CIL_PCIDEVICECON:
-			rc = cil_resolve_pcidevicecon(node, args);
+			rc = cil_resolve_pcidevicecon(node, db);
 			break;
 		case CIL_DEVICETREECON:
-			rc = cil_resolve_devicetreecon(node, args);
+			rc = cil_resolve_devicetreecon(node, db);
 			break;
 		case CIL_FSUSE:
-			rc = cil_resolve_fsuse(node, args);
+			rc = cil_resolve_fsuse(node, db);
 			break;
 		case CIL_SIDCONTEXT:
-			rc = cil_resolve_sidcontext(node, args);
+			rc = cil_resolve_sidcontext(node, db);
 			break;
 		case CIL_DEFAULTUSER:
 		case CIL_DEFAULTROLE:
 		case CIL_DEFAULTTYPE:
-			rc = cil_resolve_default(node, args);
+			rc = cil_resolve_default(node, db);
 			break;
 		case CIL_DEFAULTRANGE:
-			rc = cil_resolve_defaultrange(node, args);
+			rc = cil_resolve_defaultrange(node, db);
 			break;
 		case CIL_USERATTRIBUTESET:
-			rc = cil_resolve_userattributeset(node, args);
+			rc = cil_resolve_userattributeset(node, db);
 			break;
 		default:
 			break;
@@ -3949,9 +3899,6 @@ static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
 	}
 
 	return rc;
-
-exit:
-	return rc;
 }
 
 static int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args)
@@ -4040,7 +3987,7 @@ static int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *f
 		goto exit;
 	}
 
-	rc = __cil_resolve_ast_node(node, extra_args);
+	rc = __cil_resolve_ast_node(node, args);
 	if (rc == SEPOL_ENOENT) {
 		if (optional == NULL) {
 			cil_tree_log(node, CIL_ERR, "Failed to resolve %s statement", cil_node_to_string(node));
@@ -4186,13 +4133,13 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
 		}
 
 		if (pass == CIL_PASS_IN_BEFORE) {
-			rc = cil_resolve_in_list(extra_args.in_list_before, &extra_args);
+			rc = cil_resolve_in_list(extra_args.in_list_before, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
 			cil_list_destroy(&extra_args.in_list_before, CIL_FALSE);
 		} else if (pass == CIL_PASS_IN_AFTER) {
-			rc = cil_resolve_in_list(extra_args.in_list_after, &extra_args);
+			rc = cil_resolve_in_list(extra_args.in_list_after, db);
 			if (rc != SEPOL_OK) {
 				goto exit;
 			}
@@ -4413,12 +4360,12 @@ static int __cil_resolve_name_helper(struct cil_db *db, struct cil_tree_node *no
 	return rc;
 }
 
-int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum)
+int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, struct cil_db *db, struct cil_symtab_datum **datum)
 {
 	int rc = SEPOL_ERR;
 	struct cil_tree_node *node = NULL;
 
-	rc = cil_resolve_name_keep_aliases(ast_node, name, sym_index, extra_args, datum);
+	rc = cil_resolve_name_keep_aliases(ast_node, name, sym_index, db, datum);
 	if (rc != SEPOL_OK) {
 		goto exit;
 	}
@@ -4441,11 +4388,9 @@ exit:
 	return rc;
 }
 
-int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum)
+int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, struct cil_db *db, struct cil_symtab_datum **datum)
 {
 	int rc = SEPOL_ERR;
-	struct cil_args_resolve *args = extra_args;
-	struct cil_db *db = args->db;
 	struct cil_tree_node *node = NULL;
 
 	if (name == NULL) {
diff --git a/libsepol/cil/src/cil_resolve_ast.h b/libsepol/cil/src/cil_resolve_ast.h
index 78357993..2f6b7e86 100644
--- a/libsepol/cil/src/cil_resolve_ast.h
+++ b/libsepol/cil/src/cil_resolve_ast.h
@@ -35,71 +35,71 @@
 #include "cil_internal.h"
 #include "cil_tree.h"
 
-int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, void *extra_args);
-int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, void *extra_args);
-int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, void *extra_args);
-int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_deny_rule(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_type_rule(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_typeattributeset(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_typealias(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_typebounds(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_typepermissive(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_rangetransition(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_classmapping(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_userrole(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_userlevel(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_userrange(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_userbounds(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_userprefix(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_userattributeset(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_selinuxuser(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_roletype(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_roletransition(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_roleallow(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_roleattributeset(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_rolebounds(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_sensalias(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_catalias(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_catorder(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_sensitivityorder(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_cat_list(struct cil_tree_node *current, struct cil_list *cat_list, struct cil_list *res_cat_list, void *extra_args);
-int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, void *extra_args);
-int cil_resolve_senscat(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, void *extra_args); 
-int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *levelrange, void *extra_args); 
-int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args);
-int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_netifcon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_iomemcon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_ioportcon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_pcidevicecon(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_sidcontext(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_sidorder(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_blockinherit(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_in(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_call1(struct cil_tree_node *current, void *extra_args);
-int cil_resolve_call2(struct cil_tree_node *, void *extra_args);
+int cil_resolve_classorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *classorder_list, struct cil_list *unordered_classorder_list);
+int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms *cp, struct cil_db *db);
+int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_classpermissionset *cps, struct cil_db *db);
+int cil_resolve_classperms_list(struct cil_tree_node *current, struct cil_list *cp_list, struct cil_db *db);
+int cil_resolve_avrule(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_deny_rule(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_type_rule(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_typeattributeset(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_typealias(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_typebounds(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_typepermissive(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_nametypetransition(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_rangetransition(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_classcommon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_classmapping(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_userrole(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_userlevel(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_userrange(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_userbounds(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_userprefix(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_userattributeset(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_selinuxuser(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_roletype(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_roletransition(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_roleallow(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_roleattributeset(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_rolebounds(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_sensalias(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_catalias(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_catorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *catorder_list);
+int cil_resolve_sensitivityorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sensitivityorder_list);
+int cil_resolve_cat_list(struct cil_tree_node *current, struct cil_list *cat_list, struct cil_list *res_cat_list, struct cil_db *db);
+int cil_resolve_catset(struct cil_tree_node *current, struct cil_catset *catset, struct cil_db *db);
+int cil_resolve_senscat(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_level(struct cil_tree_node *current, struct cil_level *level, struct cil_db *db);
+int cil_resolve_levelrange(struct cil_tree_node *current, struct cil_levelrange *levelrange, struct cil_db *db);
+int cil_resolve_constrain(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_validatetrans(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, struct cil_db *db);
+int cil_resolve_filecon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_ibpkeycon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_ibendportcon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_portcon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_genfscon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_nodecon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_netifcon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_pirqcon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_iomemcon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_ioportcon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_pcidevicecon(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_fsuse(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_sidcontext(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_sidorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sidorder_list);
+int cil_resolve_blockinherit(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_in(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_call1(struct cil_tree_node *current, struct cil_db *db);
+int cil_resolve_call2(struct cil_tree_node *, struct cil_db *db);
 int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum);
-int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, void *extra_args);
-int cil_resolve_boolif(struct cil_tree_node *current, void *extra_args);
+int cil_resolve_expr(enum cil_flavor expr_type, struct cil_list *str_expr, struct cil_list **datum_expr, struct cil_tree_node *parent, struct cil_db *db);
+int cil_resolve_boolif(struct cil_tree_node *current, struct cil_db *db);
 int cil_evaluate_expr(struct cil_list *datum_expr, uint16_t *result);
-int cil_resolve_tunif(struct cil_tree_node *current, void *extra_args);
+int cil_resolve_tunif(struct cil_tree_node *current, struct cil_db *db);
 
 int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current);
-int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum);
-int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, void *extra_args, struct cil_symtab_datum **datum);
+int cil_resolve_name(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, struct cil_db *db, struct cil_symtab_datum **datum);
+int cil_resolve_name_keep_aliases(struct cil_tree_node *ast_node, char *name, enum cil_sym_index sym_index, struct cil_db *db, struct cil_symtab_datum **datum);
 
 #endif /* CIL_RESOLVE_AST_H_ */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/9] libsepol/cil: Refactor and improve handling of order rules
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
  2023-09-27 19:00 ` [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void * James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 3/9] libsepol/cil: Allow IP address and mask values to be directly written James Carter
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

Use the same common structure for the ordering rules (classorder,
sidorder, sensitivityorder, and categoryorder). This removes code
duplication and makes it easier to write out the CIL AST.

Simplify the merging of multiple order rules.

Add a verification that checks that the final merged ordering is
fully specified and without ambiguity.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil.c             |  44 ++--
 libsepol/cil/src/cil_build_ast.c   | 333 +++++++----------------------
 libsepol/cil/src/cil_build_ast.h   |  10 +-
 libsepol/cil/src/cil_copy_ast.c    |  86 ++------
 libsepol/cil/src/cil_copy_ast.h    |   5 +-
 libsepol/cil/src/cil_internal.h    |  27 +--
 libsepol/cil/src/cil_reset_ast.c   |  16 +-
 libsepol/cil/src/cil_resolve_ast.c | 315 ++++++++++-----------------
 libsepol/cil/src/cil_verify.c      |  72 +++++++
 libsepol/cil/src/cil_verify.h      |   1 +
 libsepol/cil/src/cil_write_ast.c   |  32 ++-
 11 files changed, 347 insertions(+), 594 deletions(-)

diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 2021187d..46477d0e 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -837,7 +837,7 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 		cil_destroy_class(*data);
 		break;
 	case CIL_CLASSORDER:
-		cil_destroy_classorder(*data);
+		cil_destroy_ordered(*data);
 		break;
 	case CIL_CLASSPERMISSION:
 		cil_destroy_classpermission(*data);
@@ -934,7 +934,7 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 		cil_destroy_aliasactual(*data);
 		break;
 	case CIL_SENSITIVITYORDER:
-		cil_destroy_sensitivityorder(*data);
+		cil_destroy_ordered(*data);
 		break;
 	case CIL_SENSCAT:
 		cil_destroy_senscat(*data);
@@ -952,7 +952,7 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 		cil_destroy_aliasactual(*data);
 		break;
 	case CIL_CATORDER:
-		cil_destroy_catorder(*data);
+		cil_destroy_ordered(*data);
 		break;
 	case CIL_LEVEL:
 		cil_destroy_level(*data);
@@ -964,7 +964,7 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 		cil_destroy_sid(*data);
 		break;
 	case CIL_SIDORDER:
-		cil_destroy_sidorder(*data);
+		cil_destroy_ordered(*data);
 		break;
 	case CIL_NAME:
 		cil_destroy_name(*data);
@@ -2164,6 +2164,14 @@ void cil_sort_destroy(struct cil_sort **sort)
 	*sort = NULL;
 }
 
+void cil_ordered_init(struct cil_ordered **ordered)
+{
+	*ordered = cil_malloc(sizeof(**ordered));
+	(*ordered)->merged = CIL_FALSE;
+	(*ordered)->strs = NULL;
+	(*ordered)->datums = NULL;
+}
+
 void cil_netifcon_init(struct cil_netifcon **netifcon)
 {
 	*netifcon = cil_malloc(sizeof(**netifcon));
@@ -2281,13 +2289,6 @@ void cil_class_init(struct cil_class **class)
 	(*class)->ordered = CIL_FALSE;
 }
 
-void cil_classorder_init(struct cil_classorder **classorder)
-{
-	*classorder = cil_malloc(sizeof(**classorder));
-
-	(*classorder)->class_list_str = NULL;
-}
-
 void cil_classcommon_init(struct cil_classcommon **classcommon)
 {
 	*classcommon = cil_malloc(sizeof(**classcommon));
@@ -2315,13 +2316,6 @@ void cil_sidcontext_init(struct cil_sidcontext **sidcontext)
 	(*sidcontext)->context = NULL;
 }
 
-void cil_sidorder_init(struct cil_sidorder **sidorder)
-{
-	*sidorder = cil_malloc(sizeof(**sidorder));
-
-	(*sidorder)->sid_list_str = NULL;
-}
-
 void cil_userrole_init(struct cil_userrole **userrole)
 {
 	*userrole = cil_malloc(sizeof(**userrole));
@@ -2877,20 +2871,6 @@ void cil_cat_init(struct cil_cat **cat)
 	(*cat)->value = 0;
 }
 
-void cil_catorder_init(struct cil_catorder **catorder)
-{
-	*catorder = cil_malloc(sizeof(**catorder));
-
-	(*catorder)->cat_list_str = NULL;
-}
-
-void cil_sensorder_init(struct cil_sensorder **sensorder)
-{
-	*sensorder = cil_malloc(sizeof(**sensorder));
-
-	(*sensorder)->sens_list_str = NULL;
-}
-
 void cil_args_init(struct cil_args **args)
 {
 	*args = cil_malloc(sizeof(**args));
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index 8976c254..efe1601c 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -186,6 +186,83 @@ static void cil_clear_node(struct cil_tree_node *ast_node)
 	ast_node->flavor = CIL_NONE;
 }
 
+int cil_gen_ordered(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor)
+{
+	enum cil_syntax syntax[] = {
+		CIL_SYN_STRING,
+		CIL_SYN_LIST,
+		CIL_SYN_END
+	};
+	size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
+	struct cil_ordered *ordered = NULL;
+	struct cil_list_item *curr = NULL;
+
+	int rc = SEPOL_ERR;
+
+	if (db == NULL || parse_current == NULL || ast_node == NULL) {
+		goto exit;
+	}
+
+	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
+	if (rc !=  SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_ordered_init(&ordered);
+
+	rc = cil_fill_list(parse_current->next->cl_head, flavor, &ordered->strs);
+	if (rc != SEPOL_OK) {
+		goto exit;
+	}
+
+	cil_list_for_each(curr, ordered->strs) {
+		if (curr->data == CIL_KEY_UNORDERED) {
+			if (flavor == CIL_CLASSORDER) {
+				if (curr == ordered->strs->head && curr->next == NULL) {
+					cil_log(CIL_ERR, "classorder 'unordered' keyword must be followed by one or more class.\n");
+					rc = SEPOL_ERR;
+					goto exit;
+				} else if (curr != ordered->strs->head) {
+					cil_log(CIL_ERR, "classorder can only use 'unordered' keyword as the first item in the list.\n");
+					rc = SEPOL_ERR;
+					goto exit;
+				}
+			} else {
+				cil_log(CIL_ERR, "The 'unordered' keyword can only be used with classorder rules.\n");
+				rc = SEPOL_ERR;
+				goto exit;
+			}
+		}
+	}
+
+	ast_node->data = ordered;
+	ast_node->flavor = flavor;
+
+	return SEPOL_OK;
+
+exit:
+	cil_tree_log(parse_current, CIL_ERR, "Bad ordered declaration");
+	cil_destroy_ordered(ordered);
+	return rc;
+}
+
+void cil_destroy_ordered(struct cil_ordered *ordered)
+{
+	if (ordered == NULL) {
+		return;
+	}
+
+	if (ordered->strs != NULL) {
+		cil_list_destroy(&ordered->strs, CIL_FALSE);
+	}
+	if (ordered->datums != NULL) {
+		cil_list_destroy(&ordered->datums, CIL_FALSE);
+	}
+
+	free(ordered);
+}
+
+
 int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint16_t is_abstract)
 {
 	enum cil_syntax syntax[] = {
@@ -510,74 +587,6 @@ void cil_destroy_class(struct cil_class *class)
 	free(class);
 }
 
-int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
-{
-	enum cil_syntax syntax[] = {
-		CIL_SYN_STRING,
-		CIL_SYN_LIST,
-		CIL_SYN_END
-	};
-	size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
-	struct cil_classorder *classorder = NULL;
-	struct cil_list_item *curr = NULL;
-	struct cil_list_item *head = NULL;
-	int rc = SEPOL_ERR;
-
-	if (db == NULL || parse_current == NULL || ast_node == NULL) {
-		goto exit;
-	}
-
-	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
-	if (rc !=  SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_classorder_init(&classorder);
-
-	rc = cil_fill_list(parse_current->next->cl_head, CIL_CLASSORDER, &classorder->class_list_str);
-	if (rc != SEPOL_OK) {
-		goto exit;
-	}
-
-	head = classorder->class_list_str->head;
-	cil_list_for_each(curr, classorder->class_list_str) {
-		if (curr->data == CIL_KEY_UNORDERED) {
-			if (curr == head && curr->next == NULL) {
-				cil_log(CIL_ERR, "Classorder 'unordered' keyword must be followed by one or more class.\n");
-				rc = SEPOL_ERR;
-				goto exit;
-			} else if (curr != head) {
-				cil_log(CIL_ERR, "Classorder can only use 'unordered' keyword as the first item in the list.\n");
-				rc = SEPOL_ERR;
-				goto exit;
-			}
-		}
-	}
-
-	ast_node->data = classorder;
-	ast_node->flavor = CIL_CLASSORDER;
-
-	return SEPOL_OK;
-
-exit:
-	cil_tree_log(parse_current, CIL_ERR, "Bad classorder declaration");
-	cil_destroy_classorder(classorder);
-	return rc;
-}
-
-void cil_destroy_classorder(struct cil_classorder *classorder)
-{
-	if (classorder == NULL) {
-		return;
-	}
-
-	if (classorder->class_list_str != NULL) {
-		cil_list_destroy(&classorder->class_list_str, 1);
-	}
-
-	free(classorder);
-}
-
 int cil_gen_perm(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms)
 {
 	char *key = NULL;
@@ -1220,66 +1229,6 @@ void cil_destroy_sidcontext(struct cil_sidcontext *sidcon)
 	free(sidcon);
 }
 
-int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
-{
-	enum cil_syntax syntax[] = {
-		CIL_SYN_STRING,
-		CIL_SYN_LIST,
-		CIL_SYN_END
-	};
-	size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
-	struct cil_sidorder *sidorder = NULL;
-	struct cil_list_item *curr = NULL;
-	int rc = SEPOL_ERR;
-
-	if (db == NULL || parse_current == NULL || ast_node == NULL) {
-		goto exit;
-	}
-
-	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
-	if (rc !=  SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_sidorder_init(&sidorder);
-
-	rc = cil_fill_list(parse_current->next->cl_head, CIL_SIDORDER, &sidorder->sid_list_str);
-	if (rc != SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_list_for_each(curr, sidorder->sid_list_str) {
-		if (curr->data == CIL_KEY_UNORDERED) {
-			cil_log(CIL_ERR, "Sidorder cannot be unordered.\n");
-			rc = SEPOL_ERR;
-			goto exit;
-		}
-	}
-
-	ast_node->data = sidorder;
-	ast_node->flavor = CIL_SIDORDER;
-
-	return SEPOL_OK;
-
-exit:
-	cil_tree_log(parse_current, CIL_ERR, "Bad sidorder declaration");
-	cil_destroy_sidorder(sidorder);
-	return rc;
-}
-
-void cil_destroy_sidorder(struct cil_sidorder *sidorder)
-{
-	if (sidorder == NULL) {
-		return;
-	}
-
-	if (sidorder->sid_list_str != NULL) {
-		cil_list_destroy(&sidorder->sid_list_str, 1);
-	}
-
-	free(sidorder);
-}
-
 int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
 {
 	enum cil_syntax syntax[] = {
@@ -3699,126 +3648,6 @@ void cil_destroy_catset(struct cil_catset *catset)
 	free(catset);
 }
 
-int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
-{
-	enum cil_syntax syntax[] = {
-		CIL_SYN_STRING,
-		CIL_SYN_LIST,
-		CIL_SYN_END
-	};
-	size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
-	struct cil_catorder *catorder = NULL;
-	struct cil_list_item *curr = NULL;
-	int rc = SEPOL_ERR;
-
-	if (db == NULL || parse_current == NULL || ast_node == NULL) {
-		goto exit;
-	}
-
-	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
-	if (rc !=  SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_catorder_init(&catorder);
-
-	rc = cil_fill_list(parse_current->next->cl_head, CIL_CATORDER, &catorder->cat_list_str);
-	if (rc != SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_list_for_each(curr, catorder->cat_list_str) {
-		if (curr->data == CIL_KEY_UNORDERED) {
-			cil_log(CIL_ERR, "Category order cannot be unordered.\n");
-			rc = SEPOL_ERR;
-			goto exit;
-		}
-	}
-
-	ast_node->data = catorder;
-	ast_node->flavor = CIL_CATORDER;
-
-	return SEPOL_OK;
-
-exit:
-	cil_tree_log(parse_current, CIL_ERR, "Bad categoryorder declaration");
-	cil_destroy_catorder(catorder);
-	return rc;
-}
-
-void cil_destroy_catorder(struct cil_catorder *catorder)
-{
-	if (catorder == NULL) {
-		return;
-	}
-
-	if (catorder->cat_list_str != NULL) {
-		cil_list_destroy(&catorder->cat_list_str, 1);
-	}
-
-	free(catorder);
-}
-
-int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
-{
-	enum cil_syntax syntax[] = {
-		CIL_SYN_STRING,
-		CIL_SYN_LIST,
-		CIL_SYN_END
-	};
-	size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
-	struct cil_sensorder *sensorder = NULL;
-	struct cil_list_item *curr = NULL;
-	int rc = SEPOL_ERR;
-
-	if (db == NULL || parse_current == NULL || ast_node == NULL) {
-		goto exit;
-	}
-
-	rc = __cil_verify_syntax(parse_current, syntax, syntax_len);
-	if (rc != SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_sensorder_init(&sensorder);
-
-	rc = cil_fill_list(parse_current->next->cl_head, CIL_SENSITIVITYORDER, &sensorder->sens_list_str);
-	if (rc != SEPOL_OK) {
-		goto exit;
-	}
-
-	cil_list_for_each(curr, sensorder->sens_list_str) {
-		if (curr->data == CIL_KEY_UNORDERED) {
-			cil_log(CIL_ERR, "Sensitivity order cannot be unordered.\n");
-			rc = SEPOL_ERR;
-			goto exit;
-		}
-	}
-
-	ast_node->data = sensorder;
-	ast_node->flavor = CIL_SENSITIVITYORDER;
-
-	return SEPOL_OK;
-
-exit:
-	cil_tree_log(parse_current, CIL_ERR, "Bad sensitivityorder declaration");
-	cil_destroy_sensitivityorder(sensorder);
-	return rc;
-}
-
-void cil_destroy_sensitivityorder(struct cil_sensorder *sensorder)
-{
-	if (sensorder == NULL) {
-		return;
-	}
-
-	if (sensorder->sens_list_str != NULL) {
-		cil_list_destroy(&sensorder->sens_list_str, CIL_TRUE);
-	}
-
-	free(sensorder);
-}
-
 int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
 {
 	enum cil_syntax syntax[] = {
@@ -6314,7 +6143,7 @@ static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree
 	} else if (parse_current->data == CIL_KEY_CLASS) {
 		rc = cil_gen_class(db, parse_current, new_ast_node);
 	} else if (parse_current->data == CIL_KEY_CLASSORDER) {
-		rc = cil_gen_classorder(db, parse_current, new_ast_node);
+		rc = cil_gen_ordered(db, parse_current, new_ast_node, CIL_CLASSORDER);
 	} else if (parse_current->data == CIL_KEY_MAP_CLASS) {
 		rc = cil_gen_map_class(db, parse_current, new_ast_node);
 	} else if (parse_current->data == CIL_KEY_CLASSMAPPING) {
@@ -6332,7 +6161,7 @@ static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree
 	} else if (parse_current->data == CIL_KEY_SIDCONTEXT) {
 		rc = cil_gen_sidcontext(db, parse_current, new_ast_node);
 	} else if (parse_current->data == CIL_KEY_SIDORDER) {
-		rc = cil_gen_sidorder(db, parse_current, new_ast_node);
+		rc = cil_gen_ordered(db, parse_current, new_ast_node, CIL_SIDORDER);
 	} else if (parse_current->data == CIL_KEY_USER) {
 		rc = cil_gen_user(db, parse_current, new_ast_node);
 	} else if (parse_current->data == CIL_KEY_USERATTRIBUTE) {
@@ -6446,9 +6275,9 @@ static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree
 	} else if (parse_current->data == CIL_KEY_CATSET) {
 		rc = cil_gen_catset(db, parse_current, new_ast_node);
 	} else if (parse_current->data == CIL_KEY_CATORDER) {
-		rc = cil_gen_catorder(db, parse_current, new_ast_node);
+		rc = cil_gen_ordered(db, parse_current, new_ast_node, CIL_CATORDER);
 	} else if (parse_current->data == CIL_KEY_SENSITIVITYORDER) {
-		rc = cil_gen_sensitivityorder(db, parse_current, new_ast_node);
+		rc = cil_gen_ordered(db, parse_current, new_ast_node, CIL_SENSITIVITYORDER);
 	} else if (parse_current->data == CIL_KEY_SENSCAT) {
 		rc = cil_gen_senscat(db, parse_current, new_ast_node);
 	} else if (parse_current->data == CIL_KEY_LEVEL) {
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index aca84b24..96af3c91 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -42,6 +42,8 @@ int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t ke
 int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor);
 int cil_parse_to_list(struct cil_tree_node *parse_cl_head, struct cil_list *ast_cl, enum cil_flavor flavor);
 
+int cil_gen_ordered(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor);
+void cil_destroy_ordered(struct cil_ordered *ordered);
 int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, uint16_t is_abstract);
 void cil_destroy_block(struct cil_block *block);
 int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
@@ -52,8 +54,6 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci
 void cil_destroy_in(struct cil_in *in);
 int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_class(struct cil_class *class);
-int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
-void cil_destroy_classorder(struct cil_classorder *classorder);
 int cil_gen_perm(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms);
 void cil_destroy_perm(struct cil_perm *perm);
 int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, struct cil_tree_node *ast_node, enum cil_flavor flavor, unsigned int *num_perms);
@@ -78,8 +78,6 @@ int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct c
 void cil_destroy_sid(struct cil_sid *sid);
 int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_sidcontext(struct cil_sidcontext *sidcon);
-int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
-void cil_destroy_sidorder(struct cil_sidorder *sidorder);
 int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_user(struct cil_user *user);
 int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
@@ -158,10 +156,6 @@ int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, str
 void cil_destroy_category(struct cil_cat *cat);
 int cil_set_to_list(struct cil_tree_node *parse_current, struct cil_list *ast_cl);
 void cil_destroy_catset(struct cil_catset *catset);
-int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
-void cil_destroy_catorder(struct cil_catorder *catorder);
-int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
-void cil_destroy_sensitivityorder(struct cil_sensorder *sensorder);
 int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_senscat(struct cil_senscat *senscat);
 int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index bc972f03..735628df 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -97,6 +97,24 @@ static int cil_copy_node(__attribute__((unused)) struct cil_db *db, void *data,
 	return SEPOL_OK;
 }
 
+int cil_copy_ordered(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
+{
+	struct cil_ordered *orig = data;
+	struct cil_ordered *new = NULL;
+
+	cil_ordered_init(&new);
+	if (orig->strs != NULL) {
+		cil_copy_list(orig->strs, &new->strs);
+	}
+	if (orig->datums != NULL) {
+		cil_copy_list(orig->datums, &new->datums);
+	}
+
+	*copy = new;
+
+	return SEPOL_OK;
+}
+
 int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
 {
 	struct cil_block *orig = data;
@@ -261,21 +279,6 @@ int cil_copy_class(__attribute__((unused)) struct cil_db *db, void *data, void *
 	return SEPOL_OK;
 }
 
-int cil_copy_classorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
-{
-	struct cil_classorder *orig = data;
-	struct cil_classorder *new = NULL;
-
-	cil_classorder_init(&new);
-	if (orig->class_list_str != NULL) {
-		cil_copy_list(orig->class_list_str, &new->class_list_str);
-	}
-
-	*copy = new;
-
-	return SEPOL_OK;
-}
-
 int cil_copy_classpermission(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
 {
 	struct cil_classpermission *orig = data;
@@ -368,21 +371,6 @@ int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, __attribute_
 	return SEPOL_OK;
 }
 
-int cil_copy_sidorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
-{
-	struct cil_sidorder *orig = data;
-	struct cil_sidorder *new = NULL;
-
-	cil_sidorder_init(&new);
-	if (orig->sid_list_str != NULL) {
-		cil_copy_list(orig->sid_list_str, &new->sid_list_str);
-	}
-
-	*copy = new;
-
-	return SEPOL_OK;
-}
-
 int cil_copy_user(__attribute__((unused)) struct cil_db *db, void *data, void **copy, symtab_t *symtab)
 {
 	struct cil_user *orig = data;
@@ -969,36 +957,6 @@ int cil_copy_senscat(struct cil_db *db, void *data, void **copy, __attribute__((
 	return SEPOL_OK;
 }
 
-int cil_copy_catorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
-{
-	struct cil_catorder *orig = data;
-	struct cil_catorder *new = NULL;
-
-	cil_catorder_init(&new);
-	if (orig->cat_list_str != NULL) {
-		cil_copy_list(orig->cat_list_str, &new->cat_list_str);
-	}
-
-	*copy = new;
-
-	return SEPOL_OK;
-}
-
-int cil_copy_sensitivityorder(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
-{
-	struct cil_sensorder *orig = data;
-	struct cil_sensorder *new = NULL;
-
-	cil_sensorder_init(&new);
-	if (orig->sens_list_str != NULL) {
-		cil_copy_list(orig->sens_list_str, &new->sens_list_str);
-	}
-
-	*copy = new;
-
-	return SEPOL_OK;
-}
-
 void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new)
 {
 	cil_level_init(new);
@@ -1768,7 +1726,7 @@ static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished
 		copy_func = &cil_copy_class;
 		break;
 	case CIL_CLASSORDER:
-		copy_func = &cil_copy_classorder;
+		copy_func = &cil_copy_ordered;
 		break;
 	case CIL_CLASSPERMISSION:
 		copy_func = &cil_copy_classpermission;
@@ -1786,7 +1744,7 @@ static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished
 		copy_func = &cil_copy_sidcontext;
 		break;
 	case CIL_SIDORDER:
-		copy_func = &cil_copy_sidorder;
+		copy_func = &cil_copy_ordered;
 		break;
 	case CIL_USER:
 		copy_func = &cil_copy_user;
@@ -1907,10 +1865,10 @@ static int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished
 		copy_func = &cil_copy_senscat;
 		break;
 	case CIL_CATORDER:
-		copy_func = &cil_copy_catorder;
+		copy_func = &cil_copy_ordered;
 		break;
 	case CIL_SENSITIVITYORDER:
-		copy_func = &cil_copy_sensitivityorder;
+		copy_func = &cil_copy_ordered;
 		break;
 	case CIL_LEVEL:
 		copy_func = &cil_copy_level;
diff --git a/libsepol/cil/src/cil_copy_ast.h b/libsepol/cil/src/cil_copy_ast.h
index 9f695ec5..9e6be5ac 100644
--- a/libsepol/cil/src/cil_copy_ast.h
+++ b/libsepol/cil/src/cil_copy_ast.h
@@ -37,12 +37,12 @@
 void cil_copy_list(struct cil_list *orig, struct cil_list **copy);
 int cil_copy_expr(struct cil_db *db, struct cil_list *orig, struct cil_list **new);
 
+int cil_copy_ordered(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab);
 int cil_copy_block(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_blockabstract(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_blockinherit(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_perm(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_class(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
-int cil_copy_classorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_classmapping(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_permset(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 
@@ -55,7 +55,6 @@ int cil_copy_common(struct cil_db *db, void *data, void **copy, symtab_t *symtab
 int cil_copy_classcommon(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_sid(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_sidcontext(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
-int cil_copy_sidorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_user(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_userattribute(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_userattributeset(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
@@ -88,8 +87,6 @@ int cil_copy_cat(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_catalias(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_catset(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 int cil_copy_senscat(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
-int cil_copy_catorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
-int cil_copy_sensitivityorder(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 void cil_copy_fill_level(struct cil_db *db, struct cil_level *orig, struct cil_level **new);
 int cil_copy_level(struct cil_db *db, void *data, void **copy, symtab_t *symtab);
 void cil_copy_fill_levelrange(struct cil_db *db, struct cil_levelrange *orig, struct cil_levelrange *new);
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 9e492cb9..013483c9 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -347,6 +347,12 @@ struct cil_sort {
 	void **array;
 };
 
+struct cil_ordered {
+	int merged;
+	struct cil_list *strs;
+	struct cil_list *datums;
+};
+
 struct cil_block {
 	struct cil_symtab_datum datum;
 	symtab_t symtab[CIL_SYM_NUM];
@@ -387,10 +393,6 @@ struct cil_class {
 	uint32_t ordered; /* Only used for kernel class */
 };
 
-struct cil_classorder {
-	struct cil_list *class_list_str;
-};
-
 struct cil_classperms_set {
 	char *set_str;
 	struct cil_classpermission *set;
@@ -446,10 +448,6 @@ struct cil_sidcontext {
 	struct cil_context *context;
 };
 
-struct cil_sidorder {
-	struct cil_list *sid_list_str;
-};
-
 struct cil_user {
 	struct cil_symtab_datum datum;
 	struct cil_user *bounds;
@@ -685,10 +683,6 @@ struct cil_sens {
 	uint32_t ordered;
 };
 
-struct cil_sensorder {
-	struct cil_list *sens_list_str;
-};
-
 struct cil_cat {
 	struct cil_symtab_datum datum;
 	uint32_t ordered;
@@ -706,10 +700,6 @@ struct cil_catset {
 	struct cil_cats *cats;
 };
 
-struct cil_catorder {
-	struct cil_list *cat_list_str;
-};
-
 struct cil_senscat {
 	char *sens_str;
 	struct cil_cats *cats;
@@ -1012,6 +1002,7 @@ int cil_string_to_uint64(const char *string, uint64_t *value, int base);
 
 void cil_sort_init(struct cil_sort **sort);
 void cil_sort_destroy(struct cil_sort **sort);
+void cil_ordered_init(struct cil_ordered **ordered);
 void cil_netifcon_init(struct cil_netifcon **netifcon);
 void cil_ibendportcon_init(struct cil_ibendportcon **ibendportcon);
 void cil_context_init(struct cil_context **context);
@@ -1023,11 +1014,9 @@ void cil_blockinherit_init(struct cil_blockinherit **inherit);
 void cil_blockabstract_init(struct cil_blockabstract **abstract);
 void cil_in_init(struct cil_in **in);
 void cil_class_init(struct cil_class **class);
-void cil_classorder_init(struct cil_classorder **classorder);
 void cil_classcommon_init(struct cil_classcommon **classcommon);
 void cil_sid_init(struct cil_sid **sid);
 void cil_sidcontext_init(struct cil_sidcontext **sidcontext);
-void cil_sidorder_init(struct cil_sidorder **sidorder);
 void cil_userrole_init(struct cil_userrole **userrole);
 void cil_userprefix_init(struct cil_userprefix **userprefix);
 void cil_selinuxuser_init(struct cil_selinuxuser **selinuxuser);
@@ -1083,8 +1072,6 @@ void cil_userrange_init(struct cil_userrange **userrange);
 void cil_role_init(struct cil_role **role);
 void cil_type_init(struct cil_type **type);
 void cil_cat_init(struct cil_cat **cat);
-void cil_catorder_init(struct cil_catorder **catorder);
-void cil_sensorder_init(struct cil_sensorder **sensorder);
 void cil_args_init(struct cil_args **args);
 void cil_call_init(struct cil_call **call);
 void cil_optional_init(struct cil_optional **optional);
diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
index 9069317e..fa312c6f 100644
--- a/libsepol/cil/src/cil_reset_ast.c
+++ b/libsepol/cil/src/cil_reset_ast.c
@@ -11,6 +11,12 @@ static inline void cil_reset_levelrange(struct cil_levelrange *levelrange);
 static inline void cil_reset_context(struct cil_context *context);
 
 
+static void cil_reset_ordered(struct cil_ordered *ordered)
+{
+	ordered->merged = CIL_FALSE;
+	cil_list_destroy(&ordered->datums, CIL_FALSE);
+}
+
 static int __class_reset_perm_values(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args)
 {
 	struct cil_perm *perm = (struct cil_perm *)d;
@@ -638,14 +644,16 @@ static int __cil_reset_node(struct cil_tree_node *node,  __attribute__((unused))
 	case CIL_BOOLEANIF:
 		cil_reset_booleanif(node->data);
 		break;
-	case CIL_TUNABLEIF:
-	case CIL_CALL:
-		break; /* Not effected by optional block disabling */
-	case CIL_MACRO:
 	case CIL_SIDORDER:
 	case CIL_CLASSORDER:
 	case CIL_CATORDER:
 	case CIL_SENSITIVITYORDER:
+		cil_reset_ordered(node->data);
+		break;
+	case CIL_TUNABLEIF:
+	case CIL_CALL:
+		break; /* Not effected by optional block disabling */
+	case CIL_MACRO:
 		break; /* Nothing to reset */
 	default:
 		break;
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 595bd2b9..0172bbdd 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -1213,55 +1213,6 @@ exit:
 	return rc;
 }
 
-struct cil_ordered_list {
-	int merged;
-	struct cil_list *list;
-	struct cil_tree_node *node;
-};
-
-static void __cil_ordered_list_init(struct cil_ordered_list **ordered)
-{
-	*ordered = cil_malloc(sizeof(**ordered));
-
-	(*ordered)->merged = CIL_FALSE;
-	(*ordered)->list = NULL;
-	(*ordered)->node = NULL;
-}
-
-static void __cil_ordered_list_destroy(struct cil_ordered_list **ordered)
-{
-	cil_list_destroy(&(*ordered)->list, CIL_FALSE);
-	(*ordered)->node = NULL;
-	free(*ordered);
-	*ordered = NULL;
-}
-
-static void __cil_ordered_lists_destroy(struct cil_list **ordered_lists)
-{
-	struct cil_list_item *item = NULL;
-
-	if (ordered_lists == NULL || *ordered_lists == NULL) {
-		return;
-	}
-
-	item = (*ordered_lists)->head;
-	while (item != NULL) {
-		struct cil_list_item *next = item->next;
-		struct cil_ordered_list *ordered = item->data;
-		__cil_ordered_list_destroy(&ordered);
-		free(item);
-		item = next;
-	}
-	free(*ordered_lists);
-	*ordered_lists = NULL;
-}
-
-static void __cil_ordered_lists_reset(struct cil_list **ordered_lists)
-{
-	__cil_ordered_lists_destroy(ordered_lists);
-	cil_list_init(ordered_lists, CIL_LIST_ITEM);
-}
-
 static struct cil_list_item *__cil_ordered_item_insert(struct cil_list *old, struct cil_list_item *curr, struct cil_list_item *item)
 {
 	if (item->flavor == CIL_SID) {
@@ -1310,24 +1261,30 @@ static int __cil_ordered_list_insert(struct cil_list *old, struct cil_list_item
 	return SEPOL_OK;
 }
 
-static struct cil_list_item *__cil_ordered_find_match(struct cil_list_item *t, struct cil_list_item *i)
+static void __cil_ordered_find_next_match(struct cil_list_item **i, struct cil_list_item **j, struct cil_list_item **p)
 {
-	while (i) {
-		if (i->data == t->data) {
-			return i;
+	struct cil_list_item *pstart = *p;
+	struct cil_list_item *jstart = *j;
+
+	while (*i) {
+		*p = pstart;
+		*j = jstart;
+		while (*j) {
+			if ((*i)->data == (*j)->data) {
+				return;
+			}
+			*p = *j;
+			*j = (*j)->next;
 		}
-		i = i->next;
+		*i = (*i)->next;
 	}
-	return NULL;
 }
 
 static int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new)
 {
-	struct cil_list_item *omatch = NULL;
 	struct cil_list_item *ofirst = old->head;
 	struct cil_list_item *ocurr = NULL;
 	struct cil_list_item *oprev = NULL;
-	struct cil_list_item *nmatch = NULL;
 	struct cil_list_item *nfirst = new->head;
 	struct cil_list_item *ncurr = NULL;
 	int rc = SEPOL_ERR;
@@ -1338,75 +1295,41 @@ static int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new)
 
 	if (ofirst == NULL) {
 		/* First list added */
-		rc = __cil_ordered_list_insert(old, NULL, nfirst, NULL);
-		return rc;
+		return __cil_ordered_list_insert(old, NULL, nfirst, NULL);
 	}
 
-	/* Find a match between the new list and the old one */
-	for (nmatch = nfirst; nmatch; nmatch = nmatch->next) {
-		omatch = __cil_ordered_find_match(nmatch, ofirst);
-		if (omatch) {
+	ncurr = nfirst;
+	ocurr = ofirst;
+	oprev = NULL;
+	while (ncurr && ocurr) {
+		__cil_ordered_find_next_match(&ncurr, &ocurr, &oprev);
+		if (!ncurr || !ocurr) {
 			break;
 		}
-	}
-
-	if (!nmatch) {
-		/* List cannot be merged yet */
-		return SEPOL_ERR;
-	}
-
-	if (nmatch != nfirst && omatch != ofirst) {
-		/* Potential ordering conflict--try again later */
-		return SEPOL_ERR;
-	}
-
-	if (nmatch != nfirst) {
-		/* Prepend the beginning of the new list up to the first match to the old list */
-		rc = __cil_ordered_list_insert(old, NULL, nfirst, nmatch);
-		if (rc != SEPOL_OK) {
-			return rc;
+		if (ncurr != nfirst) {
+			rc = __cil_ordered_list_insert(old, oprev, nfirst, ncurr);
+			if (rc != SEPOL_OK) {
+				return rc;
+			}
 		}
+		ncurr = ncurr->next;
+		nfirst = ncurr;
+		oprev = ocurr;
+		ocurr = ocurr->next;
 	}
 
-	/* In the overlapping protion, add items from the new list not in the old list */
-	ncurr = nmatch->next;
-	ocurr = omatch->next;
-	oprev = omatch;
-	while (ncurr && ocurr) {
-		if (ncurr->data == ocurr->data) {
-			oprev = ocurr;
-			ocurr = ocurr->next;
-			ncurr = ncurr->next;
+	if (!ncurr) {
+		if (!nfirst) {
+			/* Done */
+			return SEPOL_OK;
 		} else {
-			/* Handle gap in old: old = (A C)  new = (A B C) */
-			nmatch = __cil_ordered_find_match(ocurr, ncurr->next);
-			if (nmatch) {
-				rc = __cil_ordered_list_insert(old, oprev, ncurr, nmatch);
-				if (rc != SEPOL_OK) {
-					return rc;
-				}
-				oprev = ocurr;
-				ocurr = ocurr->next;
-				ncurr = nmatch->next;
-				continue;
-			}
-			/* Handle gap in new: old = (A B C)  new = (A C) */
-			omatch = __cil_ordered_find_match(ncurr, ocurr->next);
-			if (omatch) {
-				/* Nothing to insert, just skip */
-				oprev = omatch;
-				ocurr = omatch->next;
-				ncurr = ncurr->next;
-				continue;
-			} else {
-				return SEPOL_ERR;
-			}
+			/* Can't merge yet */
+			return SEPOL_ERR;
 		}
 	}
 
-	if (ncurr) {
-		/* Add the rest of the items from the new list */
-		rc = __cil_ordered_list_insert(old, old->tail, ncurr, NULL);
+	if (ncurr && !ocurr) { /* some remaining */
+		rc = __cil_ordered_list_insert(old, oprev, ncurr, NULL);
 		if (rc != SEPOL_OK) {
 			return rc;
 		}
@@ -1415,18 +1338,19 @@ static int __cil_ordered_lists_merge(struct cil_list *old, struct cil_list *new)
 	return SEPOL_OK;
 }
 
-static int insert_unordered(struct cil_list *merged, struct cil_list *unordered)
+static int insert_unordered(struct cil_list *merged, struct cil_list *unordered_list)
 {
+	struct cil_tree_node *node;
+	struct cil_ordered *unordered;
 	struct cil_list_item *curr = NULL;
-	struct cil_ordered_list *unordered_list = NULL;
 	struct cil_list_item *item = NULL;
 	struct cil_list_item *ret = NULL;
 	int rc = SEPOL_ERR;
 
-	cil_list_for_each(curr, unordered) {
-		unordered_list = curr->data;
-
-		cil_list_for_each(item, unordered_list->list) {
+	cil_list_for_each(curr, unordered_list) {
+		node = curr->data;
+		unordered = node->data;
+		cil_list_for_each(item, unordered->datums) {
 			if (cil_list_contains(merged, item->data)) {
 				/* item was declared in an ordered statement, which supersedes
 				 * all unordered statements */
@@ -1453,40 +1377,50 @@ exit:
 static struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, struct cil_list **unordered_lists)
 {
 	struct cil_list *composite = NULL;
+	struct cil_tree_node *node;
+	struct cil_ordered *ordered;
 	struct cil_list_item *curr = NULL;
 	int changed = CIL_TRUE;
 	int waiting = 1;
 	int rc = SEPOL_ERR;
 
-	cil_list_init(&composite, CIL_LIST_ITEM);
+	cil_list_init(&composite, (*ordered_lists)->flavor);
 
 	while (waiting && changed == CIL_TRUE) {
 		changed = CIL_FALSE;
 		waiting = 0;
 		cil_list_for_each(curr, *ordered_lists) {
-			struct cil_ordered_list *ordered_list = curr->data;
-			if (ordered_list->merged == CIL_FALSE) {
-				rc = __cil_ordered_lists_merge(composite, ordered_list->list);
+			node = curr->data;
+			ordered = node->data;
+			if (ordered->merged == CIL_FALSE) {
+				rc = __cil_ordered_lists_merge(composite, ordered->datums);
 				if (rc != SEPOL_OK) {
 					/* Can't merge yet */
 					waiting++;
 				} else {
-					ordered_list->merged = CIL_TRUE;
+					ordered->merged = CIL_TRUE;
 					changed = CIL_TRUE;
 				}
 			}
 		}
 		if (waiting > 0 && changed == CIL_FALSE) {
 			cil_list_for_each(curr, *ordered_lists) {
-				struct cil_ordered_list *ordered_list = curr->data;
-				if (ordered_list->merged == CIL_FALSE) {
-					cil_tree_log(ordered_list->node, CIL_ERR, "Unable to merge ordered list");
+				node = curr->data;
+				ordered = node->data;
+				if (ordered->merged == CIL_FALSE) {
+					cil_tree_log(node, CIL_ERR, "Unable to merge ordered list");
 				}
 			}
 			goto exit;
 		}
 	}
 
+	rc = cil_verify_completed_ordered_list(composite, *ordered_lists);
+	if (rc != SEPOL_OK) {
+		cil_log(CIL_ERR, "Unable to validate ordering\n");
+		goto exit;
+	}
+
 	if (unordered_lists != NULL) {
 		rc = insert_unordered(composite, *unordered_lists);
 		if (rc != SEPOL_OK) {
@@ -1494,31 +1428,24 @@ static struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_
 		}
 	}
 
-	__cil_ordered_lists_destroy(ordered_lists);
-	__cil_ordered_lists_destroy(unordered_lists);
-
 	return composite;
 
 exit:
-	__cil_ordered_lists_destroy(ordered_lists);
-	__cil_ordered_lists_destroy(unordered_lists);
 	cil_list_destroy(&composite, CIL_FALSE);
 	return NULL;
 }
 
 int cil_resolve_classorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *classorder_list, struct cil_list *unordered_classorder_list)
 {
-	struct cil_classorder *classorder = current->data;
-	struct cil_list *new = NULL;
+	struct cil_ordered *ordered = current->data;
 	struct cil_list_item *curr = NULL;
 	struct cil_symtab_datum *datum = NULL;
-	struct cil_ordered_list *class_list = NULL;
 	int rc = SEPOL_ERR;
 	int unordered = CIL_FALSE;
 
-	cil_list_init(&new, CIL_CLASSORDER);
+	cil_list_init(&ordered->datums, CIL_DATUM);
 
-	cil_list_for_each(curr, classorder->class_list_str) {
+	cil_list_for_each(curr, ordered->strs) {
 		if (curr->data == CIL_KEY_UNORDERED) {
 			unordered = CIL_TRUE;
 			continue;
@@ -1535,37 +1462,32 @@ int cil_resolve_classorder(struct cil_tree_node *current, struct cil_db *db, str
 			rc = SEPOL_ERR;
 			goto exit;
 		}
-		cil_list_append(new, CIL_CLASS, datum);
+		cil_list_append(ordered->datums, CIL_CLASS, datum);
 	}
 
-	__cil_ordered_list_init(&class_list);
-	class_list->list = new;
-	class_list->node = current;
 	if (unordered) {
-		cil_list_append(unordered_classorder_list, CIL_CLASSORDER, class_list);
+		cil_list_append(unordered_classorder_list, CIL_CLASSORDER, current);
 	} else {
-		cil_list_append(classorder_list, CIL_CLASSORDER, class_list);
+		cil_list_append(classorder_list, CIL_CLASSORDER, current);
 	}
 
 	return SEPOL_OK;
 
 exit:
-	cil_list_destroy(&new, CIL_FALSE);
+	cil_list_destroy(&ordered->datums, CIL_FALSE);
 	return rc;
 }
 
 int cil_resolve_sidorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sidorder_list)
 {
-	struct cil_sidorder *sidorder = current->data;
-	struct cil_list *new = NULL;
+	struct cil_ordered *ordered = current->data;
 	struct cil_list_item *curr = NULL;
 	struct cil_symtab_datum *datum = NULL;
-	struct cil_ordered_list *ordered = NULL;
 	int rc = SEPOL_ERR;
 
-	cil_list_init(&new, CIL_SIDORDER);
+	cil_list_init(&ordered->datums, CIL_DATUM);
 
-	cil_list_for_each(curr, sidorder->sid_list_str) {
+	cil_list_for_each(curr, ordered->strs) {
 		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SIDS, db, &datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve sid %s in sidorder\n", (char *)curr->data);
@@ -1577,18 +1499,15 @@ int cil_resolve_sidorder(struct cil_tree_node *current, struct cil_db *db, struc
 			goto exit;
 		}
 
-		cil_list_append(new, CIL_SID, datum);
+		cil_list_append(ordered->datums, CIL_SID, datum);
 	}
 
-	__cil_ordered_list_init(&ordered);
-	ordered->list = new;
-	ordered->node = current;
-	cil_list_append(sidorder_list, CIL_SIDORDER, ordered);
+	cil_list_append(sidorder_list, CIL_SIDORDER, current);
 
 	return SEPOL_OK;
 
 exit:
-	cil_list_destroy(&new, CIL_FALSE);
+	cil_list_destroy(&ordered->datums, CIL_FALSE);
 	return rc;
 }
 
@@ -1608,57 +1527,47 @@ static void cil_set_cat_values(struct cil_list *ordered_cats, struct cil_db *db)
 
 int cil_resolve_catorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *catorder_list)
 {
-	struct cil_catorder *catorder = current->data;
-	struct cil_list *new = NULL;
+	struct cil_ordered *ordered = current->data;
 	struct cil_list_item *curr = NULL;
-	struct cil_symtab_datum *cat_datum;
-	struct cil_cat *cat = NULL;
-	struct cil_ordered_list *ordered = NULL;
+	struct cil_symtab_datum *datum;
 	int rc = SEPOL_ERR;
 
-	cil_list_init(&new, CIL_CATORDER);
+	cil_list_init(&ordered->datums, CIL_DATUM);
 
-	cil_list_for_each(curr, catorder->cat_list_str) {
-		struct cil_tree_node *node = NULL;
-		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, db, &cat_datum);
+	cil_list_for_each(curr, ordered->strs) {
+		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_CATS, db, &datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve category %s in categoryorder\n", (char *)curr->data);
 			goto exit;
 		}
-		node = NODE(cat_datum);
-		if (node->flavor != CIL_CAT) {
-			cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", cat_datum->name);
+		if (FLAVOR(datum) != CIL_CAT) {
+			cil_log(CIL_ERR, "%s is not a category. Only categories are allowed in categoryorder statements\n", datum->name);
 			rc = SEPOL_ERR;
 			goto exit;
 		}
-		cat = (struct cil_cat *)cat_datum;
-		cil_list_append(new, CIL_CAT, cat);
+
+		cil_list_append(ordered->datums, CIL_CAT, datum);
 	}
 
-	__cil_ordered_list_init(&ordered);
-	ordered->list = new;
-	ordered->node = current;
-	cil_list_append(catorder_list, CIL_CATORDER, ordered);
+	cil_list_append(catorder_list, CIL_CATORDER, current);
 
 	return SEPOL_OK;
 
 exit:
-	cil_list_destroy(&new, CIL_FALSE);
+	cil_list_destroy(&ordered->datums, CIL_FALSE);
 	return rc;
 }
 
 int cil_resolve_sensitivityorder(struct cil_tree_node *current, struct cil_db *db, struct cil_list *sensitivityorder_list)
 {
-	struct cil_sensorder *sensorder = current->data;
-	struct cil_list *new = NULL;
+	struct cil_ordered *ordered = current->data;
 	struct cil_list_item *curr = NULL;
 	struct cil_symtab_datum *datum = NULL;
-	struct cil_ordered_list *ordered = NULL;
 	int rc = SEPOL_ERR;
 
-	cil_list_init(&new, CIL_LIST_ITEM);
+	cil_list_init(&ordered->datums, CIL_DATUM);
 
-	cil_list_for_each(curr, sensorder->sens_list_str) {
+	cil_list_for_each(curr, ordered->strs) {
 		rc = cil_resolve_name(current, (char *)curr->data, CIL_SYM_SENS, db, &datum);
 		if (rc != SEPOL_OK) {
 			cil_log(CIL_ERR, "Failed to resolve sensitivity %s in sensitivityorder\n", (char *)curr->data);
@@ -1669,18 +1578,15 @@ int cil_resolve_sensitivityorder(struct cil_tree_node *current, struct cil_db *d
 			rc = SEPOL_ERR;
 			goto exit;
 		}
-		cil_list_append(new, CIL_SENS, datum);
+		cil_list_append(ordered->datums, CIL_SENS, datum);
 	}
 
-	__cil_ordered_list_init(&ordered);
-	ordered->list = new;
-	ordered->node = current;
-	cil_list_append(sensitivityorder_list, CIL_SENSITIVITYORDER, ordered);
+	cil_list_append(sensitivityorder_list, CIL_SENSITIVITYORDER, current);
 
 	return SEPOL_OK;
 
 exit:
-	cil_list_destroy(&new, CIL_FALSE);
+	cil_list_destroy(&ordered->datums, CIL_FALSE);
 	return rc;
 }
 
@@ -4115,11 +4021,11 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
 	extra_args.abstract_blocks = NULL;
 
 	cil_list_init(&extra_args.to_destroy, CIL_NODE);
-	cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
-	cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM);
-	cil_list_init(&extra_args.unordered_classorder_lists, CIL_LIST_ITEM);
-	cil_list_init(&extra_args.catorder_lists, CIL_LIST_ITEM);
-	cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM);
+	cil_list_init(&extra_args.sidorder_lists, CIL_SIDORDER);
+	cil_list_init(&extra_args.classorder_lists, CIL_CLASSORDER);
+	cil_list_init(&extra_args.unordered_classorder_lists, CIL_CLASSORDER);
+	cil_list_init(&extra_args.catorder_lists, CIL_CATORDER);
+	cil_list_init(&extra_args.sensitivityorder_lists, CIL_SENSITIVITYORDER);
 	cil_list_init(&extra_args.in_list_before, CIL_IN);
 	cil_list_init(&extra_args.in_list_after, CIL_IN);
 	cil_list_init(&extra_args.abstract_blocks, CIL_NODE);
@@ -4227,11 +4133,16 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
 					cil_log(CIL_INFO, "Resetting declarations\n");
 
 					if (pass >= CIL_PASS_MISC1) {
-						__cil_ordered_lists_reset(&extra_args.sidorder_lists);
-						__cil_ordered_lists_reset(&extra_args.classorder_lists);
-						__cil_ordered_lists_reset(&extra_args.unordered_classorder_lists);
-						__cil_ordered_lists_reset(&extra_args.catorder_lists);
-						__cil_ordered_lists_reset(&extra_args.sensitivityorder_lists);
+						cil_list_destroy(&extra_args.sidorder_lists, CIL_FALSE);
+						cil_list_destroy(&extra_args.classorder_lists, CIL_FALSE);
+						cil_list_destroy(&extra_args.catorder_lists, CIL_FALSE);
+						cil_list_destroy(&extra_args.sensitivityorder_lists, CIL_FALSE);
+						cil_list_destroy(&extra_args.unordered_classorder_lists, CIL_FALSE);
+						cil_list_init(&extra_args.sidorder_lists, CIL_SIDORDER);
+						cil_list_init(&extra_args.classorder_lists, CIL_CLASSORDER);
+						cil_list_init(&extra_args.unordered_classorder_lists, CIL_CLASSORDER);
+						cil_list_init(&extra_args.catorder_lists, CIL_CATORDER);
+						cil_list_init(&extra_args.sensitivityorder_lists, CIL_SENSITIVITYORDER);
 						cil_list_destroy(&db->sidorder, CIL_FALSE);
 						cil_list_destroy(&db->classorder, CIL_FALSE);
 						cil_list_destroy(&db->catorder, CIL_FALSE);
@@ -4263,11 +4174,11 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
 
 	rc = SEPOL_OK;
 exit:
-	__cil_ordered_lists_destroy(&extra_args.sidorder_lists);
-	__cil_ordered_lists_destroy(&extra_args.classorder_lists);
-	__cil_ordered_lists_destroy(&extra_args.catorder_lists);
-	__cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists);
-	__cil_ordered_lists_destroy(&extra_args.unordered_classorder_lists);
+	cil_list_destroy(&extra_args.sidorder_lists, CIL_FALSE);
+	cil_list_destroy(&extra_args.classorder_lists, CIL_FALSE);
+	cil_list_destroy(&extra_args.catorder_lists, CIL_FALSE);
+	cil_list_destroy(&extra_args.sensitivityorder_lists, CIL_FALSE);
+	cil_list_destroy(&extra_args.unordered_classorder_lists, CIL_FALSE);
 	cil_list_destroy(&extra_args.to_destroy, CIL_FALSE);
 	cil_list_destroy(&extra_args.in_list_before, CIL_FALSE);
 	cil_list_destroy(&extra_args.in_list_after, CIL_FALSE);
diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 579e7962..45bf4689 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -519,6 +519,78 @@ exit:
 	return rc;
 }
 
+int cil_verify_completed_ordered_list(struct cil_list *complete, struct cil_list *ordered_lists)
+{
+	struct cil_list_item *cprev, *ccurr, *cnext;
+	int found_prev, found_next;
+	int rc = SEPOL_OK;
+
+	found_prev = CIL_FALSE;
+	found_next = CIL_FALSE;
+	cprev = NULL;
+	ccurr = complete->head;
+	cnext = ccurr ? ccurr->next : NULL;
+	while (ccurr) {
+		struct cil_tree_node *node;
+		struct cil_ordered *ordered;
+		struct cil_list_item *curr_list, *oprev, *ocurr, *onext;
+		int change = CIL_FALSE;
+		cil_list_for_each(curr_list, ordered_lists) {
+			node = curr_list->data;
+			ordered = node->data;
+			oprev = NULL;
+			cil_list_for_each(ocurr, ordered->datums) {
+				onext = ocurr ? ocurr->next : NULL;
+				if (ccurr->data == ocurr->data) {
+					if (found_prev == CIL_FALSE && ((!cprev && !oprev) ||
+						(cprev && oprev && cprev->data == oprev->data))) {
+						found_prev = CIL_TRUE;
+						change = CIL_TRUE;
+					}
+					if (found_next == CIL_FALSE && ((!cnext && !onext) ||
+						(cnext && onext && cnext->data == onext->data))) {
+						found_next = CIL_TRUE;
+						change = CIL_TRUE;
+					}
+					if (found_prev && found_next) {
+						cprev = ccurr;
+						ccurr = cnext;
+						cnext = ccurr ? ccurr->next : NULL;
+						found_prev = CIL_FALSE;
+						found_next = CIL_FALSE;
+						if (!ccurr) {
+							/* Went through the whole list */
+							return rc;
+						}
+					}
+				}
+				oprev = ocurr;
+			}
+		}
+		if (!change) {
+			rc = SEPOL_ERR;
+			cil_log(CIL_ERR, "Unable to verify the order of %s\n", DATUM(ccurr->data)->fqn);
+			cil_log(CIL_ERR, "Found in the following ordering rules:\n");
+			cil_list_for_each(curr_list, ordered_lists) {
+				node = curr_list->data;
+				ordered = node->data;
+				cil_list_for_each(ocurr, ordered->datums) {
+					if (ccurr->data == ocurr->data) {
+						cil_tree_log(node, CIL_ERR, "    ");
+					}
+				}
+			}
+			cprev = ccurr;
+			ccurr = cnext;
+			cnext = ccurr ? ccurr->next : NULL;
+			found_prev = CIL_FALSE;
+			found_next = CIL_FALSE;
+		}
+	}
+
+	return rc;
+}
+
 struct cil_args_verify_order {
 	uint32_t *flavor;
 };
diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
index bb1a072c..daa2f80a 100644
--- a/libsepol/cil/src/cil_verify.h
+++ b/libsepol/cil/src/cil_verify.h
@@ -64,6 +64,7 @@ int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_fl
 int cil_verify_conditional_blocks(struct cil_tree_node *current);
 int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, struct cil_tree_node *node, const char *name);
 int __cil_verify_ranges(struct cil_list *list);
+int cil_verify_completed_ordered_list(struct cil_list *complete, struct cil_list *ordered_lists);
 int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args);
 int __cil_verify_ordered(struct cil_tree_node *current, enum cil_flavor flavor);
 int __cil_verify_initsids(struct cil_list *sids);
diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c
index 4da7a77c..59122a17 100644
--- a/libsepol/cil/src/cil_write_ast.c
+++ b/libsepol/cil/src/cil_write_ast.c
@@ -765,9 +765,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 		break;
 	}
 	case CIL_CLASSORDER: {
-		struct cil_classorder *classorder = node->data;
+		struct cil_ordered *ordered = node->data;
 		fprintf(out, "(classorder ");
-		write_string_list(out, classorder->class_list_str);
+		if (ordered->datums) {
+			write_datum_list(out, ordered->datums);
+		} else {
+			write_string_list(out, ordered->strs);
+		}
 		fprintf(out, ")\n");
 		break;
 	}
@@ -834,9 +838,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 		break;
 	}
 	case CIL_SIDORDER: {
-		struct cil_sidorder *sidorder = node->data;
+		struct cil_ordered *ordered = node->data;
 		fprintf(out, "(sidorder ");
-		write_string_list(out, sidorder->sid_list_str);
+		if (ordered->datums) {
+			write_datum_list(out, ordered->datums);
+		} else {
+			write_string_list(out, ordered->strs);
+		}
 		fprintf(out, ")\n");
 		break;
 	}
@@ -888,9 +896,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 		break;
 	}
 	case CIL_CATORDER: {
-		struct cil_catorder *catorder = node->data;
+		struct cil_ordered *ordered = node->data;
 		fprintf(out, "(categoryorder ");
-		write_string_list(out, catorder->cat_list_str);
+		if (ordered->datums) {
+			write_datum_list(out, ordered->datums);
+		} else {
+			write_string_list(out, ordered->strs);
+		}
 		fprintf(out, ")\n");
 		break;
 	}
@@ -903,9 +915,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 		break;
 	}
 	case CIL_SENSITIVITYORDER: {
-		struct cil_sensorder *sensorder = node->data;
+		struct cil_ordered *ordered = node->data;
 		fprintf(out, "(sensitivityorder ");
-		write_string_list(out, sensorder->sens_list_str);
+		if (ordered->datums) {
+			write_datum_list(out, ordered->datums);
+		} else {
+			write_string_list(out, ordered->strs);
+		}
 		fprintf(out, ")\n");
 		break;
 	}
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/9] libsepol/cil: Allow IP address and mask values to be directly written
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
  2023-09-27 19:00 ` [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void * James Carter
  2023-09-27 19:00 ` [PATCH 2/9] libsepol/cil: Refactor and improve handling of order rules James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 4/9] secilc/docs: Update syntax for IP addresses and nodecon James Carter
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

The nodecon statement requires that the IP address and mask values be
enclosed in parentheses so that these values can be distinguished from
named IP addresses. But since an identifier in CIL cannot start with a
number or contain colons, the parentheses are not really required.

Allow IP address and mask values to be written directly and do not
require (but still allow) parentheses around them. Distinguish
between an address or mask and an identifier by checking if the
first character is a number or if the string contains a colon.

Both of these are now valid:
  (nodecon (10.0.0.1) (255.255.255.0) (USER ROLE TYPE ((SENS) (SENS))))
  (nodecon 10.0.0.1 255.255.255.0 (USER ROLE TYPE ((SENS) (SENS))))

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil_build_ast.c | 42 +++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index efe1601c..fa7148b0 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4387,26 +4387,42 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru
 
 	cil_nodecon_init(&nodecon);
 
-	if (parse_current->next->cl_head == NULL ) {
-		nodecon->addr_str = parse_current->next->data;
-	} else {
+	if (parse_current->next->cl_head) {
 		cil_ipaddr_init(&nodecon->addr);
-
 		rc = cil_fill_ipaddr(parse_current->next->cl_head, nodecon->addr);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
+	} else {
+		char *addr = parse_current->next->data;
+		if (strchr(addr, ':') || (strchr(addr, '.') && isdigit(addr[0]))) {
+			cil_ipaddr_init(&nodecon->addr);
+			rc = cil_fill_ipaddr(parse_current->next, nodecon->addr);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		} else {
+			nodecon->addr_str = addr;
+		}
 	}
 
-	if (parse_current->next->next->cl_head == NULL ) {
-		nodecon->mask_str = parse_current->next->next->data;
-	} else {
+	if (parse_current->next->next->cl_head) {
 		cil_ipaddr_init(&nodecon->mask);
-
 		rc = cil_fill_ipaddr(parse_current->next->next->cl_head, nodecon->mask);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
+	} else {
+		char *mask = parse_current->next->next->data;
+		if (strchr(mask, ':') || (strchr(mask, '.') && isdigit(mask[0]))) {
+			cil_ipaddr_init(&nodecon->mask);
+			rc = cil_fill_ipaddr(parse_current->next->next, nodecon->mask);
+			if (rc != SEPOL_OK) {
+				goto exit;
+			}
+		} else {
+			nodecon->mask_str = mask;
+		}
 	}
 
 	if (parse_current->next->next->next->cl_head == NULL ) {
@@ -5584,15 +5600,19 @@ exit:
 int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
 {
 	int rc = SEPOL_ERR;
+	char *addr_str;
 
 	if (addr_node == NULL || addr_node->data == NULL || addr == NULL) {
 		goto exit;
 	}
 
-	if (strchr(addr_node->data, ':') != NULL) {
+	addr_str = addr_node->data;
+	if (strchr(addr_str, ':')) {
 		addr->family = AF_INET6;
-	} else {
+	} else if (strchr(addr_str, '.') && isdigit(addr_str[0])) {
 		addr->family = AF_INET;
+	} else {
+		goto exit;
 	}
 
 	rc = inet_pton(addr->family, addr_node->data, &addr->ip);
@@ -5604,7 +5624,7 @@ int cil_fill_ipaddr(struct cil_tree_node *addr_node, struct cil_ipaddr *addr)
 	return SEPOL_OK;
 
 exit:
-	cil_log(CIL_ERR, "Bad ip address or netmask: %s\n", (addr_node && addr_node->data) ? (const char *)addr_node->data : "n/a");
+	cil_log(CIL_ERR, "Bad ip address or netmask: %s\n", (addr_node && addr_node->data) ? (const char *)addr_node->data : "NULL");
 	return rc;
 }
 
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/9] secilc/docs: Update syntax for IP addresses and nodecon
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
                   ` (2 preceding siblings ...)
  2023-09-27 19:00 ` [PATCH 3/9] libsepol/cil: Allow IP address and mask values to be directly written James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 5/9] libsepol/cil: Refactor Named Type Transition Filename Creation James Carter
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

For nodecon rules, IP Addresses may be declared without a previous
declaration by enclosing them within parentheses.
Like this: (127.0.0.1) or (::1)

Allow them to also be declared by writing them directly.
Like this: 127.0.0.11 or ::1

This can be done without causing problems with the use of named
IP addresses because identifiers cannot start with a number or
contain a ":".

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 secilc/docs/cil_network_labeling_statements.md | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/secilc/docs/cil_network_labeling_statements.md b/secilc/docs/cil_network_labeling_statements.md
index f92e2136..fed269f9 100644
--- a/secilc/docs/cil_network_labeling_statements.md
+++ b/secilc/docs/cil_network_labeling_statements.md
@@ -10,7 +10,7 @@ Notes:
 
 -   CIL statements utilising an IP address may reference a named IP address or use an anonymous address, the examples will show each option.
 
--   IP Addresses may be declared without a previous declaration by enclosing within parentheses e.g. `(127.0.0.1)` or `(::1)`.
+-   IP Addresses may be declared without a previous declaration by either writing them directly e.g. `127.0.0.11 or `::1` or by enclosing within parentheses e.g. `(127.0.0.1)` or `(::1)`.
 
 **Statement definition:**
 
@@ -113,7 +113,7 @@ nodecon
 
 Label network address objects that represent IPv4 or IPv6 IP addresses and network masks.
 
-IP Addresses may be declared without a previous declaration by enclosing within parentheses e.g. `(127.0.0.1)` or `(::1)`.
+IP Addresses may be declared without a previous declaration by either writing them directly e.g. `127.0.0.11 or `::1` or by enclosing within parentheses e.g. `(127.0.0.1)` or `(::1)`.
 
 **Statement definition:**
 
@@ -160,7 +160,7 @@ These examples show named and anonymous [`nodecon`](cil_network_labeling_stateme
     (ipaddr ipv4_1 192.0.2.64)
 
     (nodecon ipv4_1 netmask_1 context_2)
-    (nodecon (192.0.2.64) (255.255.255.255) context_1)
+    (nodecon 192.0.2.64 255.255.255.255 context_1)
     (nodecon (192.0.2.64) netmask_1 (unconfined.user object_r unconfined.object ((s0) (s0 (c0)))))
 
     (context context_3 (sys.id sys.role my48prefix.node ((s0)(s0))))
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/9] libsepol/cil: Refactor Named Type Transition Filename Creation
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
                   ` (3 preceding siblings ...)
  2023-09-27 19:00 ` [PATCH 4/9] secilc/docs: Update syntax for IP addresses and nodecon James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 6/9] libsepol/cil: Allow paths in filecon rules to be passed as arguments James Carter
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

To support passing a filename as an argument in a macro call that
is to be used in a named type transition, the filename is considered
to be declared when it is used in a named type transition or passed
as an argument with the name flavor. In the struct for a named
type transition, there are fields for a pointer to the filename
string and the filename datum pointer.

When writing out the filename after the resolve phase AST, it is not
possible to determine whether the filename in a named type transition
is an argument name or an actual filename. If it is an actual filename,
then it should be enclosed in double quotes, otherwise, it should
not. Currently, it is always double quoted.

Rework how filenames are declared and handled, so that if the datum
pointer for the name is not NULL, then that is an actual filename
that should be double quoted. Otherwise, the value pointed to by
the string pointer is used and not double quoted.

Move the declaration of the filename to the build phase. Any named
type transition that is not in a macro or is not using a macro
argument is an actual filename, so create a datum and store that in
the struct for the named type transition. Otherwise, store the
string in the named type transition. During the resolve phase,
filename strings can be looked up to find the actual filename that
is being passed into the macro call.

Since the name parameter was never used, just get rid of the
cil_name struct and use datums directly.

Allow either "name" or "string" to be used as the parameter flavor.
Internally, it will be a CIL_DECLARED_STRING and "string" will be
used to write out the AST.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil.c             | 38 ++++++++-------
 libsepol/cil/src/cil_build_ast.c   | 78 +++++++++++++++++++++---------
 libsepol/cil/src/cil_build_ast.h   |  3 +-
 libsepol/cil/src/cil_copy_ast.c    |  1 +
 libsepol/cil/src/cil_flavor.h      |  2 +-
 libsepol/cil/src/cil_fqn.c         |  2 +-
 libsepol/cil/src/cil_internal.h    | 12 ++---
 libsepol/cil/src/cil_policy.c      |  5 +-
 libsepol/cil/src/cil_resolve_ast.c | 64 ++++--------------------
 libsepol/cil/src/cil_write_ast.c   | 30 +++++++-----
 10 files changed, 115 insertions(+), 120 deletions(-)

diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index 46477d0e..d2219f77 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -431,7 +431,7 @@ void cil_db_init(struct cil_db **db)
 	cil_sort_init(&(*db)->fsuse);
 	cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
 	cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM);
-	cil_list_init(&(*db)->names, CIL_LIST_ITEM);
+	cil_list_init(&(*db)->declared_strings, CIL_LIST_ITEM);
 
 	cil_type_init(&(*db)->selftype);
 	(*db)->selftype->datum.name = CIL_KEY_SELF;
@@ -465,6 +465,18 @@ void cil_db_init(struct cil_db **db)
 	(*db)->policy_version = POLICYDB_VERSION_MAX;
 }
 
+static void cil_declared_strings_list_destroy(struct cil_list **strings)
+{
+	struct cil_list_item *i;
+
+	cil_list_for_each(i, *strings) {
+		struct cil_symtab_datum *d = i->data;
+		cil_symtab_datum_destroy(d);
+		free(d);
+	}
+	cil_list_destroy(strings, CIL_FALSE);
+}
+
 void cil_db_destroy(struct cil_db **db)
 {
 	if (db == NULL || *db == NULL) {
@@ -492,7 +504,8 @@ void cil_db_destroy(struct cil_db **db)
 	cil_sort_destroy(&(*db)->fsuse);
 	cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
 	cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE);
-	cil_list_destroy(&(*db)->names, CIL_TRUE);
+
+	cil_declared_strings_list_destroy(&(*db)->declared_strings);
 
 	cil_destroy_type((*db)->selftype);
 	cil_destroy_type((*db)->notselftype);
@@ -966,9 +979,6 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 	case CIL_SIDORDER:
 		cil_destroy_ordered(*data);
 		break;
-	case CIL_NAME:
-		cil_destroy_name(*data);
-		break;
 	case CIL_ROLEALLOW:
 		cil_destroy_roleallow(*data);
 		break;
@@ -1010,6 +1020,8 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
 	case CIL_IPADDR:
 		cil_destroy_ipaddr(*data);
 		break;
+	case CIL_DECLARED_STRING:
+		break;
 	case CIL_SIDCONTEXT:
 		cil_destroy_sidcontext(*data);
 		break;
@@ -1151,8 +1163,8 @@ int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_i
 	case CIL_SID:
 		*sym_index = CIL_SYM_SIDS;
 		break;
-	case CIL_NAME:
-		*sym_index = CIL_SYM_NAMES;
+	case CIL_DECLARED_STRING:
+		*sym_index = CIL_SYM_STRINGS;
 		break;
 	case CIL_CONTEXT:
 		*sym_index = CIL_SYM_CONTEXTS;
@@ -1185,7 +1197,7 @@ const char * cil_node_to_string(struct cil_tree_node *node)
 	case CIL_NODE:
 		return CIL_KEY_NODE;
 	case CIL_STRING:
-		return "string";
+		return CIL_KEY_STRING;
 	case CIL_DATUM:
 		return "<datum>";
 	case CIL_LIST:
@@ -1324,8 +1336,6 @@ const char * cil_node_to_string(struct cil_tree_node *node)
 		return CIL_KEY_SID;
 	case CIL_SIDORDER:
 		return CIL_KEY_SIDORDER;
-	case CIL_NAME:
-		return CIL_KEY_NAME;
 	case CIL_ROLEALLOW:
 		return CIL_KEY_ROLEALLOW;
 	case CIL_AVRULE:
@@ -2430,14 +2440,6 @@ void cil_typepermissive_init(struct cil_typepermissive **typeperm)
 	(*typeperm)->type = NULL;
 }
 
-void cil_name_init(struct cil_name **name)
-{
-	*name = cil_malloc(sizeof(**name));
-
-	cil_symtab_datum_init(&(*name)->datum);
-	(*name)->name_str = NULL;
-}
-
 void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans)
 {
 	*nametypetrans = cil_malloc(sizeof(**nametypetrans));
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index fa7148b0..ec430743 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -83,6 +83,51 @@ exit:
 	return rc;
 }
 
+struct cil_symtab_datum *cil_gen_declared_string(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
+{
+	struct cil_tree_node *parent = ast_node->parent;
+	struct cil_macro *macro = NULL;
+	symtab_t *symtab;
+	struct cil_symtab_datum *datum;
+
+	while (parent) {
+		if (parent->flavor == CIL_MACRO) {
+			/* This condition is only reached in the build phase */
+			macro = parent->data;
+			break;
+		} else if (parent->flavor == CIL_CALL) {
+			/* This condition is only reached in the resolve phase */
+			struct cil_call *call = parent->data;
+			macro = call->macro;
+			break;
+		}
+		parent = parent->parent;
+	}
+
+	if (macro && macro->params) {
+		struct cil_list_item *item;
+		cil_list_for_each(item, macro->params) {
+			struct cil_param *param = item->data;
+			if (param->flavor == CIL_DECLARED_STRING && param->str == key) {
+				return NULL;
+			}
+		}
+	}
+
+	symtab = &((struct cil_root *)db->ast->root->data)->symtab[CIL_SYM_STRINGS];
+	cil_symtab_get_datum(symtab, key, &datum);
+	if (datum != NULL) {
+		return datum;
+	}
+
+	datum = cil_malloc(sizeof(*datum));
+	cil_symtab_datum_init(datum);
+	cil_symtab_insert(symtab, key, datum, ast_node);
+	cil_list_append(db->declared_strings, CIL_DATUM, datum);
+	return datum;
+}
+
+
 static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, enum cil_flavor f_old)
 {
 	if (f_new != f_old) {
@@ -3371,30 +3416,29 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren
 
 	if (s5) {
 		struct cil_nametypetransition *nametypetrans = NULL;
-
 		cil_nametypetransition_init(&nametypetrans);
 
+		ast_node->data = nametypetrans;
+		ast_node->flavor = CIL_NAMETYPETRANSITION;
+
 		nametypetrans->src_str = s1;
 		nametypetrans->tgt_str = s2;
 		nametypetrans->obj_str = s3;
-		nametypetrans->result_str = s5;
 		nametypetrans->name_str = s4;
-
-		ast_node->data = nametypetrans;
-		ast_node->flavor = CIL_NAMETYPETRANSITION;
+		nametypetrans->name = cil_gen_declared_string(db, s4, ast_node);
+		nametypetrans->result_str = s5;
 	} else {
 		struct cil_type_rule *rule = NULL;
-
 		cil_type_rule_init(&rule);
 
+		ast_node->data = rule;
+		ast_node->flavor = CIL_TYPE_RULE;
+
 		rule->rule_kind = CIL_TYPE_TRANSITION;
 		rule->src_str = s1;
 		rule->tgt_str = s2;
 		rule->obj_str = s3;
 		rule->result_str = s4;
-
-		ast_node->data = rule;
-		ast_node->flavor = CIL_TYPE_RULE;
 	}
 
 	return SEPOL_OK;
@@ -3404,16 +3448,6 @@ exit:
 	return rc;
 }
 
-void cil_destroy_name(struct cil_name *name)
-{
-	if (name == NULL) {
-		return;
-	}
-
-	cil_symtab_datum_destroy(&name->datum);
-	free(name);
-}
-
 void cil_destroy_typetransition(struct cil_nametypetransition *nametypetrans)
 {
 	if (nametypetrans == NULL) {
@@ -5223,9 +5257,9 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
 		} else if (kind == CIL_KEY_BOOL) {
 			param->flavor = CIL_BOOL;
 		} else if (kind == CIL_KEY_STRING) {
-			param->flavor = CIL_NAME;
+			param->flavor = CIL_DECLARED_STRING;
 		} else if (kind == CIL_KEY_NAME) {
-			param->flavor = CIL_NAME;
+			param->flavor = CIL_DECLARED_STRING;
 		} else {
 			cil_log(CIL_ERR, "The kind %s is not allowed as a parameter\n",kind);
 			cil_destroy_param(param);
@@ -5365,7 +5399,7 @@ void cil_destroy_args(struct cil_args *args)
 	} else if (args->arg != NULL) {
 		struct cil_tree_node *node = args->arg->nodes->head->data;
 		switch (args->flavor) {
-		case CIL_NAME:
+		case CIL_DECLARED_STRING:
 			break;
 		case CIL_CATSET:
 			cil_destroy_catset((struct cil_catset *)args->arg);
diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h
index 96af3c91..7fa4299c 100644
--- a/libsepol/cil/src/cil_build_ast.h
+++ b/libsepol/cil/src/cil_build_ast.h
@@ -34,11 +34,13 @@
 
 #include "cil_internal.h"
 #include "cil_flavor.h"
+#include "cil_symtab.h"
 #include "cil_tree.h"
 #include "cil_list.h"
 
 int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node);
 
+struct cil_symtab_datum *cil_gen_declared_string(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node);
 int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor);
 int cil_parse_to_list(struct cil_tree_node *parse_cl_head, struct cil_list *ast_cl, enum cil_flavor flavor);
 
@@ -146,7 +148,6 @@ int cil_gen_typebounds(struct cil_db *db, struct cil_tree_node *parse_current, s
 int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_typepermissive(struct cil_typepermissive *typeperm);
 int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
-void cil_destroy_name(struct cil_name *name);
 void cil_destroy_typetransition(struct cil_nametypetransition *nametypetrans);
 int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
 void cil_destroy_rangetransition(struct cil_rangetransition *rangetrans);
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index 735628df..b6e13f3c 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -714,6 +714,7 @@ int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void
 	new->tgt_str = orig->tgt_str;
 	new->obj_str = orig->obj_str;
 	new->name_str = orig->name_str;
+	new->name = orig->name;
 	new->result_str = orig->result_str;
 
 
diff --git a/libsepol/cil/src/cil_flavor.h b/libsepol/cil/src/cil_flavor.h
index 89ab7875..155d7c80 100644
--- a/libsepol/cil/src/cil_flavor.h
+++ b/libsepol/cil/src/cil_flavor.h
@@ -184,7 +184,7 @@ enum cil_flavor {
 	CIL_LEVEL,
 	CIL_LEVELRANGE,
 	CIL_SID,
-	CIL_NAME,
+	CIL_DECLARED_STRING,
 	CIL_CONTEXT,
 	CIL_IPADDR,
 	CIL_POLICYCAP,
diff --git a/libsepol/cil/src/cil_fqn.c b/libsepol/cil/src/cil_fqn.c
index 46db069b..20e062e5 100644
--- a/libsepol/cil/src/cil_fqn.c
+++ b/libsepol/cil/src/cil_fqn.c
@@ -103,7 +103,7 @@ static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, has
 		case CIL_SYM_CONTEXTS:
 		case CIL_SYM_LEVELRANGES:
 		case CIL_SYM_IPADDRS:
-		case CIL_SYM_NAMES:
+		case CIL_SYM_STRINGS:
 		case CIL_SYM_PERMX:
 			/* These do not show up in the kernel policy */
 			break;
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 013483c9..6d578cea 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -267,7 +267,7 @@ enum cil_sym_index {
 	CIL_SYM_LEVELRANGES,
 	CIL_SYM_POLICYCAPS,
 	CIL_SYM_IPADDRS,
-	CIL_SYM_NAMES,
+	CIL_SYM_STRINGS,
 	CIL_SYM_PERMX,
 	CIL_SYM_NUM,
 	CIL_SYM_UNKNOWN,
@@ -313,7 +313,7 @@ struct cil_db {
 	struct cil_sort *fsuse;
 	struct cil_list *userprefixes;
 	struct cil_list *selinuxusers;
-	struct cil_list *names;
+	struct cil_list *declared_strings;
 	int num_types_and_attrs;
 	int num_classes;
 	int num_cats;
@@ -564,11 +564,6 @@ struct cil_typepermissive {
 	void *type; /* type or alias */
 };
 
-struct cil_name {
-	struct cil_symtab_datum datum;
-	char *name_str;
-};
-
 struct cil_nametypetransition {
 	char *src_str;
 	void *src; /* type, alias, or attribute */
@@ -577,7 +572,7 @@ struct cil_nametypetransition {
 	char *obj_str;
 	struct cil_class *obj;
 	char *name_str;
-	struct cil_name *name;
+	struct cil_symtab_datum *name;
 	char *result_str;
 	void *result; /* type or alias */
 
@@ -1029,7 +1024,6 @@ void cil_expandtypeattribute_init(struct cil_expandtypeattribute **expandattr);
 void cil_alias_init(struct cil_alias **alias);
 void cil_aliasactual_init(struct cil_aliasactual **aliasactual);
 void cil_typepermissive_init(struct cil_typepermissive **typeperm);
-void cil_name_init(struct cil_name **name);
 void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans);
 void cil_rangetransition_init(struct cil_rangetransition **rangetrans);
 void cil_bool_init(struct cil_bool **cilbool);
diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
index feb97868..e9a8f75d 100644
--- a/libsepol/cil/src/cil_policy.c
+++ b/libsepol/cil/src/cil_policy.c
@@ -1256,8 +1256,7 @@ static void cil_type_rule_to_policy(FILE *out, struct cil_type_rule *rule)
 
 static void cil_nametypetransition_to_policy(FILE *out, struct cil_nametypetransition *trans)
 {
-	struct cil_symtab_datum *src, *tgt, *res;
-	struct cil_name *name;
+	struct cil_symtab_datum *src, *tgt, *name, *res;
 	struct cil_list *class_list;
 	struct cil_list_item *i1;
 
@@ -1268,7 +1267,7 @@ static void cil_nametypetransition_to_policy(FILE *out, struct cil_nametypetrans
 
 	class_list = cil_expand_class(trans->obj);
 	cil_list_for_each(i1, class_list) {
-		fprintf(out, "type_transition %s %s : %s %s \"%s\";\n", src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn, name->datum.fqn);
+		fprintf(out, "type_transition %s %s : %s %s \"%s\";\n", src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn, name->fqn);
 	}
 	cil_list_destroy(&class_list, CIL_FALSE);
 }
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index 0172bbdd..bdff044a 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -68,49 +68,6 @@ struct cil_args_resolve {
 	struct cil_list *abstract_blocks;
 };
 
-static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
-{
-	/* Currently only used for typetransition file names.
-	   But could be used for any string that is passed as a parameter.
-	*/
-	struct cil_tree_node *parent = ast_node->parent;
-	struct cil_macro *macro = NULL;
-	struct cil_name *name;
-	symtab_t *symtab;
-	enum cil_sym_index sym_index;
-	struct cil_symtab_datum *datum = NULL;
-
-	if (parent->flavor == CIL_CALL) {
-		struct cil_call *call = parent->data;
-		macro = call->macro;	
-	} else if (parent->flavor == CIL_MACRO) {
-		macro = parent->data;
-	}
-	if (macro != NULL && macro->params != NULL) {
-		struct cil_list_item *item;
-		cil_list_for_each(item, macro->params) {
-			struct cil_param *param = item->data;
-			if (param->flavor == CIL_NAME && param->str == key) {
-				return NULL;
-			}
-		}
-	}
-
-	cil_flavor_to_symtab_index(CIL_NAME, &sym_index);
-	symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index];
-
-	cil_symtab_get_datum(symtab, key, &datum);
-	if (datum != NULL) {
-		return (struct cil_name *)datum;
-	}
-
-	cil_name_init(&name);
-	cil_symtab_insert(symtab, key, (struct cil_symtab_datum *)name, ast_node);
-	cil_list_append(db->names, CIL_NAME, name);
-
-	return name;
-}
-
 static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums, enum cil_flavor class_flavor)
 {
 	int rc = SEPOL_ERR;
@@ -691,13 +648,12 @@ int cil_resolve_nametypetransition(struct cil_tree_node *current, struct cil_db
 	}
 	nametypetrans->obj = (struct cil_class*)obj_datum;
 
-	nametypetrans->name = __cil_insert_name(db, nametypetrans->name_str, current);
-	if (nametypetrans->name == NULL) {
-		rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_NAMES, db, &name_datum);
+	if (!nametypetrans->name) {
+		rc = cil_resolve_name(current, nametypetrans->name_str, CIL_SYM_STRINGS, db, &name_datum);
 		if (rc != SEPOL_OK) {
 			goto exit;
 		}
-		nametypetrans->name = (struct cil_name *)name_datum;
+		nametypetrans->name = name_datum;
 	}
 
 	rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, db, &result_datum);
@@ -2689,17 +2645,17 @@ static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call
 		cil_args_init(&arg);
 
 		switch (flavor) {
-		case CIL_NAME: {
-			struct cil_name *name;
+		case CIL_DECLARED_STRING: {
+			struct cil_symtab_datum *string;
 			if (arg_node->data == NULL) {
 				cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
 				cil_destroy_args(arg);
 				rc = SEPOL_ERR;
 				goto exit;
 			}
-			name = __cil_insert_name(db, arg_node->data, call_node);
-			if (name != NULL) {
-				arg->arg = (struct cil_symtab_datum *)name;
+			string = cil_gen_declared_string(db, arg_node->data, call_node);
+			if (string) {
+				arg->arg = string;
 			} else {
 				arg->arg_str = arg_node->data;
 			}
@@ -3017,11 +2973,11 @@ static int cil_resolve_call_args(struct cil_tree_node *current, struct cil_db *d
 		}
 
 		switch (arg->flavor) {
-		case CIL_NAME:
+		case CIL_DECLARED_STRING:
 			if (arg->arg != NULL) {
 				continue; /* No need to resolve */
 			} else {
-				sym_index = CIL_SYM_NAMES;
+				sym_index = CIL_SYM_STRINGS;
 			}
 			break;
 		case CIL_LEVEL:
diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c
index 59122a17..d867fa8b 100644
--- a/libsepol/cil/src/cil_write_ast.c
+++ b/libsepol/cil/src/cil_write_ast.c
@@ -43,7 +43,7 @@
 
 static inline const char *datum_or_str(struct cil_symtab_datum *datum, const char *str)
 {
-	return datum ? datum->fqn : str;
+	return datum && datum->fqn ? datum->fqn : str;
 }
 
 static inline const char *datum_to_str(struct cil_symtab_datum *datum)
@@ -78,7 +78,7 @@ static void write_expr(FILE *out, struct cil_list *expr)
 		case CIL_BOOL:
 		case CIL_CLASS:
 		case CIL_MAP_CLASS:
-		case CIL_NAME:
+		case CIL_DECLARED_STRING:
 			fprintf(out, "%s", datum_to_str(curr->data));
 			break;
 		case CIL_OP: {
@@ -413,9 +413,16 @@ static void write_call_args(FILE *out, struct cil_list *args)
 		case CIL_CAT:
 		case CIL_BOOL:
 		case CIL_CLASS:
-		case CIL_MAP_CLASS:
-		case CIL_NAME: {
-			fprintf(out, "%s", datum_or_str(arg->arg, arg->arg_str));
+		case CIL_MAP_CLASS: {
+			fprintf(out, "%s", datum_or_str(DATUM(arg->arg), arg->arg_str));
+			break;
+		}
+		case CIL_DECLARED_STRING: {
+			if (arg->arg) {
+				fprintf(out, "\"%s\" ", DATUM(arg->arg)->fqn);
+			} else {
+				fprintf(out, "%s ", arg->arg_str);
+			}
 			break;
 		}
 		case CIL_CATSET: {
@@ -467,7 +474,7 @@ static void write_call_args(FILE *out, struct cil_list *args)
 			break;
 		}
 		default:
-			fprintf(out, "<?ARG:%s>", datum_or_str(arg->arg, arg->arg_str));
+			fprintf(out, "<?ARG:%s>", datum_or_str(DATUM(arg->arg), arg->arg_str));
 			break;
 		}
 	}
@@ -533,12 +540,9 @@ static const char *macro_param_flavor_to_string(enum cil_flavor flavor)
 	case CIL_BOOL:
 		str = CIL_KEY_BOOL;
 		break;
-	case CIL_STRING:
+	case CIL_DECLARED_STRING:
 		str = CIL_KEY_STRING;
 		break;
-	case CIL_NAME:
-		str = CIL_KEY_NAME;
-		break;
 	default:
 		str = "<?FLAVOR>";
 		break;
@@ -1193,7 +1197,11 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 		fprintf(out, "%s ", datum_or_str(DATUM(rule->src), rule->src_str));
 		fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str));
 		fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str));
-		fprintf(out, "\"%s\" ", datum_or_str(DATUM(rule->name), rule->name_str));
+		if (rule->name) {
+			fprintf(out, "\"%s\" ", DATUM(rule->name)->fqn);
+		} else {
+			fprintf(out, "%s ", rule->name_str);
+		}
 		fprintf(out, "%s", datum_or_str(DATUM(rule->result), rule->result_str));
 		fprintf(out, ")\n");
 		break;
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/9] libsepol/cil: Allow paths in filecon rules to be passed as arguments
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
                   ` (4 preceding siblings ...)
  2023-09-27 19:00 ` [PATCH 5/9] libsepol/cil: Refactor Named Type Transition Filename Creation James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 7/9] secilc/docs: Fix and update the documentation for macro parameters James Carter
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

Allow paths in filecon rules to be passed as arguments in macro calls
just like filenames can be passed for named type transition rules.

The paths are handled just like the filenames in named type transition
rules.

Example/
  (macro m1 ((string ARG1))
    (filecon ARG1 dir (USER ROLE TYPE ((SENS)(SENS))))
  )
  (call m1 ("/usr/bin"))

  Results in the following equivalent rule:
  (filecon "/usr/bin" dir (USER ROLE TYPE ((SENS)(SENS))))

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil.c             |  8 ++++----
 libsepol/cil/src/cil_build_ast.c   |  8 +++++---
 libsepol/cil/src/cil_copy_ast.c    |  1 +
 libsepol/cil/src/cil_internal.h    |  1 +
 libsepol/cil/src/cil_post.c        | 14 +++++++++-----
 libsepol/cil/src/cil_resolve_ast.c |  9 +++++++++
 libsepol/cil/src/cil_write_ast.c   |  6 +++++-
 7 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index d2219f77..ac548d15 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -1806,8 +1806,8 @@ int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size)
 	for (i = 0; i < filecons->count; i++) {
 		struct cil_filecon *filecon = filecons->array[i];
 		struct cil_context *ctx = filecon->context;
-
-		str_len += strlen(filecon->path_str);
+		char *path_str = filecon->path ? DATUM(filecon->path)->fqn : filecon->path_str;
+		str_len += strlen(path_str);
 
 		if (filecon->type != CIL_FILECON_ANY) {
 			/* If a type is specified,
@@ -1845,8 +1845,8 @@ int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size)
 		struct cil_filecon *filecon = filecons->array[i];
 		struct cil_context *ctx = filecon->context;
 		const char *str_type = NULL;
-
-		buf_pos = sprintf(str_tmp, "%s", filecon->path_str);
+		char *path_str = filecon->path ? DATUM(filecon->path)->fqn : filecon->path_str;
+		buf_pos = sprintf(str_tmp, "%s", path_str);
 		str_tmp += buf_pos;
 
 		switch(filecon->type) {
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
index ec430743..be260a31 100644
--- a/libsepol/cil/src/cil_build_ast.c
+++ b/libsepol/cil/src/cil_build_ast.c
@@ -4148,7 +4148,12 @@ int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, stru
 	type = parse_current->next->next->data;
 	cil_filecon_init(&filecon);
 
+	ast_node->data = filecon;
+	ast_node->flavor = CIL_FILECON;
+
 	filecon->path_str = parse_current->next->data;
+	/* filecon->path will be NULL if in a macro and the path is an argument */
+	filecon->path = cil_gen_declared_string(db, filecon->path_str, ast_node);
 
 	if (type == CIL_KEY_ANY) {
 		filecon->type = CIL_FILECON_ANY;
@@ -4187,9 +4192,6 @@ int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, stru
 		}
 	}
 
-	ast_node->data = filecon;
-	ast_node->flavor = CIL_FILECON;
-
 	return SEPOL_OK;
 
 exit:
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index b6e13f3c..f025de2f 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -1124,6 +1124,7 @@ int cil_copy_filecon(struct cil_db *db, void *data, void **copy, __attribute__((
 	cil_filecon_init(&new);
 
 	new->path_str = orig->path_str;
+	new->path = orig->path;
 	new->type = orig->type;
 
 	if (orig->context_str != NULL) {
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 6d578cea..4193ee99 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -740,6 +740,7 @@ enum cil_filecon_types {
 
 struct cil_filecon {
 	char *path_str;
+	struct cil_symtab_datum *path;
 	enum cil_filecon_types type;
 	char *context_str;
 	struct cil_context *context;
diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index da97a392..7f45299a 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -213,12 +213,16 @@ int cil_post_filecon_compare(const void *a, const void *b)
 	struct cil_filecon *b_filecon = *(struct cil_filecon**)b;
 	struct fc_data *a_data = cil_malloc(sizeof(*a_data));
 	struct fc_data *b_data = cil_malloc(sizeof(*b_data));
-	char *a_path = cil_malloc(strlen(a_filecon->path_str) + 1);
-	char *b_path = cil_malloc(strlen(b_filecon->path_str) + 1);
+	char *a_path_str, *a_path, *b_path_str, *b_path;
+
+	a_path_str = a_filecon->path ? DATUM(a_filecon->path)->fqn : a_filecon->path_str;
+	b_path_str = b_filecon->path ? DATUM(b_filecon->path)->fqn : b_filecon->path_str;
+	a_path = cil_malloc(strlen(a_path_str) + 1);
+	b_path = cil_malloc(strlen(b_path_str) + 1);
 	a_path[0] = '\0';
 	b_path[0] = '\0';
-	strcat(a_path, a_filecon->path_str);
-	strcat(b_path, b_filecon->path_str);
+	strcat(a_path, a_path_str);
+	strcat(b_path, b_path_str);
 	cil_post_fc_fill_data(a_data, a_path);
 	cil_post_fc_fill_data(b_data, b_path);
 	if (a_data->meta && !b_data->meta) {
@@ -238,7 +242,7 @@ int cil_post_filecon_compare(const void *a, const void *b)
 	} else if (b_filecon->type < a_filecon->type) {
 		rc = 1;
 	} else {
-		rc = strcmp(a_filecon->path_str, b_filecon->path_str);
+		rc = strcmp(a_path_str, b_path_str);
 	}
 
 	free(a_path);
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index bdff044a..d52c106a 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -1811,8 +1811,17 @@ int cil_resolve_filecon(struct cil_tree_node *current, struct cil_db *db)
 {
 	struct cil_filecon *filecon = current->data;
 	struct cil_symtab_datum *context_datum = NULL;
+	struct cil_symtab_datum *path_datum = NULL;
 	int rc = SEPOL_ERR;
 
+	if (!filecon->path) {
+		rc = cil_resolve_name(current, filecon->path_str, CIL_SYM_STRINGS, db, &path_datum);
+		if (rc != SEPOL_OK) {
+			return rc;
+		}
+		filecon->path = path_datum;
+	}
+
 	if (filecon->context_str != NULL) {
 		rc = cil_resolve_name(current, filecon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
 		if (rc != SEPOL_OK) {
diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c
index d867fa8b..161c53e9 100644
--- a/libsepol/cil/src/cil_write_ast.c
+++ b/libsepol/cil/src/cil_write_ast.c
@@ -1265,7 +1265,11 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	case CIL_FILECON: {
 		struct cil_filecon *filecon = node->data;
 		fprintf(out, "(filecon ");
-		fprintf(out, "\"%s\" ", filecon->path_str);
+		if (filecon->path) {
+			fprintf(out, "\"%s\" ", DATUM(filecon->path)->fqn);
+		} else {
+			fprintf(out, "%s ", filecon->path_str);
+		}
 		switch (filecon->type) {
 		case CIL_FILECON_ANY:
 			fprintf(out, "%s ", CIL_KEY_ANY);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/9] secilc/docs: Fix and update the documentation for macro parameters
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
                   ` (5 preceding siblings ...)
  2023-09-27 19:00 ` [PATCH 6/9] libsepol/cil: Allow paths in filecon rules to be passed as arguments James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 8/9] libsepol/cil: Add pointers to datums to improve writing out AST James Carter
  2023-09-27 19:00 ` [PATCH 9/9] libsepol/cil: Give warning for name that has different flavor James Carter
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

Remove references to "typealias", "categoryalias", and
sensitivityalias" as valid parameter kinds, because they are not.

Add "string" as a valid parameter kind.

Add a note that "categoryset", "level", "levelrange",
"classpermission", and "ipaddr" can be named or anonymous.

Add a note that "type", "role", and "user" can be used for attributes.

Add a note that "type", "sensitivity" and "category" can be used for
aliases.

Add a note that "string" and "name" can be used for filenames in
typetransition rules and paths in filecon rules.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 secilc/docs/cil_call_macro_statements.md | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/secilc/docs/cil_call_macro_statements.md b/secilc/docs/cil_call_macro_statements.md
index dcc6139f..adbfef4b 100644
--- a/secilc/docs/cil_call_macro_statements.md
+++ b/secilc/docs/cil_call_macro_statements.md
@@ -90,7 +90,11 @@ Duplicate [`macro`](cil_call_macro_statements.md#macro) declarations in the same
 <tr class="odd">
 <td align="left"><p><code>param_type</code></p></td>
 <td align="left"><p>Zero or more parameters that are passed to the macro. The <code>param_type</code> is a keyword used to determine the declaration type (e.g. <code>type</code>, <code>class</code>, <code>categoryset</code>).</p>
-<p>The list of valid <code>param_type</code> entries are: <code>type</code>, <code>typealias</code>, <code>role</code>, <code>user</code>, <code>sensitivity</code>, <code>sensitivityalias</code>, <code>category</code>, <code>categoryalias</code>, <code>categoryset</code> (named or anonymous), <code>level</code> (named or anonymous), <code>levelrange</code> (named or anonymous), <code>class</code>, <code>classpermission</code> (named or anonymous), <code>ipaddr</code> (named or anonymous), <code>name</code> (a string), <code>classmap</code></p></td>
+<p>The list of valid <code>param_type</code> entries are: <code>string</code>, <code>name</code>, <code>type</code>, <code>role</code>, <code>user</code>, <code>sensitivity</code>, <code>category</code>, <code>bool</code>, <code>categoryset</code>, <code>level</code>, <code>levelrange</code>, <code>ipaddr</code>, <code>class</code>, <code>classmap</code>, and <code>classpermission</code>.
+<p>The <code>param_types</code> <code>categoryset</code>, <code>level</code>, <code>levelrange</code>, <code>classpermission</code>, and <code>ipaddr</code> can by named or anonymous.</p>
+<p>The <code>param_types</code> <code>type</code>, <code>role</code>, and <code>user</code> can be used for attributes.</p>
+<p>The <code>param_types</code> <code>type</code>, <code>sensitivity</code> and <code>category</code> can be used for aliases.</p>
+<p>The <code>param_types</code> <code>name</code> and <code>string</node> can be used interchangeably for an <code>object_name</code> in [`typetransition`](cil_type_statements.md#typetransition) and the <code>path</code> in [`filecon`](cil_file_labeling_statements.md#filecon) statements.</p></td>
 </tr>
 <tr class="even">
 <td align="left"><p><code>param_id</code></p></td>
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 8/9] libsepol/cil: Add pointers to datums to improve writing out AST
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
                   ` (6 preceding siblings ...)
  2023-09-27 19:00 ` [PATCH 7/9] secilc/docs: Fix and update the documentation for macro parameters James Carter
@ 2023-09-27 19:00 ` James Carter
  2023-09-27 19:00 ` [PATCH 9/9] libsepol/cil: Give warning for name that has different flavor James Carter
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

There are many rules in CIL that do not declare an object but
reference a datum or relate two or more datums together. In the
struct for these rules, strings are stored so that the appropriate
datums can be looked up when the rule is resolved. One example is
classcommon, which relates a kernel class and a common class. Often
the datums referenced in these rules will not be needed again, so
there are no pointers to datums in the struct for these rules.

When these rules are in a macro and make use of one of the arguments,
then we do not know the actual value to use when writing out the
AST for the resolve phase or later. Re-resolving the strings to
find the corresponding datums would be complex. If the structs for
these rules had pointers to the datums, then we could use the datums
to write out the correct values.

Add pointers to the datums in the data structures for these rules
and then use the actual datum values when writing out the AST.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil.c             | 18 ++++++++++
 libsepol/cil/src/cil_copy_ast.c    |  8 +++++
 libsepol/cil/src/cil_internal.h    | 18 ++++++++++
 libsepol/cil/src/cil_resolve_ast.c | 16 +++++++++
 libsepol/cil/src/cil_write_ast.c   | 57 +++++++++++++++++++-----------
 5 files changed, 96 insertions(+), 21 deletions(-)

diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
index ac548d15..067e28a6 100644
--- a/libsepol/cil/src/cil.c
+++ b/libsepol/cil/src/cil.c
@@ -2275,6 +2275,7 @@ void cil_blockabstract_init(struct cil_blockabstract **abstract)
 {
 	*abstract = cil_malloc(sizeof(**abstract));
 	(*abstract)->block_str = NULL;
+	(*abstract)->block = NULL;
 }
 
 void cil_in_init(struct cil_in **in)
@@ -2284,6 +2285,7 @@ void cil_in_init(struct cil_in **in)
 	cil_symtab_array_init((*in)->symtab, cil_sym_sizes[CIL_SYM_ARRAY_IN]);
 	(*in)->is_after = CIL_FALSE;
 	(*in)->block_str = NULL;
+	(*in)->block = NULL;
 }
 
 void cil_class_init(struct cil_class **class)
@@ -2304,7 +2306,9 @@ void cil_classcommon_init(struct cil_classcommon **classcommon)
 	*classcommon = cil_malloc(sizeof(**classcommon));
 
 	(*classcommon)->class_str = NULL;
+	(*classcommon)->class = NULL;
 	(*classcommon)->common_str = NULL;
+	(*classcommon)->common = NULL;
 }
 
 void cil_sid_init(struct cil_sid **sid)
@@ -2322,6 +2326,7 @@ void cil_sidcontext_init(struct cil_sidcontext **sidcontext)
 	*sidcontext = cil_malloc(sizeof(**sidcontext));
 
 	(*sidcontext)->sid_str = NULL;
+	(*sidcontext)->sid = NULL;
 	(*sidcontext)->context_str = NULL;
 	(*sidcontext)->context = NULL;
 }
@@ -2381,6 +2386,7 @@ void cil_roleattributeset_init(struct cil_roleattributeset **attrset)
 	*attrset = cil_malloc(sizeof(**attrset));
 
 	(*attrset)->attr_str = NULL;
+	(*attrset)->attr = NULL;
 	(*attrset)->str_expr = NULL;
 	(*attrset)->datum_expr = NULL;
 }
@@ -2402,6 +2408,7 @@ void cil_typeattributeset_init(struct cil_typeattributeset **attrset)
 	*attrset = cil_malloc(sizeof(**attrset));
 
 	(*attrset)->attr_str = NULL;
+	(*attrset)->attr = NULL;
 	(*attrset)->str_expr = NULL;
 	(*attrset)->datum_expr = NULL;
 }
@@ -2429,7 +2436,9 @@ void cil_aliasactual_init(struct cil_aliasactual **aliasactual)
 	*aliasactual = cil_malloc(sizeof(**aliasactual));
 
 	(*aliasactual)->alias_str = NULL;
+	(*aliasactual)->alias = NULL;
 	(*aliasactual)->actual_str = NULL;
+	(*aliasactual)->actual = NULL;
 }
 
 void cil_typepermissive_init(struct cil_typepermissive **typeperm)
@@ -2598,6 +2607,7 @@ void cil_senscat_init(struct cil_senscat **senscat)
 	*senscat = cil_malloc(sizeof(**senscat));
 
 	(*senscat)->sens_str = NULL;
+	(*senscat)->sens = NULL;
 	(*senscat)->cats = NULL;
 }
 
@@ -2768,6 +2778,7 @@ void cil_classpermissionset_init(struct cil_classpermissionset **cps)
 	*cps = cil_malloc(sizeof(**cps));
 
 	(*cps)->set_str = NULL;
+	(*cps)->set = NULL;
 	(*cps)->classperms = NULL;
 }
 
@@ -2792,7 +2803,9 @@ void cil_classmapping_init(struct cil_classmapping **mapping)
 	*mapping = cil_malloc(sizeof(**mapping));
 
 	(*mapping)->map_class_str = NULL;
+	(*mapping)->map_class = NULL;
 	(*mapping)->map_perm_str = NULL;
+	(*mapping)->map_perm = NULL;
 	(*mapping)->classperms = NULL;
 }
 
@@ -2823,6 +2836,7 @@ void cil_userattributeset_init(struct cil_userattributeset **attrset)
 	*attrset = cil_malloc(sizeof(**attrset));
 
 	(*attrset)->attr_str = NULL;
+	(*attrset)->attr = NULL;
 	(*attrset)->str_expr = NULL;
 	(*attrset)->datum_expr = NULL;
 }
@@ -2832,6 +2846,7 @@ void cil_userlevel_init(struct cil_userlevel **usrlvl)
 	*usrlvl = cil_malloc(sizeof(**usrlvl));
 
 	(*usrlvl)->user_str = NULL;
+	(*usrlvl)->user = NULL;
 	(*usrlvl)->level_str = NULL;
 	(*usrlvl)->level = NULL;
 }
@@ -2841,6 +2856,7 @@ void cil_userrange_init(struct cil_userrange **userrange)
 	*userrange = cil_malloc(sizeof(**userrange));
 
 	(*userrange)->user_str = NULL;
+	(*userrange)->user = NULL;
 	(*userrange)->range_str = NULL;
 	(*userrange)->range = NULL;
 }
@@ -2928,7 +2944,9 @@ void cil_bounds_init(struct cil_bounds **bounds)
 	*bounds = cil_malloc(sizeof(**bounds));
 
 	(*bounds)->parent_str = NULL;
+	(*bounds)->parent = NULL;
 	(*bounds)->child_str = NULL;
+	(*bounds)->child = NULL;
 }
 
 void cil_default_init(struct cil_default **def)
diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
index f025de2f..1507edb4 100644
--- a/libsepol/cil/src/cil_copy_ast.c
+++ b/libsepol/cil/src/cil_copy_ast.c
@@ -148,6 +148,7 @@ int cil_copy_blockabstract(__attribute__((unused)) struct cil_db *db, void *data
 	cil_blockabstract_init(&new);
 
 	new->block_str = orig->block_str;
+	new->block = orig->block;
 
 	*copy = new;
 
@@ -248,7 +249,9 @@ int cil_copy_classmapping(__attribute__((unused)) struct cil_db *db, void *data,
 	cil_classmapping_init(&new);
 
 	new->map_class_str = orig->map_class_str;
+	new->map_class = orig->map_class;
 	new->map_perm_str = orig->map_perm_str;
+	new->map_perm = orig->map_perm;
 
 	cil_copy_classperms_list(orig->classperms, &new->classperms);
 
@@ -311,6 +314,7 @@ int cil_copy_classpermissionset(__attribute__((unused)) struct cil_db *db, void
 	cil_classpermissionset_init(&new);
 
 	new->set_str = orig->set_str;
+	new->set = orig->set;
 
 	cil_copy_classperms_list(orig->classperms, &new->classperms);
 
@@ -327,7 +331,9 @@ int cil_copy_classcommon(__attribute__((unused)) struct cil_db *db, void *data,
 	cil_classcommon_init(&new);
 
 	new->class_str = orig->class_str;
+	new->class = orig->class;
 	new->common_str = orig->common_str;
+	new->common = orig->common;
 
 	*copy = new;
 
@@ -679,7 +685,9 @@ static int cil_copy_aliasactual(__attribute__((unused)) struct cil_db *db, void
 	cil_aliasactual_init(&new);
 
 	new->alias_str = orig->alias_str;
+	new->alias = orig->alias;
 	new->actual_str = orig->actual_str;
+	new->actual = orig->actual;
 
 	*copy = new;
 
diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
index 4193ee99..47b67c89 100644
--- a/libsepol/cil/src/cil_internal.h
+++ b/libsepol/cil/src/cil_internal.h
@@ -367,12 +367,14 @@ struct cil_blockinherit {
 
 struct cil_blockabstract {
 	char *block_str;
+	struct cil_block *block;
 };
 
 struct cil_in {
 	symtab_t symtab[CIL_SYM_NUM];
 	int is_after;
 	char *block_str;
+	struct cil_block *block;
 };
 
 struct cil_optional {
@@ -412,18 +414,23 @@ struct cil_classpermission {
 
 struct cil_classpermissionset {
 	char *set_str;
+	struct cil_classpermission *set;
 	struct cil_list *classperms;
 };
 
 struct cil_classmapping {
 	char *map_class_str;
+	struct cil_class *map_class;
 	char *map_perm_str;
+	struct cil_perm *map_perm;
 	struct cil_list *classperms;
 };
 
 struct cil_classcommon {
 	char *class_str;
+	struct cil_class *class;
 	char *common_str;
+	struct cil_class *common;
 };
 
 struct cil_alias {
@@ -433,7 +440,9 @@ struct cil_alias {
 
 struct cil_aliasactual {
 	char *alias_str;
+	void *alias;
 	char *actual_str;
+	void *actual;
 };
 
 struct cil_sid {
@@ -444,6 +453,7 @@ struct cil_sid {
 
 struct cil_sidcontext {
 	char *sid_str;
+	struct cil_sid *sid;
 	char *context_str;
 	struct cil_context *context;
 };
@@ -465,6 +475,7 @@ struct cil_userattribute {
 
 struct cil_userattributeset {
 	char *attr_str;
+	struct cil_userattribute *attr;
 	struct cil_list *str_expr;
 	struct cil_list *datum_expr;
 };
@@ -478,12 +489,14 @@ struct cil_userrole {
 
 struct cil_userlevel {
 	char *user_str;
+	void *user;
 	char *level_str;
 	struct cil_level *level;
 };
 
 struct cil_userrange {
 	char *user_str;
+	void *user;
 	char *range_str;
 	struct cil_levelrange *range;
 };
@@ -517,6 +530,7 @@ struct cil_roleattribute {
 
 struct cil_roleattributeset {
 	char *attr_str;
+	struct cil_roleattribute *attr;
 	struct cil_list *str_expr;
 	struct cil_list *datum_expr;
 };
@@ -549,6 +563,7 @@ struct cil_typeattribute {
 
 struct cil_typeattributeset {
 	char *attr_str;
+	struct cil_typeattribute *attr;
 	struct cil_list *str_expr;
 	struct cil_list *datum_expr;
 };
@@ -697,6 +712,7 @@ struct cil_catset {
 
 struct cil_senscat {
 	char *sens_str;
+	struct cil_sens *sens;
 	struct cil_cats *cats;
 };
 
@@ -925,7 +941,9 @@ struct cil_policycap {
 
 struct cil_bounds {
 	char *parent_str;
+	void *parent;
 	char *child_str;
+	void *child;
 };
 
 /* Ensure that CIL uses the same values as sepol policydb.h */
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
index d52c106a..4e8a375d 100644
--- a/libsepol/cil/src/cil_resolve_ast.c
+++ b/libsepol/cil/src/cil_resolve_ast.c
@@ -216,6 +216,7 @@ int cil_resolve_classpermissionset(struct cil_tree_node *current, struct cil_cla
 	}
 
 	cp = (struct cil_classpermission *)datum;
+	cps->set = cp;
 
 	if (cp->classperms == NULL) {
 		cil_list_init(&cp->classperms, CIL_CLASSPERMS);
@@ -524,6 +525,7 @@ static int cil_resolve_aliasactual(struct cil_tree_node *current, struct cil_db
 	}
 
 	alias = (struct cil_alias *)alias_datum;
+	aliasactual->alias = alias_datum;
 
 	if (alias->actual != NULL) {
 		cil_log(CIL_ERR, "%s %s cannot bind more than one value\n", cil_node_to_string(NODE(alias_datum)), alias_datum->name);
@@ -532,6 +534,7 @@ static int cil_resolve_aliasactual(struct cil_tree_node *current, struct cil_db
 	}
 
 	alias->actual = actual_datum;
+	aliasactual->actual = actual_datum;
 
 	return SEPOL_OK;
 
@@ -773,6 +776,9 @@ int cil_resolve_classcommon(struct cil_tree_node *current, struct cil_db *db)
 
 	class->common = common;
 
+	clscom->class = class;
+	clscom->common = common;
+
 	cil_symtab_map(&class->perms, __class_update_perm_values, &common->num_perms);
 
 	class->num_perms += common->num_perms;
@@ -802,6 +808,7 @@ int cil_resolve_classmapping(struct cil_tree_node *current, struct cil_db *db)
 		goto exit;
 	}
 	map = (struct cil_class*)datum;
+	mapping->map_class = map;
 
 	rc = cil_symtab_get_datum(&map->perms, mapping->map_perm_str, &datum);
 	if (rc != SEPOL_OK) {
@@ -809,6 +816,7 @@ int cil_resolve_classmapping(struct cil_tree_node *current, struct cil_db *db)
 	}
 
 	mp = (struct cil_perm*)datum;
+	mapping->map_perm = mp;
 
 	rc = cil_resolve_classperms_list(current, mapping->classperms, db);
 	if (rc != SEPOL_OK) {
@@ -877,6 +885,7 @@ int cil_resolve_userlevel(struct cil_tree_node *current, struct cil_db *db)
 	}
 
 	user = (struct cil_user*)user_datum;
+	usrlvl->user = user;
 
 	if (usrlvl->level_str != NULL) {
 		rc = cil_resolve_name(current, usrlvl->level_str, CIL_SYM_LEVELS, db, &lvl_datum);
@@ -930,6 +939,7 @@ int cil_resolve_userrange(struct cil_tree_node *current, struct cil_db *db)
 	}
 
 	user = (struct cil_user*)user_datum;
+	userrange->user = user;
 
 	if (userrange->range_str != NULL) {
 		rc = cil_resolve_name(current, userrange->range_str, CIL_SYM_LEVELRANGES, db, &range_datum);
@@ -2190,6 +2200,7 @@ int cil_resolve_sidcontext(struct cil_tree_node *current, struct cil_db *db)
 		goto exit;
 	}
 	sid = (struct cil_sid*)sid_datum;
+	sidcon->sid = sid;
 
 	if (sidcon->context_str != NULL) {
 		rc = cil_resolve_name(current, sidcon->context_str, CIL_SYM_CONTEXTS, db, &context_datum);
@@ -2315,6 +2326,8 @@ static int cil_resolve_blockabstract(struct cil_tree_node *current, struct cil_d
 		goto exit;
 	}
 
+	abstract->block = (struct cil_block *)block_datum;
+
 	cil_list_append(abstract_blocks, CIL_NODE, block_node);
 
 	return SEPOL_OK;
@@ -2335,6 +2348,8 @@ int cil_resolve_in(struct cil_tree_node *current, struct cil_db *db)
 		goto exit;
 	}
 
+	in->block = (struct cil_block *)block_datum;
+
 	block_node = NODE(block_datum);
 
 	if (block_node->flavor == CIL_OPTIONAL) {
@@ -3364,6 +3379,7 @@ int cil_resolve_userattributeset(struct cil_tree_node *current, struct cil_db *d
 		goto exit;
 	}
 	attr = (struct cil_userattribute*)attr_datum;
+	attrusers->attr = attr;
 
 	rc = cil_resolve_expr(CIL_USERATTRIBUTESET, attrusers->str_expr, &attrusers->datum_expr, current, db);
 	if (rc != SEPOL_OK) {
diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c
index 161c53e9..f4f9f167 100644
--- a/libsepol/cil/src/cil_write_ast.c
+++ b/libsepol/cil/src/cil_write_ast.c
@@ -588,7 +588,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_IN: {
 		struct cil_in *in = node->data;
-		fprintf(out, "(in %s", in->block_str);
+		fprintf(out, "(in %s", datum_or_str(DATUM(in->block), in->block_str));
 		if (!node->cl_head)
 			fprintf(out, ")");
 		fprintf(out, "\n");
@@ -667,7 +667,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_BLOCKABSTRACT: {
 		struct cil_blockabstract *abstract = node->data;
-		fprintf(out, "(blockabstract %s)\n", abstract->block_str);
+		fprintf(out, "(blockabstract %s)\n", datum_or_str(DATUM(abstract->block), abstract->block_str));
 		break;
 	}
 	case CIL_MLS: {
@@ -788,7 +788,9 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_CLASSCOMMON: {
 		struct cil_classcommon *cc = node->data;
-		fprintf(out, "(classcommon %s %s)\n", cc->class_str, cc->common_str);
+		fprintf(out, "(classcommon %s ", datum_or_str(DATUM(cc->class), cc->class_str));
+		fprintf(out, "%s", datum_or_str(DATUM(cc->common), cc->common_str));
+		fprintf(out, ")\n");
 		break;
 	}
 	case CIL_CLASSPERMISSION: {
@@ -798,7 +800,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_CLASSPERMISSIONSET: {
 		struct cil_classpermissionset *cps = node->data;
-		fprintf(out, "(classpermissionset %s ", cps->set_str);
+		fprintf(out, "(classpermissionset %s ", datum_or_str(DATUM(cps->set), cps->set_str));
 		write_classperms_list(out, cps->classperms);
 		fprintf(out, ")\n");
 		break;
@@ -812,7 +814,8 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_CLASSMAPPING: {
 		struct cil_classmapping *mapping = node->data;
-		fprintf(out, "(classmapping %s %s ", mapping->map_class_str, mapping->map_perm_str);
+		fprintf(out, "(classmapping %s ", datum_or_str(DATUM(mapping->map_class), mapping->map_class_str));
+		fprintf(out, "%s ", datum_or_str(DATUM(mapping->map_perm), mapping->map_perm_str));
 		write_classperms_list(out, mapping->classperms);
 		fprintf(out, ")\n");
 		break;
@@ -833,7 +836,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_SIDCONTEXT: {
 		struct cil_sidcontext *sidcon = node->data;
-		fprintf(out, "(sidcontext %s ", sidcon->sid_str);
+		fprintf(out, "(sidcontext %s ", datum_or_str(DATUM(sidcon->sid), sidcon->sid_str));
 		if (sidcon->context)
 			write_context(out, sidcon->context, CIL_TRUE);
 		else
@@ -874,7 +877,9 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_SENSALIASACTUAL: {
 		struct cil_aliasactual *aliasactual = node->data;
-		fprintf(out, "(sensitivityaliasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str);
+		fprintf(out, "(sensitivityaliasactual %s ", datum_or_str(DATUM(aliasactual->alias), aliasactual->alias_str));
+		fprintf(out, "%s", datum_or_str(DATUM(aliasactual->actual), aliasactual->actual_str));
+		fprintf(out, ")\n");
 		break;
 	}
 	case CIL_CAT: {
@@ -889,7 +894,9 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_CATALIASACTUAL: {
 		struct cil_aliasactual *aliasactual = node->data;
-		fprintf(out, "(categoryaliasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str);
+		fprintf(out, "(categoryaliasactual %s ", datum_or_str(DATUM(aliasactual->alias), aliasactual->alias_str));
+		fprintf(out, "%s", datum_or_str(DATUM(aliasactual->actual), aliasactual->actual_str));
+		fprintf(out, ")\n");
 		break;
 	}
 	case CIL_CATSET: {
@@ -913,7 +920,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	case CIL_SENSCAT: {
 		struct cil_senscat *senscat = node->data;
 		fprintf(out, "(sensitivitycategory ");
-		fprintf(out, "%s ", senscat->sens_str);
+		fprintf(out, "%s ", datum_or_str(DATUM(senscat->sens), senscat->sens_str));
 		write_cats(out, senscat->cats);
 		fprintf(out, ")\n");
 		break;
@@ -955,7 +962,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_USERATTRIBUTESET: {
 		struct cil_userattributeset *attr = node->data;
-		fprintf(out, "(userattributeset %s ", attr->attr_str);
+		fprintf(out, "(userattributeset %s ", datum_or_str(DATUM(attr->attr), attr->attr_str));
 		if (attr->datum_expr)
 			write_expr(out, attr->datum_expr);
 		else
@@ -966,14 +973,14 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	case CIL_USERROLE: {
 		struct cil_userrole *userrole = node->data;
 		fprintf(out, "(userrole ");
-		fprintf(out, "%s ", datum_or_str(userrole->user, userrole->user_str));
-		fprintf(out, "%s", datum_or_str(userrole->role, userrole->role_str));
+		fprintf(out, "%s ", datum_or_str(DATUM(userrole->user), userrole->user_str));
+		fprintf(out, "%s", datum_or_str(DATUM(userrole->role), userrole->role_str));
 		fprintf(out, ")\n");
 		break;
 	}
 	case CIL_USERLEVEL: {
 		struct cil_userlevel *userlevel = node->data;
-		fprintf(out, "(userlevel %s ", userlevel->user_str);
+		fprintf(out, "(userlevel %s ", datum_or_str(DATUM(userlevel->user), userlevel->user_str));
 		if (userlevel->level)
 			write_level(out, userlevel->level, CIL_TRUE);
 		else
@@ -983,7 +990,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_USERRANGE: {
 		struct cil_userrange *userrange = node->data;
-		fprintf(out, "(userrange %s ", userrange->user_str);
+		fprintf(out, "(userrange %s ", datum_or_str(DATUM(userrange->user), userrange->user_str));
 		if (userrange->range)
 			write_range(out, userrange->range, CIL_TRUE);
 		else
@@ -993,7 +1000,9 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_USERBOUNDS: {
 		struct cil_bounds *bounds = node->data;
-		fprintf(out, "(userbounds %s %s)\n", bounds->parent_str, bounds->child_str);
+		fprintf(out, "(userbounds ");
+		fprintf(out, "%s ", datum_or_str(DATUM(bounds->parent), bounds->parent_str));
+		fprintf(out, "%s)\n", datum_or_str(DATUM(bounds->child), bounds->child_str));
 		break;
 	}
 	case CIL_USERPREFIX: {
@@ -1035,7 +1044,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_ROLEATTRIBUTESET: {
 		struct cil_roleattributeset *attr = node->data;
-		fprintf(out, "(roleattributeset %s ", attr->attr_str);
+		fprintf(out, "(roleattributeset %s ", datum_or_str(DATUM(attr->attr), attr->attr_str));
 		if (attr->datum_expr)
 			write_expr(out, attr->datum_expr);
 		else
@@ -1052,8 +1061,10 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 		break;
 	}
 	case CIL_ROLEBOUNDS: {
-		struct cil_bounds *bnds = node->data;
-		fprintf(out, "(rolebounds %s %s)\n", bnds->parent_str, bnds->child_str);
+		struct cil_bounds *bounds = node->data;
+		fprintf(out, "(rolebounds ");
+		fprintf(out, "%s ", datum_or_str(DATUM(bounds->parent), bounds->parent_str));
+		fprintf(out, "%s)\n", datum_or_str(DATUM(bounds->child), bounds->child_str));
 		break;
 	}
 	case CIL_TYPE: {
@@ -1066,7 +1077,9 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_TYPEALIASACTUAL: {
 		struct cil_aliasactual *aliasactual = node->data;
-		fprintf(out, "(typealiasactual %s %s)\n", aliasactual->alias_str, aliasactual->actual_str);
+		fprintf(out, "(typealiasactual %s ", datum_or_str(DATUM(aliasactual->alias), aliasactual->alias_str));
+		fprintf(out, "%s", datum_or_str(DATUM(aliasactual->actual), aliasactual->actual_str));
+		fprintf(out, ")\n");
 		break;
 	}
 	case CIL_TYPEATTRIBUTE: {
@@ -1075,7 +1088,7 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_TYPEATTRIBUTESET: {
 		struct cil_typeattributeset *attr = node->data;
-		fprintf(out, "(typeattributeset %s ", attr->attr_str);
+		fprintf(out, "(typeattributeset %s ", datum_or_str(DATUM(attr->attr), attr->attr_str));
 		if (attr->datum_expr)
 			write_expr(out, attr->datum_expr);
 		else
@@ -1102,7 +1115,9 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
 	}
 	case CIL_TYPEBOUNDS: {
 		struct cil_bounds *bounds = node->data;
-		fprintf(out, "(typebounds %s %s)\n", bounds->parent_str, bounds->child_str);
+		fprintf(out, "(typebounds ");
+		fprintf(out, "%s ", datum_or_str(DATUM(bounds->parent), bounds->parent_str));
+		fprintf(out, "%s)\n", datum_or_str(DATUM(bounds->child), bounds->child_str));
 		break;
 	}
 	case CIL_ROLEALLOW: {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 9/9] libsepol/cil: Give warning for name that has different flavor
  2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
                   ` (7 preceding siblings ...)
  2023-09-27 19:00 ` [PATCH 8/9] libsepol/cil: Add pointers to datums to improve writing out AST James Carter
@ 2023-09-27 19:00 ` James Carter
  8 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-09-27 19:00 UTC (permalink / raw)
  To: selinux; +Cc: James Carter

While still giving an error if there is a declaration with the
same flavor and name as a macro parameter, now give a warning in
the case where there is a declaration with the same name as a
macro parameter, but with a different flavor.

Example/
  (macro m1 ((string ARG1))
    (type ARG1)
    (allow ARG1 ARG1 (CLASS (PERM)))
    (typetransition t1a t1b CLASS ARG1 t1c)
  )
  (call m1 (foo))

  This will result in the following equivalent code:
  (type ARG1)
  (allow ARG1 ARG1 (CLASS (PERM)))
  (typetransition t1a t1b CLASS "foo" t1c)

  With the warning (if using "-v"), "Declaration of type ARG1 has
  same name as a macro parameter with a different flavor"

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libsepol/cil/src/cil_verify.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
index 45bf4689..0c6d50a1 100644
--- a/libsepol/cil/src/cil_verify.c
+++ b/libsepol/cil/src/cil_verify.c
@@ -405,10 +405,12 @@ int cil_verify_decl_does_not_shadow_macro_parameter(struct cil_macro *macro, str
 	if (param_list != NULL) {
 		cil_list_for_each(item, param_list) {
 			struct cil_param *param = item->data;
-			if (param->flavor == node->flavor) {
-				if (param->str == name) {
-					cil_log(CIL_ERR, "%s %s shadows a macro parameter in macro declaration\n", cil_node_to_string(node), name);
+			if (param->str == name) {
+				if (param->flavor == node->flavor) {
+					cil_log(CIL_ERR, "Declaration of %s %s shadows a macro parameter with the same flavor\n", cil_node_to_string(node), name);
 					return SEPOL_ERR;
+				} else {
+					cil_log(CIL_WARN, "Declaration of %s %s has same name as a macro parameter with a different flavor\n", cil_node_to_string(node), name);
 				}
 			}
 		}
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-09-27 19:00 ` [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void * James Carter
@ 2023-09-27 19:27   ` Daniel Burgener
  2023-09-27 20:41     ` James Carter
  0 siblings, 1 reply; 16+ messages in thread
From: Daniel Burgener @ 2023-09-27 19:27 UTC (permalink / raw)
  To: James Carter, selinux

> @@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
>   	return rc;
>   }
>   
> -static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
> +static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
>   {
>   	int rc = SEPOL_OK;
> -	struct cil_args_resolve *args = extra_args;
> +	struct cil_db *db = args->db;
>   	enum cil_pass pass = 0;
>   
> -	if (node == NULL || args == NULL) {
> -		goto exit;
> -	}
> -

Is deleting the "node == NULL" part of this check intended here?  It 
seems unrelated to the rest of the commit, and it's not locally obvious 
that it's safe.



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-09-27 19:27   ` Daniel Burgener
@ 2023-09-27 20:41     ` James Carter
  2023-09-28 17:10       ` Daniel Burgener
  0 siblings, 1 reply; 16+ messages in thread
From: James Carter @ 2023-09-27 20:41 UTC (permalink / raw)
  To: Daniel Burgener; +Cc: selinux

On Wed, Sep 27, 2023 at 3:27 PM Daniel Burgener
<dburgener@linux.microsoft.com> wrote:
>
> > @@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
> >       return rc;
> >   }
> >
> > -static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
> > +static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
> >   {
> >       int rc = SEPOL_OK;
> > -     struct cil_args_resolve *args = extra_args;
> > +     struct cil_db *db = args->db;
> >       enum cil_pass pass = 0;
> >
> > -     if (node == NULL || args == NULL) {
> > -             goto exit;
> > -     }
> > -
>
> Is deleting the "node == NULL" part of this check intended here?  It
> seems unrelated to the rest of the commit, and it's not locally obvious
> that it's safe.

You are right. It is not related to the rest of the commit. There are
a bunch of these sorts of checks that are useless and really annoy me.
The function __cil_resolve_ast_node() is called once from
__cil_resolve_ast_node_helper() and neither node nor args can be NULL.
Since I was changing something nearby, I guess I couldn't resist. I
can leave it in, if people prefer. It doesn't cause any harm, other
than annoying me.

Jim

>
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-09-27 20:41     ` James Carter
@ 2023-09-28 17:10       ` Daniel Burgener
  2023-11-01  9:45         ` Petr Lautrbach
  0 siblings, 1 reply; 16+ messages in thread
From: Daniel Burgener @ 2023-09-28 17:10 UTC (permalink / raw)
  To: James Carter; +Cc: selinux

On 9/27/2023 4:41 PM, James Carter wrote:
> On Wed, Sep 27, 2023 at 3:27 PM Daniel Burgener
> <dburgener@linux.microsoft.com> wrote:
>>
>>> @@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
>>>        return rc;
>>>    }
>>>
>>> -static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
>>> +static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
>>>    {
>>>        int rc = SEPOL_OK;
>>> -     struct cil_args_resolve *args = extra_args;
>>> +     struct cil_db *db = args->db;
>>>        enum cil_pass pass = 0;
>>>
>>> -     if (node == NULL || args == NULL) {
>>> -             goto exit;
>>> -     }
>>> -
>>
>> Is deleting the "node == NULL" part of this check intended here?  It
>> seems unrelated to the rest of the commit, and it's not locally obvious
>> that it's safe.
> 
> You are right. It is not related to the rest of the commit. There are
> a bunch of these sorts of checks that are useless and really annoy me.
> The function __cil_resolve_ast_node() is called once from
> __cil_resolve_ast_node_helper() and neither node nor args can be NULL.
> Since I was changing something nearby, I guess I couldn't resist. I
> can leave it in, if people prefer. It doesn't cause any harm, other
> than annoying me.
> 

As is is fine by me.  Your explanation makes sense.  I mostly wanted to 
make sure it was reasoned out rather than an accidental drop, but now 
that you point it out, it does look impossible for this to be NULL.

Reviewed-by: Daniel Burgener <dburgener@linux.microsoft.com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-09-28 17:10       ` Daniel Burgener
@ 2023-11-01  9:45         ` Petr Lautrbach
  2023-11-17 15:29           ` James Carter
  0 siblings, 1 reply; 16+ messages in thread
From: Petr Lautrbach @ 2023-11-01  9:45 UTC (permalink / raw)
  To: Daniel Burgener, James Carter; +Cc: selinux

Daniel Burgener <dburgener@linux.microsoft.com> writes:

> On 9/27/2023 4:41 PM, James Carter wrote:
>> On Wed, Sep 27, 2023 at 3:27 PM Daniel Burgener
>> <dburgener@linux.microsoft.com> wrote:
>>>
>>>> @@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
>>>>        return rc;
>>>>    }
>>>>
>>>> -static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
>>>> +static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
>>>>    {
>>>>        int rc = SEPOL_OK;
>>>> -     struct cil_args_resolve *args = extra_args;
>>>> +     struct cil_db *db = args->db;
>>>>        enum cil_pass pass = 0;
>>>>
>>>> -     if (node == NULL || args == NULL) {
>>>> -             goto exit;
>>>> -     }
>>>> -
>>>
>>> Is deleting the "node == NULL" part of this check intended here?  It
>>> seems unrelated to the rest of the commit, and it's not locally obvious
>>> that it's safe.
>> 
>> You are right. It is not related to the rest of the commit. There are
>> a bunch of these sorts of checks that are useless and really annoy me.
>> The function __cil_resolve_ast_node() is called once from
>> __cil_resolve_ast_node_helper() and neither node nor args can be NULL.
>> Since I was changing something nearby, I guess I couldn't resist. I
>> can leave it in, if people prefer. It doesn't cause any harm, other
>> than annoying me.
>> 
>
> As is is fine by me.  Your explanation makes sense.  I mostly wanted to 
> make sure it was reasoned out rather than an accidental drop, but now 
> that you point it out, it does look impossible for this to be NULL.
>
> Reviewed-by: Daniel Burgener <dburgener@linux.microsoft.com>

Acked-by: Petr Lautrbach <lautrbach@redhat.com>


Petr


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-11-01  9:45         ` Petr Lautrbach
@ 2023-11-17 15:29           ` James Carter
  2023-11-21 14:10             ` James Carter
  0 siblings, 1 reply; 16+ messages in thread
From: James Carter @ 2023-11-17 15:29 UTC (permalink / raw)
  To: Petr Lautrbach; +Cc: Daniel Burgener, selinux

On Wed, Nov 1, 2023 at 5:45 AM Petr Lautrbach <lautrbach@redhat.com> wrote:
>
> Daniel Burgener <dburgener@linux.microsoft.com> writes:
>
> > On 9/27/2023 4:41 PM, James Carter wrote:
> >> On Wed, Sep 27, 2023 at 3:27 PM Daniel Burgener
> >> <dburgener@linux.microsoft.com> wrote:
> >>>
> >>>> @@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
> >>>>        return rc;
> >>>>    }
> >>>>
> >>>> -static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
> >>>> +static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
> >>>>    {
> >>>>        int rc = SEPOL_OK;
> >>>> -     struct cil_args_resolve *args = extra_args;
> >>>> +     struct cil_db *db = args->db;
> >>>>        enum cil_pass pass = 0;
> >>>>
> >>>> -     if (node == NULL || args == NULL) {
> >>>> -             goto exit;
> >>>> -     }
> >>>> -
> >>>
> >>> Is deleting the "node == NULL" part of this check intended here?  It
> >>> seems unrelated to the rest of the commit, and it's not locally obvious
> >>> that it's safe.
> >>
> >> You are right. It is not related to the rest of the commit. There are
> >> a bunch of these sorts of checks that are useless and really annoy me.
> >> The function __cil_resolve_ast_node() is called once from
> >> __cil_resolve_ast_node_helper() and neither node nor args can be NULL.
> >> Since I was changing something nearby, I guess I couldn't resist. I
> >> can leave it in, if people prefer. It doesn't cause any harm, other
> >> than annoying me.
> >>
> >
> > As is is fine by me.  Your explanation makes sense.  I mostly wanted to
> > make sure it was reasoned out rather than an accidental drop, but now
> > that you point it out, it does look impossible for this to be NULL.
> >
> > Reviewed-by: Daniel Burgener <dburgener@linux.microsoft.com>
>
> Acked-by: Petr Lautrbach <lautrbach@redhat.com>
>
>
> Petr
>

I plan on merging this series next week, unless someone objects.
Jim

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void *
  2023-11-17 15:29           ` James Carter
@ 2023-11-21 14:10             ` James Carter
  0 siblings, 0 replies; 16+ messages in thread
From: James Carter @ 2023-11-21 14:10 UTC (permalink / raw)
  To: Petr Lautrbach; +Cc: Daniel Burgener, selinux

On Fri, Nov 17, 2023 at 10:29 AM James Carter <jwcart2@gmail.com> wrote:
>
> On Wed, Nov 1, 2023 at 5:45 AM Petr Lautrbach <lautrbach@redhat.com> wrote:
> >
> > Daniel Burgener <dburgener@linux.microsoft.com> writes:
> >
> > > On 9/27/2023 4:41 PM, James Carter wrote:
> > >> On Wed, Sep 27, 2023 at 3:27 PM Daniel Burgener
> > >> <dburgener@linux.microsoft.com> wrote:
> > >>>
> > >>>> @@ -3661,21 +3615,17 @@ static int cil_check_for_bad_inheritance(struct cil_tree_node *node)
> > >>>>        return rc;
> > >>>>    }
> > >>>>
> > >>>> -static int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
> > >>>> +static int __cil_resolve_ast_node(struct cil_tree_node *node, struct cil_args_resolve *args)
> > >>>>    {
> > >>>>        int rc = SEPOL_OK;
> > >>>> -     struct cil_args_resolve *args = extra_args;
> > >>>> +     struct cil_db *db = args->db;
> > >>>>        enum cil_pass pass = 0;
> > >>>>
> > >>>> -     if (node == NULL || args == NULL) {
> > >>>> -             goto exit;
> > >>>> -     }
> > >>>> -
> > >>>
> > >>> Is deleting the "node == NULL" part of this check intended here?  It
> > >>> seems unrelated to the rest of the commit, and it's not locally obvious
> > >>> that it's safe.
> > >>
> > >> You are right. It is not related to the rest of the commit. There are
> > >> a bunch of these sorts of checks that are useless and really annoy me.
> > >> The function __cil_resolve_ast_node() is called once from
> > >> __cil_resolve_ast_node_helper() and neither node nor args can be NULL.
> > >> Since I was changing something nearby, I guess I couldn't resist. I
> > >> can leave it in, if people prefer. It doesn't cause any harm, other
> > >> than annoying me.
> > >>
> > >
> > > As is is fine by me.  Your explanation makes sense.  I mostly wanted to
> > > make sure it was reasoned out rather than an accidental drop, but now
> > > that you point it out, it does look impossible for this to be NULL.
> > >
> > > Reviewed-by: Daniel Burgener <dburgener@linux.microsoft.com>
> >
> > Acked-by: Petr Lautrbach <lautrbach@redhat.com>
> >
> >
> > Petr
> >
>
> I plan on merging this series next week, unless someone objects.
> Jim

These nine patches have been merged.
Jim

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2023-11-21 14:10 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-27 19:00 [PATCH 0/9] CIL Cleanups and Improved Argument handling James Carter
2023-09-27 19:00 ` [PATCH 1/9] libsepol/cil: Use struct cil_db * instead of void * James Carter
2023-09-27 19:27   ` Daniel Burgener
2023-09-27 20:41     ` James Carter
2023-09-28 17:10       ` Daniel Burgener
2023-11-01  9:45         ` Petr Lautrbach
2023-11-17 15:29           ` James Carter
2023-11-21 14:10             ` James Carter
2023-09-27 19:00 ` [PATCH 2/9] libsepol/cil: Refactor and improve handling of order rules James Carter
2023-09-27 19:00 ` [PATCH 3/9] libsepol/cil: Allow IP address and mask values to be directly written James Carter
2023-09-27 19:00 ` [PATCH 4/9] secilc/docs: Update syntax for IP addresses and nodecon James Carter
2023-09-27 19:00 ` [PATCH 5/9] libsepol/cil: Refactor Named Type Transition Filename Creation James Carter
2023-09-27 19:00 ` [PATCH 6/9] libsepol/cil: Allow paths in filecon rules to be passed as arguments James Carter
2023-09-27 19:00 ` [PATCH 7/9] secilc/docs: Fix and update the documentation for macro parameters James Carter
2023-09-27 19:00 ` [PATCH 8/9] libsepol/cil: Add pointers to datums to improve writing out AST James Carter
2023-09-27 19:00 ` [PATCH 9/9] libsepol/cil: Give warning for name that has different flavor James Carter

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.