psss / rpms / libsepol

Forked from rpms/libsepol 5 years ago
Clone
71b1a80
diff --git libsepol-2.5/Android.mk libsepol-2.5/Android.mk
0a1d1e5
index a43b343..6d89f17 100644
71b1a80
--- libsepol-2.5/Android.mk
71b1a80
+++ libsepol-2.5/Android.mk
0a1d1e5
@@ -64,14 +64,11 @@ cil_src_files := \
71b1a80
 	cil/src/cil_verify.c
71b1a80
 
71b1a80
 common_cflags := \
71b1a80
+	-D_GNU_SOURCE \
71b1a80
 	-Wall -W -Wundef \
71b1a80
 	-Wshadow -Wmissing-noreturn \
71b1a80
 	-Wmissing-format-attribute
0a1d1e5
 
0a1d1e5
-ifeq ($(HOST_OS), darwin)
0a1d1e5
-common_cflags += -DDARWIN
0a1d1e5
-endif
0a1d1e5
-
0a1d1e5
 common_includes := \
0a1d1e5
 	$(LOCAL_PATH)/include/ \
0a1d1e5
 	$(LOCAL_PATH)/src/ \
a7ec325
diff --git libsepol-2.5/ChangeLog libsepol-2.5/ChangeLog
aac9abe
index ace3d54..b45f3ad 100644
a7ec325
--- libsepol-2.5/ChangeLog
a7ec325
+++ libsepol-2.5/ChangeLog
aac9abe
@@ -1,3 +1,23 @@
aac9abe
+	* Warn instead of fail if permission is not resolved, from James Carter.
aac9abe
+	* Ignore object_r when adding userrole mappings to policydb, from Steve Lawrence.
5ec2ad1
+	* Add missing return to sepol_node_query(), from Petr Lautrbach.
5ec2ad1
+	* Add missing <stdarg.h> include, from Thomas Petazzoni.
44e2d26
+	* Correctly detect unknown classes in sepol_string_to_security_class, from Joshua Brindle.
44e2d26
+	* Sort object files for deterministic linking order, from Laurent Bigonville.
44e2d26
+	* Fix neverallowxperm checking on attributes, from Jeff Vander Stoep.
44e2d26
+	* Remove libsepol.map when cleaning, from Nicolas Iooss.
44e2d26
+	* Add high-level language line marking support to CIL, from James Carter.
0a1d1e5
+	* Change logic of bounds checking to match change in kernel, from James Carter.
0a1d1e5
+	* Fix multiple spelling errors, from Laurent Bigonville.
d88ffa1
+	* Only apply bounds checking to source types in rules, from Stephen Smalley.
d88ffa1
+	* Fix CIL and not add an attribute as a type in the attr_type_map, from James Carter
71b1a80
+	* Build policy on systems not supporting DCCP protocol, from Richard Haines.
71b1a80
+	* Fix extended permissions neverallow checking, from Jeff Vander Stoep.
71b1a80
+	* Fix CIL neverallow and bounds checking, from James Carter
71b1a80
+	* Android.mk: Add -D_GNU_SOURCE to common_cflags, from Nick Kralevich.
a7ec325
+	* Add support for portcon dccp protocol, from Richard Haines
a7ec325
+	* Fix bug in CIL when resetting classes, from Steve Lawrence
a7ec325
+
a7ec325
 2.5 2016-02-23
a7ec325
 	* Fix unused variable annotations, from Nicolas Iooss.
a7ec325
 	* Fix uninitialized variable in CIL, from Nicolas Iooss.
a7ec325
diff --git libsepol-2.5/cil/src/cil.c libsepol-2.5/cil/src/cil.c
44e2d26
index afdc240..929ab19 100644
a7ec325
--- libsepol-2.5/cil/src/cil.c
a7ec325
+++ libsepol-2.5/cil/src/cil.c
a7ec325
@@ -108,6 +108,7 @@ static void cil_init_keys(void)
a7ec325
 	CIL_KEY_STAR = cil_strpool_add("*");
a7ec325
 	CIL_KEY_UDP = cil_strpool_add("udp");
a7ec325
 	CIL_KEY_TCP = cil_strpool_add("tcp");
a7ec325
+	CIL_KEY_DCCP = cil_strpool_add("dccp");
a7ec325
 	CIL_KEY_AUDITALLOW = cil_strpool_add("auditallow");
a7ec325
 	CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif");
a7ec325
 	CIL_KEY_ALLOW = cil_strpool_add("allow");
44e2d26
@@ -232,6 +233,9 @@ static void cil_init_keys(void)
44e2d26
 	CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx");
44e2d26
 	CIL_KEY_IOCTL = cil_strpool_add("ioctl");
44e2d26
 	CIL_KEY_UNORDERED = cil_strpool_add("unordered");
44e2d26
+	CIL_KEY_SRC_INFO = cil_strpool_add("<src_info>");
44e2d26
+	CIL_KEY_SRC_CIL = cil_strpool_add("<src_cil>");
44e2d26
+	CIL_KEY_SRC_HLL = cil_strpool_add("<src_hll>");
44e2d26
 }
44e2d26
 
44e2d26
 void cil_db_init(struct cil_db **db)
44e2d26
@@ -756,6 +760,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
44e2d26
 	case CIL_MLS:
44e2d26
 		cil_destroy_mls(*data);
44e2d26
 		break;
44e2d26
+	case CIL_SRC_INFO:
44e2d26
+		cil_destroy_src_info(*data);
44e2d26
+		break;
44e2d26
 	case CIL_OP:
44e2d26
 	case CIL_CONS_OPERAND:
44e2d26
 		break;
44e2d26
@@ -763,8 +770,8 @@ void cil_destroy_data(void **data, enum cil_flavor flavor)
44e2d26
 		cil_log(CIL_INFO, "Unknown data flavor: %d\n", flavor);
44e2d26
 		break;
44e2d26
 	}
44e2d26
-	
44e2d26
-	*data = NULL;		
44e2d26
+
44e2d26
+	*data = NULL;
44e2d26
 }
44e2d26
 
44e2d26
 int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_index)
44e2d26
@@ -1108,6 +1115,8 @@ const char * cil_node_to_string(struct cil_tree_node *node)
44e2d26
 		return CIL_KEY_HANDLEUNKNOWN;
44e2d26
 	case CIL_MLS:
44e2d26
 		return CIL_KEY_MLS;
44e2d26
+	case CIL_SRC_INFO:
44e2d26
+		return CIL_KEY_SRC_INFO;
44e2d26
 	case CIL_ALL:
44e2d26
 		return CIL_KEY_ALL;
44e2d26
 	case CIL_RANGE:
44e2d26
@@ -1755,8 +1764,7 @@ int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_s
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Failed to get symtab from node at line %d of %s\n",
44e2d26
-			ast_node->line, ast_node->path);
44e2d26
+	cil_tree_log(ast_node, CIL_ERR, "Failed to get symtab from node");
44e2d26
 	return SEPOL_ERR;	
44e2d26
 }
44e2d26
 
44e2d26
@@ -2553,3 +2561,10 @@ void cil_mls_init(struct cil_mls **mls)
44e2d26
 	*mls = cil_malloc(sizeof(**mls));
44e2d26
 	(*mls)->value = 0;
44e2d26
 }
44e2d26
+
44e2d26
+void cil_src_info_init(struct cil_src_info **info)
44e2d26
+{
44e2d26
+	*info = cil_malloc(sizeof(**info));
44e2d26
+	(*info)->is_cil = 0;
44e2d26
+	(*info)->path = NULL;
44e2d26
+}
a7ec325
diff --git libsepol-2.5/cil/src/cil_binary.c libsepol-2.5/cil/src/cil_binary.c
aac9abe
index f749e53..46fea4b 100644
a7ec325
--- libsepol-2.5/cil/src/cil_binary.c
a7ec325
+++ libsepol-2.5/cil/src/cil_binary.c
71b1a80
@@ -31,6 +31,9 @@
71b1a80
 #include <stdio.h>
71b1a80
 #include <assert.h>
71b1a80
 #include <netinet/in.h>
71b1a80
+#ifndef IPPROTO_DCCP
71b1a80
+#define IPPROTO_DCCP 33
71b1a80
+#endif
71b1a80
 
71b1a80
 #include <sepol/policydb/policydb.h>
71b1a80
 #include <sepol/policydb/polcaps.h>
d88ffa1
@@ -606,9 +609,11 @@ int __cil_typeattr_bitmap_init(policydb_t *pdb)
d88ffa1
 			rc = SEPOL_ERR;
d88ffa1
 			goto exit;
d88ffa1
 		}
d88ffa1
-		if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) {
d88ffa1
-			rc = SEPOL_ERR;
d88ffa1
-			goto exit;
d88ffa1
+		if (pdb->type_val_to_struct[i] && pdb->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
d88ffa1
+			if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) {
d88ffa1
+				rc = SEPOL_ERR;
d88ffa1
+				goto exit;
d88ffa1
+			}
d88ffa1
 		}
d88ffa1
 
d88ffa1
 	}
aac9abe
@@ -749,6 +754,12 @@ int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct ci
aac9abe
 				goto exit;
aac9abe
 			}
aac9abe
 
aac9abe
+			if (sepol_role->s.value == 1) {
aac9abe
+				// role is object_r, ignore it since it is implicitly associated
aac9abe
+				// with all users
aac9abe
+				continue;
aac9abe
+			}
aac9abe
+
aac9abe
 			if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) {
aac9abe
 				cil_log(CIL_INFO, "Failed to set role bit for user\n");
aac9abe
 				rc = SEPOL_ERR;
aac9abe
@@ -1770,13 +1781,12 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu
44e2d26
 		cil_typetrans = (struct cil_nametypetransition*)node->data;
44e2d26
 		if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) {
44e2d26
 			cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n");
44e2d26
-			cil_log(CIL_ERR,"Invalid typetransition statement at line %d of %s\n", 
44e2d26
-			node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR,"Invalid typetransition statement");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 		rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_ERR, "Failed to insert type transition into avtab at line %d of %s\n", node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 		break;
aac9abe
@@ -1784,7 +1794,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu
44e2d26
 		cil_type_rule = node->data;
44e2d26
 		rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_ERR, "Failed to insert typerule into avtab at line %d of %s\n", node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Failed to insert typerule into avtab");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 		break;
aac9abe
@@ -1792,7 +1802,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu
44e2d26
 		cil_avrule = node->data;
44e2d26
 		rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Failed to insert avrule into avtab");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 		break;
aac9abe
@@ -1800,8 +1810,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu
44e2d26
 	case CIL_TUNABLEIF:
44e2d26
 		break;
44e2d26
 	default:
44e2d26
-		cil_log(CIL_ERR, "Invalid statement within booleanif at line %d of %s\n", 
44e2d26
-			node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_ERR, "Invalid statement within booleanif");
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
 
aac9abe
@@ -2060,14 +2069,13 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
44e2d26
 	tmp_cond = cond_node_create(pdb, NULL);
44e2d26
 	if (tmp_cond == NULL) {
44e2d26
 		rc = SEPOL_ERR;
44e2d26
-		cil_log(CIL_INFO, "Failed to create sepol conditional node at line %d of %s\n", 
44e2d26
-			node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_INFO, "Failed to create sepol conditional node");
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
 	
44e2d26
 	rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr);
44e2d26
 	if (rc != SEPOL_OK) {
44e2d26
-		cil_log(CIL_INFO, "Failed to convert CIL conditional expression to sepol expression at line %d of %s\n", node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_INFO, "Failed to convert CIL conditional expression to sepol expression");
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
 
aac9abe
@@ -2123,7 +2131,7 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
44e2d26
 		bool_args.cond_flavor = CIL_CONDTRUE;
44e2d26
 		rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_ERR, "Failure while walking true conditional block at line %d of %s\n", true_node->line, true_node->path);
44e2d26
+			cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 	}
aac9abe
@@ -2132,7 +2140,7 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
44e2d26
 		bool_args.cond_flavor = CIL_CONDFALSE;
44e2d26
 		rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_ERR, "Failure while walking false conditional block at line %d of %s\n", false_node->line, false_node->path);
44e2d26
+			cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 	}
aac9abe
@@ -3035,6 +3043,9 @@ int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons)
a7ec325
 		case CIL_PROTOCOL_TCP:
a7ec325
 			new_ocon->u.port.protocol = IPPROTO_TCP;
a7ec325
 			break;
a7ec325
+		case CIL_PROTOCOL_DCCP:
a7ec325
+			new_ocon->u.port.protocol = IPPROTO_DCCP;
a7ec325
+			break;
a7ec325
 		default:
a7ec325
 			/* should not get here */
a7ec325
 			rc = SEPOL_ERR;
aac9abe
@@ -3583,7 +3594,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args)
44e2d26
 
44e2d26
 exit:
44e2d26
 	if (rc != SEPOL_OK) {
44e2d26
-		cil_log(CIL_ERR, "Binary policy creation failed at line %d of %s\n", node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_ERR, "Binary policy creation failed");
44e2d26
 	}
44e2d26
 	return rc;
44e2d26
 }
aac9abe
@@ -4227,6 +4238,9 @@ exit:
44e2d26
 static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node)
44e2d26
 {
44e2d26
 	avrule_t *avrule;
44e2d26
+	struct cil_tree_node *source_node;
44e2d26
+	char *source_path;
44e2d26
+	int is_cil;
44e2d26
 
44e2d26
 	avrule = cil_malloc(sizeof(avrule_t));
44e2d26
 	avrule->specified = kind;
aac9abe
@@ -4235,8 +4249,17 @@ static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *no
44e2d26
 	__cil_init_sepol_type_set(&avrule->ttypes);
44e2d26
 	avrule->perms = NULL;
44e2d26
 	avrule->line = node->line;
44e2d26
-	avrule->source_filename = node->path;
44e2d26
+
44e2d26
+	avrule->source_filename = NULL;
44e2d26
 	avrule->source_line = node->line;
44e2d26
+	source_node = cil_tree_get_next_path(node, &source_path, &is_cil);
44e2d26
+	if (source_node) {
44e2d26
+		avrule->source_filename = source_path;
44e2d26
+		if (!is_cil) {
44e2d26
+			avrule->source_line = node->hll_line;
44e2d26
+		}
44e2d26
+	}
44e2d26
+
44e2d26
 	avrule->next = NULL;
44e2d26
 	return avrule;
44e2d26
 }
aac9abe
@@ -4263,10 +4286,8 @@ static void __cil_print_parents(const char *pad, struct cil_tree_node *n)
44e2d26
 
44e2d26
 	__cil_print_parents(pad, n->parent);
44e2d26
 
44e2d26
-	if (!n->path) {
44e2d26
-		cil_log(CIL_ERR,"%s%s\n", pad, cil_node_to_string(n));
44e2d26
-	} else {
44e2d26
-		cil_log(CIL_ERR,"%s%s at line %d of %s\n", pad, cil_node_to_string(n), n->line, n->path);
44e2d26
+	if (n->flavor != CIL_SRC_INFO) {
44e2d26
+		cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n));
44e2d26
 	}
44e2d26
 }
44e2d26
 
aac9abe
@@ -4357,7 +4378,7 @@ static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tr
44e2d26
 		allow_str = CIL_KEY_ALLOWX;
44e2d26
 		avrule_flavor = CIL_AVRULEX;
44e2d26
 	}
44e2d26
-	cil_log(CIL_ERR, "%s check failed at line %d of %s\n", neverallow_str, node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str);
44e2d26
 	__cil_print_rule("  ", neverallow_str, cil_rule);
44e2d26
 	cil_list_init(&matching, CIL_NODE);
44e2d26
 	rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE);
aac9abe
@@ -4380,10 +4401,9 @@ exit:
71b1a80
 	return rc;
71b1a80
 }
71b1a80
 
71b1a80
-static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node)
71b1a80
+static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation)
71b1a80
 {
71b1a80
-	int rc = SEPOL_ERR;
71b1a80
-	int ret = CIL_FALSE;
71b1a80
+	int rc = SEPOL_OK;
71b1a80
 	struct cil_avrule *cil_rule = node->data;
71b1a80
 	struct cil_symtab_datum *tgt = cil_rule->tgt;
71b1a80
 	uint32_t kind;
aac9abe
@@ -4422,11 +4442,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
71b1a80
 
71b1a80
 		rc = check_assertion(pdb, rule);
71b1a80
 		if (rc == CIL_TRUE) {
71b1a80
+			*violation = CIL_TRUE;
71b1a80
 			rc = __cil_print_neverallow_failure(db, node);
71b1a80
 			if (rc != SEPOL_OK) {
71b1a80
 				goto exit;
71b1a80
 			}
71b1a80
-			ret = CIL_TRUE;
71b1a80
 		}
71b1a80
 
71b1a80
 	} else {
aac9abe
@@ -4444,12 +4464,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
71b1a80
 			rule->xperms = item->data;
71b1a80
 			rc = check_assertion(pdb, rule);
71b1a80
 			if (rc == CIL_TRUE) {
71b1a80
+				*violation = CIL_TRUE;
71b1a80
 				rc = __cil_print_neverallow_failure(db, node);
71b1a80
 				if (rc != SEPOL_OK) {
71b1a80
 					goto exit;
71b1a80
 				}
71b1a80
-				ret = CIL_TRUE;
71b1a80
-				goto exit;
71b1a80
 			}
71b1a80
 		}
71b1a80
 	}
aac9abe
@@ -4466,34 +4485,23 @@ exit:
71b1a80
 	rule->xperms = NULL;
71b1a80
 	__cil_destroy_sepol_avrules(rule);
71b1a80
 
71b1a80
-	if (rc) {
71b1a80
-		return rc;
71b1a80
-	} else {
71b1a80
-		return ret;
71b1a80
-	}
71b1a80
+	return rc;
71b1a80
 }
71b1a80
 
71b1a80
-static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows)
71b1a80
+static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation)
71b1a80
 {
71b1a80
 	int rc = SEPOL_OK;
71b1a80
-	int ret = CIL_FALSE;
71b1a80
 	struct cil_list_item *item;
71b1a80
 
71b1a80
 	cil_list_for_each(item, neverallows) {
71b1a80
-		rc = cil_check_neverallow(db, pdb, item->data);
71b1a80
-		if (rc < 0) {
71b1a80
+		rc = cil_check_neverallow(db, pdb, item->data, violation);
71b1a80
+		if (rc != SEPOL_OK) {
71b1a80
 			goto exit;
71b1a80
-		} else if (rc > 0) {
71b1a80
-			ret = CIL_TRUE;
71b1a80
 		}
71b1a80
 	}
71b1a80
 
71b1a80
 exit:
71b1a80
-	if (rc || ret) {
71b1a80
-		return SEPOL_ERR;
71b1a80
-	} else {
71b1a80
-		return SEPOL_OK;
71b1a80
-	}
71b1a80
+	return rc;
71b1a80
 }
71b1a80
 
71b1a80
 static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
aac9abe
@@ -4548,7 +4556,7 @@ exit:
71b1a80
 	return rc;
71b1a80
 }
71b1a80
 
71b1a80
-static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[])
71b1a80
+static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[], int *violation)
71b1a80
 {
71b1a80
 	int rc = SEPOL_OK;
71b1a80
 	int i;
aac9abe
@@ -4574,6 +4582,9 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
71b1a80
 		if (bad) {
71b1a80
 			avtab_ptr_t cur;
71b1a80
 			struct cil_avrule target;
71b1a80
+			struct cil_tree_node *n1 = NULL;
71b1a80
+
71b1a80
+			*violation = CIL_TRUE;
71b1a80
 
71b1a80
                         target.is_extended = 0;
71b1a80
 			target.rule_kind = CIL_AVRULE_ALLOWED;
aac9abe
@@ -4585,7 +4596,6 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
71b1a80
 			for (cur = bad; cur; cur = cur->next) {
71b1a80
 				struct cil_list_item *i2;
71b1a80
 				struct cil_list *matching;
71b1a80
-				struct cil_tree_node *n;
71b1a80
 
44e2d26
 				rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
44e2d26
 				if (rc != SEPOL_OK) {
aac9abe
@@ -4594,7 +4604,7 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
44e2d26
 				}
44e2d26
 				__cil_print_rule("  ", "allow", &target);
44e2d26
 				cil_list_init(&matching, CIL_NODE);
44e2d26
-				rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE);
44e2d26
+				rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE);
44e2d26
 				if (rc) {
44e2d26
 					cil_log(CIL_ERR, "Error occurred while checking type bounds\n");
44e2d26
 					cil_list_destroy(&matching, CIL_FALSE);
aac9abe
@@ -4602,14 +4612,17 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void
44e2d26
 					bounds_destroy_bad(bad);
44e2d26
 					goto exit;
44e2d26
 				}
44e2d26
-
44e2d26
 				cil_list_for_each(i2, matching) {
44e2d26
-					__cil_print_parents("    ", (struct cil_tree_node *)i2->data);
44e2d26
+					struct cil_tree_node *n2 = i2->data;
44e2d26
+					struct cil_avrule *r2 = n2->data;
44e2d26
+					if (n1 == n2) {
44e2d26
+						cil_log(CIL_ERR, "    <See previous>\n");
44e2d26
+					} else {
44e2d26
+						n1 = n2;
44e2d26
+						__cil_print_parents("    ", n2);
44e2d26
+						__cil_print_rule("      ", "allow", r2);
44e2d26
+					}
44e2d26
 				}
44e2d26
-				i2 = matching->tail;
44e2d26
-				n = i2->data;
44e2d26
-				__cil_print_rule("      ", "allow", n->data);
44e2d26
-				cil_log(CIL_ERR,"\n");
44e2d26
 				cil_list_destroy(&matching, CIL_FALSE);
44e2d26
 				cil_list_destroy(&target.perms.classperms, CIL_TRUE);
44e2d26
 			}
aac9abe
@@ -4753,20 +4766,32 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
44e2d26
 	__cil_set_conditional_state_and_flags(pdb);
44e2d26
 
44e2d26
 	if (db->disable_neverallow != CIL_TRUE) {
44e2d26
+		int violation = CIL_FALSE;
44e2d26
 		cil_log(CIL_INFO, "Checking Neverallows\n");
44e2d26
-		rc = cil_check_neverallows(db, pdb, neverallows);
44e2d26
+		rc = cil_check_neverallows(db, pdb, neverallows, &violation);
44e2d26
 		if (rc != SEPOL_OK) goto exit;
44e2d26
 
44e2d26
 		cil_log(CIL_INFO, "Checking User Bounds\n");
44e2d26
-		bounds_check_users(NULL, pdb);
44e2d26
+		rc = bounds_check_users(NULL, pdb);
44e2d26
+		if (rc) {
44e2d26
+			violation = CIL_TRUE;
44e2d26
+		}
44e2d26
 
44e2d26
 		cil_log(CIL_INFO, "Checking Role Bounds\n");
44e2d26
-		bounds_check_roles(NULL, pdb);
44e2d26
+		rc = bounds_check_roles(NULL, pdb);
44e2d26
+		if (rc) {
44e2d26
+			violation = CIL_TRUE;
44e2d26
+		}
44e2d26
 
44e2d26
 		cil_log(CIL_INFO, "Checking Type Bounds\n");
44e2d26
-		rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil);
44e2d26
+		rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation);
44e2d26
 		if (rc != SEPOL_OK) goto exit;
44e2d26
 
44e2d26
+		if (violation == CIL_TRUE) {
44e2d26
+			rc = SEPOL_ERR;
44e2d26
+			goto exit;
44e2d26
+		}
44e2d26
+
44e2d26
 	}
44e2d26
 
44e2d26
 	rc = SEPOL_OK;
44e2d26
diff --git libsepol-2.5/cil/src/cil_build_ast.c libsepol-2.5/cil/src/cil_build_ast.c
44e2d26
index 1135e06..1505873 100644
44e2d26
--- libsepol-2.5/cil/src/cil_build_ast.c
44e2d26
+++ libsepol-2.5/cil/src/cil_build_ast.c
44e2d26
@@ -108,8 +108,7 @@ int cil_gen_node(__attribute__((unused)) struct cil_db *db, struct cil_tree_node
44e2d26
 			if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) {
44e2d26
 				if (sflavor == CIL_SYM_BLOCKS) {
44e2d26
 					struct cil_tree_node *node = datum->nodes->head->data;
44e2d26
-					cil_log(CIL_ERR, "Previous declaration at line %d of %s\n",
44e2d26
-						node->line, node->path);
44e2d26
+					cil_tree_log(node, CIL_ERR, "Previous declaration");
44e2d26
 				}
44e2d26
 			}
44e2d26
 			goto exit;
44e2d26
@@ -186,8 +185,7 @@ int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad block declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad block declaration");
44e2d26
 	cil_destroy_block(block);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -236,8 +234,7 @@ int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad blockinherit declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad blockinherit declaration");
44e2d26
 	cil_destroy_blockinherit(inherit);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -281,8 +278,7 @@ int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad blockabstract declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad blockabstract declaration");
44e2d26
 	cil_destroy_blockabstract(abstract);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -326,8 +322,7 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad in statement at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad in statement");
44e2d26
 	cil_destroy_in(in);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -387,8 +382,7 @@ int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad class declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad class declaration");
44e2d26
 	cil_destroy_class(class);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -456,8 +450,7 @@ int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, s
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad classorder declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad classorder declaration");
44e2d26
 	cil_destroy_classorder(classorder);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -527,7 +520,7 @@ int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, st
44e2d26
 		cil_tree_node_init(&new_ast);
44e2d26
 		new_ast->parent = ast_node;
44e2d26
 		new_ast->line = current_perm->line;
44e2d26
-		new_ast->path = current_perm->path;
44e2d26
+		new_ast->hll_line = current_perm->hll_line;
44e2d26
 
44e2d26
 		rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
@@ -738,8 +731,7 @@ int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_curre
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad classpermission declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad classpermission declaration");
44e2d26
 	cil_destroy_classpermission(cp);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -800,8 +792,7 @@ int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_cu
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad classpermissionset at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad classpermissionset");
44e2d26
 	cil_destroy_classpermissionset(cps);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -852,8 +843,7 @@ int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad map class declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad map class declaration");
44e2d26
 	cil_destroy_class(map);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -897,8 +887,7 @@ int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad classmapping declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad classmapping declaration");
44e2d26
 	cil_destroy_classmapping(mapping);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -954,8 +943,7 @@ int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struc
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad common declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad common declaration");
44e2d26
 	cil_destroy_class(common);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -994,8 +982,7 @@ int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad classcommon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad classcommon declaration");
44e2d26
 	cil_destroy_classcommon(clscom);
44e2d26
 	return rc;
44e2d26
 
44e2d26
@@ -1043,8 +1030,7 @@ int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct c
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad sid declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad sid declaration");
44e2d26
 	cil_destroy_sid(sid);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -1102,8 +1088,7 @@ int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, s
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad sidcontext declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad sidcontext declaration");
44e2d26
 	cil_destroy_sidcontext(sidcon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1163,8 +1148,7 @@ int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad sidorder declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad sidorder declaration");
44e2d26
 	cil_destroy_sidorder(sidorder);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1215,8 +1199,7 @@ int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad user declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad user declaration");
44e2d26
 	cil_destroy_user(user);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -1265,8 +1248,7 @@ int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad userattribute declaration at line %d of %s\n",
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad userattribute declaration");
44e2d26
 	cil_destroy_userattribute(attr);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -1336,8 +1318,7 @@ int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_curr
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad userattributeset declaration at line %d of %s\n",
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad userattributeset declaration");
44e2d26
 	cil_destroy_userattributeset(attrset);
44e2d26
 
44e2d26
 	return rc;
44e2d26
@@ -1397,8 +1378,7 @@ int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad userlevel declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad userlevel declaration");
44e2d26
 	cil_destroy_userlevel(usrlvl);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1458,8 +1438,7 @@ int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad userrange declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad userrange declaration");
44e2d26
 	cil_destroy_userrange(userrange);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1508,8 +1487,7 @@ int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, s
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad userprefix declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad userprefix declaration");
44e2d26
 	cil_destroy_userprefix(userprefix);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1566,8 +1544,7 @@ int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad selinuxuser declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuser declaration");
44e2d26
 	cil_destroy_selinuxuser(selinuxuser);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1614,8 +1591,7 @@ int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_cu
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad selinuxuserdefault declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuserdefault declaration");
44e2d26
 	cil_destroy_selinuxuser(selinuxuser);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1666,8 +1642,7 @@ int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad role declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad role declaration");
44e2d26
 	cil_destroy_role(role);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -1717,8 +1692,7 @@ int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad roletype declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad roletype declaration");
44e2d26
 	cil_destroy_roletype(roletype);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1764,8 +1738,7 @@ int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad userrole declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad userrole declaration");
44e2d26
 	cil_destroy_userrole(userrole);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1815,8 +1788,7 @@ int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad roletransition rule at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad roletransition rule");
44e2d26
 	cil_destroy_roletransition(roletrans);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1862,8 +1834,7 @@ int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad roleallow rule at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad roleallow rule");
44e2d26
 	cil_destroy_roleallow(roleallow);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1914,8 +1885,7 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad roleattribute declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad roleattribute declaration");
44e2d26
 	cil_destroy_roleattribute(attr);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -1982,8 +1952,7 @@ int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_curr
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad roleattributeset declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad roleattributeset declaration");
44e2d26
 	cil_destroy_roleattributeset(attrset);
44e2d26
 
44e2d26
 	return rc;
44e2d26
@@ -2042,8 +2011,7 @@ int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *as
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad allow rule at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad allow rule");
44e2d26
 	cil_destroy_avrule(rule);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -2099,8 +2067,7 @@ int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permiss
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad permissionx content at line %d of %s\n",
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad permissionx content");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -2143,8 +2110,7 @@ int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad permissionx statement at line %d of %s\n",
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad permissionx statement");
44e2d26
 	cil_destroy_permissionx(permx);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -2210,8 +2176,7 @@ int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *a
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad allowx rule at line %d of %s\n",
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad allowx rule");
44e2d26
 	cil_destroy_avrule(rule);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -2253,8 +2218,7 @@ int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad type rule at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad type rule");
44e2d26
 	cil_destroy_type_rule(rule);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -2306,8 +2270,7 @@ int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad type declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad type declaration");
44e2d26
 	cil_destroy_type(type);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -2361,8 +2324,7 @@ int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad typeattribute declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad typeattribute declaration");
44e2d26
 	cil_destroy_typeattribute(attr);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -2439,11 +2401,9 @@ int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 
44e2d26
 exit:
44e2d26
 	if (tunableif) {
44e2d26
-		cil_log(CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration at line %d of %s\n",
44e2d26
-			parse_current->line, parse_current->path);
44e2d26
+		cil_tree_log(parse_current, CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration");
44e2d26
 	} else {
44e2d26
-		cil_log(CIL_ERR, "Bad boolean declaration at line %d of %s\n",
44e2d26
-			parse_current->line, parse_current->path);
44e2d26
+		cil_tree_log(parse_current, CIL_ERR, "Bad boolean declaration");
44e2d26
 	}
44e2d26
 	cil_destroy_bool(boolean);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
@@ -2504,8 +2464,7 @@ int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad tunable declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad tunable declaration");
44e2d26
 	cil_destroy_tunable(tunable);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -2880,11 +2839,9 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
44e2d26
 
44e2d26
 exit:
44e2d26
 	if (tunableif) {
44e2d26
-		cil_log(CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration at line %d of %s\n",
44e2d26
-				parse_current->line, parse_current->path);
44e2d26
+		cil_tree_log(parse_current, CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration");
44e2d26
 	} else {
44e2d26
-		cil_log(CIL_ERR, "Bad booleanif declaration at line %d of %s\n",
44e2d26
-				parse_current->line, parse_current->path);
44e2d26
+		cil_tree_log(parse_current, CIL_ERR, "Bad booleanif declaration");
44e2d26
 	}
44e2d26
 	cil_destroy_boolif(bif);
44e2d26
 	return rc;
44e2d26
@@ -2964,8 +2921,7 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad tunableif declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad tunableif declaration");
44e2d26
 	cil_destroy_tunif(tif);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3018,8 +2974,8 @@ int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad %s condition declaration at line %d of %s\n",
44e2d26
-		(char*)parse_current->data, parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad %s condition declaration",
44e2d26
+		(char*)parse_current->data);
44e2d26
 	cil_destroy_condblock(cb);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3079,8 +3035,7 @@ int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad %s declaration at line %d of %s\n",
44e2d26
-		(char*)parse_current->data, parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", (char*)parse_current->data);
44e2d26
 	cil_destroy_alias(alias);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -3137,8 +3092,7 @@ int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad %s association at line %d of %s\n", 
44e2d26
-			cil_node_to_string(parse_current),parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad %s association", cil_node_to_string(parse_current));
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3187,8 +3141,7 @@ int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_curr
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad typeattributeset statement at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad typeattributeset statement");
44e2d26
 	cil_destroy_typeattributeset(attrset);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3235,8 +3188,7 @@ int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_curren
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad typepermissive declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad typepermissive declaration");
44e2d26
 	cil_destroy_typepermissive(typeperm);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3319,8 +3271,7 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad typetransition declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad typetransition declaration");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -3391,8 +3342,7 @@ int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_curre
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad rangetransition declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad rangetransition declaration");
44e2d26
 	cil_destroy_rangetransition(rangetrans);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3443,8 +3393,7 @@ int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad sensitivity declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad sensitivity declaration");
44e2d26
 	cil_destroy_sensitivity(sens);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -3496,8 +3445,7 @@ int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad category declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad category declaration");
44e2d26
 	cil_destroy_category(cat);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -3552,8 +3500,7 @@ int cil_gen_catset(struct cil_db *db, struct cil_tree_node *parse_current, struc
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad categoryset declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad categoryset declaration");
44e2d26
 	cil_destroy_catset(catset);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -3614,8 +3561,7 @@ int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad categoryorder declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad categoryorder declaration");
44e2d26
 	cil_destroy_catorder(catorder);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3675,8 +3621,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad sensitivityorder declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad sensitivityorder declaration");
44e2d26
 	cil_destroy_sensitivityorder(sensorder);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3730,8 +3675,7 @@ int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad sensitivitycategory declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad sensitivitycategory declaration");
44e2d26
 	cil_destroy_senscat(senscat);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -3786,8 +3730,7 @@ int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad level declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad level declaration");
44e2d26
 	cil_destroy_level(level);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -3893,8 +3836,7 @@ int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, s
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad levelrange declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad levelrange declaration");
44e2d26
 	cil_destroy_levelrange(lvlrange);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -3958,8 +3900,7 @@ int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad constrain declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad constrain declaration");
44e2d26
 	cil_destroy_constrain(cons);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4013,8 +3954,7 @@ int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad validatetrans declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad validatetrans declaration");
44e2d26
 	cil_destroy_validatetrans(validtrans);
44e2d26
 	return rc;
44e2d26
 
44e2d26
@@ -4118,8 +4058,7 @@ int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad context declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad context declaration");
44e2d26
 	cil_destroy_context(context);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return SEPOL_ERR;
44e2d26
@@ -4211,8 +4150,7 @@ int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad filecon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad filecon declaration");
44e2d26
 	cil_destroy_filecon(filecon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4261,6 +4199,8 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 		portcon->proto = CIL_PROTOCOL_UDP;
44e2d26
 	} else if (proto == CIL_KEY_TCP) {
44e2d26
 		portcon->proto = CIL_PROTOCOL_TCP;
44e2d26
+	} else if (proto == CIL_KEY_DCCP) {
44e2d26
+		portcon->proto = CIL_PROTOCOL_DCCP;
44e2d26
 	} else {
44e2d26
 		cil_log(CIL_ERR, "Invalid protocol\n");
44e2d26
 		rc = SEPOL_ERR;
44e2d26
@@ -4311,8 +4251,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad portcon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad portcon declaration");
44e2d26
 	cil_destroy_portcon(portcon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4393,8 +4332,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad nodecon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad nodecon declaration");
44e2d26
 	cil_destroy_nodecon(nodecon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4464,8 +4402,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad genfscon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad genfscon declaration");
44e2d26
 	cil_destroy_genfscon(genfscon);
44e2d26
 	return SEPOL_ERR;
44e2d26
 }
44e2d26
@@ -4538,8 +4475,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad netifcon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad netifcon declaration");
44e2d26
 	cil_destroy_netifcon(netifcon);
44e2d26
 	return SEPOL_ERR;
44e2d26
 }
44e2d26
@@ -4606,8 +4542,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, stru
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad pirqcon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad pirqcon declaration");
44e2d26
 	cil_destroy_pirqcon(pirqcon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4692,8 +4627,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad iomemcon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad iomemcon declaration");
44e2d26
 	cil_destroy_iomemcon(iomemcon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4778,8 +4712,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad ioportcon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad ioportcon declaration");
44e2d26
 	cil_destroy_ioportcon(ioportcon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4842,8 +4775,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current,
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad pcidevicecon declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad pcidevicecon declaration");
44e2d26
 	cil_destroy_pcidevicecon(pcidevicecon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4903,8 +4835,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad devicetreecon declaration at line %d of %s\n",
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad devicetreecon declaration");
44e2d26
 	cil_destroy_devicetreecon(devicetreecon);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -4979,8 +4910,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad fsuse declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad fsuse declaration");
44e2d26
 	cil_destroy_fsuse(fsuse);
44e2d26
 	return SEPOL_ERR;
44e2d26
 }
44e2d26
@@ -5137,8 +5067,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad macro declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad macro declaration");
44e2d26
 	cil_destroy_macro(macro);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return SEPOL_ERR;
44e2d26
@@ -5196,8 +5125,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad macro call at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad macro call");
44e2d26
 	cil_destroy_call(call);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -5299,8 +5227,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad optional at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad optional");
44e2d26
 	cil_destroy_optional(optional);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -5348,8 +5275,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad policycap statement at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad policycap statement");
44e2d26
 	cil_destroy_policycap(polcap);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -5404,8 +5330,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad ipaddr statement at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad ipaddr statement");
44e2d26
 	cil_destroy_ipaddr(ipaddr);
44e2d26
 	cil_clear_node(ast_node);
44e2d26
 	return rc;
44e2d26
@@ -5609,8 +5534,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad bounds declaration at line %d of %s\n", 
44e2d26
-		parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad bounds declaration");
44e2d26
 	cil_destroy_bounds(bounds);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -5671,8 +5595,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad %s declaration at line %d of %s\n", 
44e2d26
-			cil_node_to_string(parse_current), parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", cil_node_to_string(parse_current));
44e2d26
 	cil_destroy_default(def);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -5758,8 +5681,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad defaultrange declaration at line %d of %s\n", 
44e2d26
-			parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad defaultrange declaration");
44e2d26
 	cil_destroy_defaultrange(def);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -5819,8 +5741,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad handleunknown at line %d of %s\n",
44e2d26
-			parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad handleunknown");
44e2d26
 	cil_destroy_handleunknown(unknown);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -5868,8 +5789,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad mls at line %d of %s\n",
44e2d26
-			parse_current->line, parse_current->path);
44e2d26
+	cil_tree_log(parse_current, CIL_ERR, "Bad mls");
44e2d26
 	cil_destroy_mls(mls);
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -5879,6 +5799,27 @@ void cil_destroy_mls(struct cil_mls *mls)
44e2d26
 	free(mls);
44e2d26
 }
44e2d26
 
44e2d26
+int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node)
44e2d26
+{
44e2d26
+	/* No need to check syntax, because this is auto generated */
44e2d26
+	struct cil_src_info *info = NULL;
44e2d26
+
44e2d26
+	cil_src_info_init(&info;;
44e2d26
+
44e2d26
+	info->is_cil = (parse_current->next->data == CIL_KEY_SRC_CIL) ? CIL_TRUE : CIL_FALSE;
44e2d26
+	info->path = parse_current->next->next->data;
44e2d26
+
44e2d26
+	ast_node->data = info;
44e2d26
+	ast_node->flavor = CIL_SRC_INFO;
44e2d26
+
44e2d26
+	return SEPOL_OK;
44e2d26
+}
44e2d26
+
44e2d26
+void cil_destroy_src_info(struct cil_src_info *info)
44e2d26
+{
44e2d26
+	free(info);
44e2d26
+}
44e2d26
+
44e2d26
 int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args)
44e2d26
 {
44e2d26
 	struct cil_args_build *args = NULL;
44e2d26
@@ -5913,7 +5854,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 		if (parse_current->parent->parent == NULL) {
44e2d26
 			rc = SEPOL_OK;
44e2d26
 		} else {
44e2d26
-			cil_log(CIL_ERR, "Keyword expected after open parenthesis in line %d of %s\n", parse_current->line, parse_current->path);
44e2d26
+			cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis");
44e2d26
 		}
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
@@ -5926,7 +5867,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 			parse_current->data == CIL_KEY_BLOCKINHERIT ||
44e2d26
 			parse_current->data == CIL_KEY_BLOCKABSTRACT) {
44e2d26
 			rc = SEPOL_ERR;
44e2d26
-			cil_log(CIL_ERR, "%s is not allowed in macros (%s:%d)\n", (char *)parse_current->data, parse_current->path, parse_current->line);
44e2d26
+			cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data);
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 	}
44e2d26
@@ -5942,8 +5883,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 			parse_current->data != CIL_KEY_TYPECHANGE &&
44e2d26
 			parse_current->data != CIL_KEY_CALL) {
44e2d26
 			rc = SEPOL_ERR;
44e2d26
-			cil_log(CIL_ERR, "Found %s at line %d of %s\n",
44e2d26
-				(char*)parse_current->data, parse_current->line, parse_current->path);
44e2d26
+			cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data);
44e2d26
 			if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
44e2d26
 				cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n",
44e2d26
 						(char*)parse_current->data);
44e2d26
@@ -5958,8 +5898,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 	if (tunif != NULL) {
44e2d26
 		if (parse_current->data == CIL_KEY_TUNABLE) {
44e2d26
 			rc = SEPOL_ERR;
44e2d26
-			cil_log(CIL_ERR, "Found tunable at line %d of %s\n",
44e2d26
-				parse_current->line, parse_current->path);
44e2d26
+			cil_tree_log(parse_current, CIL_ERR, "Found tunable");
44e2d26
 			cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -5968,8 +5907,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 	if (in != NULL) {
44e2d26
 		if (parse_current->data == CIL_KEY_IN) {
44e2d26
 			rc = SEPOL_ERR;
44e2d26
-			cil_log(CIL_ERR, "Found in-statement at line %d of %s\n",
44e2d26
-				parse_current->line, parse_current->path);
44e2d26
+			cil_tree_log(parse_current, CIL_ERR, "Found in-statement");
44e2d26
 			cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -5979,7 +5917,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 
44e2d26
 	ast_node->parent = ast_current;
44e2d26
 	ast_node->line = parse_current->line;
44e2d26
-	ast_node->path = parse_current->path;
44e2d26
+	ast_node->hll_line = parse_current->hll_line;
44e2d26
 
44e2d26
 	if (parse_current->data == CIL_KEY_BLOCK) {
44e2d26
 		rc = cil_gen_block(db, parse_current, ast_node, 0);
44e2d26
@@ -6242,8 +6180,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 	} else if (parse_current->data == CIL_KEY_MLS) {
44e2d26
 		rc = cil_gen_mls(parse_current, ast_node);
44e2d26
 		*finished = CIL_TREE_SKIP_NEXT;
44e2d26
+	} else if (parse_current->data == CIL_KEY_SRC_INFO) {
44e2d26
+		rc = cil_gen_src_info(parse_current, ast_node);
44e2d26
 	} else {
44e2d26
-		cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char*)parse_current->data);
44e2d26
+		cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data);
44e2d26
 		rc = SEPOL_ERR;
44e2d26
 	}
44e2d26
 
44e2d26
@@ -6264,7 +6204,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
44e2d26
 			if (ast_current->flavor == CIL_IN) {
44e2d26
 				args->in = ast_current;
44e2d26
 			}
44e2d26
-		
44e2d26
+
44e2d26
 			ast_current->cl_head = ast_node;
44e2d26
 		} else {
44e2d26
 			ast_current->cl_tail->next = ast_node;
44e2d26
diff --git libsepol-2.5/cil/src/cil_build_ast.h libsepol-2.5/cil/src/cil_build_ast.h
44e2d26
index f428394..825029e 100644
44e2d26
--- libsepol-2.5/cil/src/cil_build_ast.h
44e2d26
+++ libsepol-2.5/cil/src/cil_build_ast.h
44e2d26
@@ -215,6 +215,8 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n
44e2d26
 void cil_destroy_mls(struct cil_mls *mls);
44e2d26
 int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
44e2d26
 void cil_destroy_defaultrange(struct cil_defaultrange *def);
44e2d26
+int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node);
44e2d26
+void cil_destroy_src_info(struct cil_src_info *info);
44e2d26
 
44e2d26
 int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats);
44e2d26
 void cil_destroy_cats(struct cil_cats *cats);
44e2d26
diff --git libsepol-2.5/cil/src/cil_copy_ast.c libsepol-2.5/cil/src/cil_copy_ast.c
44e2d26
index 0be1dda..5debd0d 100644
44e2d26
--- libsepol-2.5/cil/src/cil_copy_ast.c
44e2d26
+++ libsepol-2.5/cil/src/cil_copy_ast.c
44e2d26
@@ -1666,6 +1666,21 @@ int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void
44e2d26
 	return SEPOL_OK;
44e2d26
 }
44e2d26
 
44e2d26
+int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
44e2d26
+{
44e2d26
+	struct cil_src_info *orig = data;
44e2d26
+	struct cil_src_info *new = NULL;
44e2d26
+
44e2d26
+	cil_src_info_init(&new;;
44e2d26
+
44e2d26
+	new->is_cil = orig->is_cil;
44e2d26
+	new->path = orig->path;
44e2d26
+
44e2d26
+	*copy = new;
44e2d26
+
44e2d26
+	return SEPOL_OK;
44e2d26
+}
44e2d26
+
44e2d26
 int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
44e2d26
 {
44e2d26
 	int rc = SEPOL_ERR;
44e2d26
@@ -1942,6 +1957,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
44e2d26
 	case CIL_MLS:
44e2d26
 		copy_func = &cil_copy_mls;
44e2d26
 		break;
44e2d26
+	case CIL_SRC_INFO:
44e2d26
+		copy_func = &cil_copy_src_info;
44e2d26
+		break;
44e2d26
 	default:
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
@@ -1964,7 +1982,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
44e2d26
 
44e2d26
 		new->parent = parent;
44e2d26
 		new->line = orig->line;
44e2d26
-		new->path = orig->path;
44e2d26
+		new->hll_line = orig->hll_line;
44e2d26
 		new->flavor = orig->flavor;
44e2d26
 		new->data = data;
44e2d26
 
44e2d26
@@ -1985,8 +2003,8 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
44e2d26
 						param = item->data;
44e2d26
 						if (param->flavor == new->flavor) {
44e2d26
 							if (param->str == ((struct cil_symtab_datum*)new->data)->name) {
44e2d26
-								cil_log(CIL_ERR, "%s %s shadows a macro parameter (%s line:%d)\n", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name, orig->path, orig->line);
44e2d26
-								cil_log(CIL_ERR, "Note: macro declaration (%s line:%d)\n", namespace->path, namespace->line);
44e2d26
+								cil_tree_log(orig, CIL_ERR, "%s %s shadows a macro parameter", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name);
44e2d26
+								cil_tree_log(namespace, CIL_ERR, "Note: macro declaration");
44e2d26
 								rc = SEPOL_ERR;
44e2d26
 								goto exit;
44e2d26
 							}
44e2d26
diff --git libsepol-2.5/cil/src/cil_find.c libsepol-2.5/cil/src/cil_find.c
44e2d26
index 75de886..4134242 100644
44e2d26
--- libsepol-2.5/cil/src/cil_find.c
44e2d26
+++ libsepol-2.5/cil/src/cil_find.c
44e2d26
@@ -69,7 +69,11 @@ static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_dat
44e2d26
 		/* Both are attributes */
44e2d26
 		struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
44e2d26
 		struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
44e2d26
-		return ebitmap_match_any(a1->types, a2->types);
44e2d26
+		if (d1 == d2) {
44e2d26
+			return CIL_TRUE;
44e2d26
+		} else if (ebitmap_match_any(a1->types, a2->types)) {
44e2d26
+			return CIL_TRUE;
44e2d26
+		}
44e2d26
 	}
44e2d26
 	return CIL_FALSE;
44e2d26
 }
44e2d26
@@ -379,7 +383,7 @@ int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flav
44e2d26
 
44e2d26
 	rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args);
44e2d26
 	if (rc) {
44e2d26
-		cil_log(CIL_ERR, "An error occured while searching for avrule in AST\n");
44e2d26
+		cil_log(CIL_ERR, "An error occurred while searching for avrule in AST\n");
44e2d26
 	}
44e2d26
 
44e2d26
 	return rc;
44e2d26
diff --git libsepol-2.5/cil/src/cil_flavor.h libsepol-2.5/cil/src/cil_flavor.h
44e2d26
index 9fb5083..cd08b97 100644
44e2d26
--- libsepol-2.5/cil/src/cil_flavor.h
44e2d26
+++ libsepol-2.5/cil/src/cil_flavor.h
44e2d26
@@ -111,6 +111,7 @@ enum cil_flavor {
44e2d26
 	CIL_DEFAULTRANGE,
44e2d26
 	CIL_HANDLEUNKNOWN,
44e2d26
 	CIL_MLS,
44e2d26
+	CIL_SRC_INFO,
44e2d26
 
44e2d26
 /*
44e2d26
  *          boolean  constraint  set  catset
44e2d26
diff --git libsepol-2.5/cil/src/cil_fqn.c libsepol-2.5/cil/src/cil_fqn.c
44e2d26
index 865bd7d..dad1347 100644
44e2d26
--- libsepol-2.5/cil/src/cil_fqn.c
44e2d26
+++ libsepol-2.5/cil/src/cil_fqn.c
44e2d26
@@ -121,7 +121,7 @@ static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, has
44e2d26
 
44e2d26
 exit:
44e2d26
 	if (rc != SEPOL_OK) {
44e2d26
-		cil_log(CIL_ERR,"Problem qualifying names in block at line %d of %s\n", child_args.node->line, child_args.node->path);
44e2d26
+		cil_tree_log(child_args.node, CIL_ERR,"Problem qualifying names in block");
44e2d26
 	}
44e2d26
 
44e2d26
 	return rc;
44e2d26
diff --git libsepol-2.5/cil/src/cil_internal.h libsepol-2.5/cil/src/cil_internal.h
44e2d26
index a0a5480..5875dc9 100644
44e2d26
--- libsepol-2.5/cil/src/cil_internal.h
44e2d26
+++ libsepol-2.5/cil/src/cil_internal.h
44e2d26
@@ -101,6 +101,7 @@ char *CIL_KEY_OBJECT_R;
44e2d26
 char *CIL_KEY_STAR;
44e2d26
 char *CIL_KEY_TCP;
44e2d26
 char *CIL_KEY_UDP;
44e2d26
+char *CIL_KEY_DCCP;
44e2d26
 char *CIL_KEY_AUDITALLOW;
44e2d26
 char *CIL_KEY_TUNABLEIF;
44e2d26
 char *CIL_KEY_ALLOW;
44e2d26
@@ -225,6 +226,9 @@ char *CIL_KEY_NEVERALLOWX;
44e2d26
 char *CIL_KEY_PERMISSIONX;
44e2d26
 char *CIL_KEY_IOCTL;
44e2d26
 char *CIL_KEY_UNORDERED;
44e2d26
+char *CIL_KEY_SRC_INFO;
44e2d26
+char *CIL_KEY_SRC_CIL;
44e2d26
+char *CIL_KEY_SRC_HLL;
44e2d26
 
44e2d26
 /*
44e2d26
 	Symbol Table Array Indices
44e2d26
@@ -713,7 +717,8 @@ struct cil_filecon {
44e2d26
 
44e2d26
 enum cil_protocol {
44e2d26
 	CIL_PROTOCOL_UDP = 1,
44e2d26
-	CIL_PROTOCOL_TCP	
44e2d26
+	CIL_PROTOCOL_TCP,
44e2d26
+	CIL_PROTOCOL_DCCP
44e2d26
 };
44e2d26
 
44e2d26
 struct cil_portcon {
44e2d26
@@ -915,6 +920,11 @@ struct cil_mls {
44e2d26
 	int value;
44e2d26
 };
44e2d26
 
44e2d26
+struct cil_src_info {
44e2d26
+	int is_cil;
44e2d26
+	char *path;
44e2d26
+};
44e2d26
+
44e2d26
 void cil_db_init(struct cil_db **db);
44e2d26
 void cil_db_destroy(struct cil_db **db);
44e2d26
 
44e2d26
@@ -1017,6 +1027,7 @@ void cil_default_init(struct cil_default **def);
44e2d26
 void cil_defaultrange_init(struct cil_defaultrange **def);
44e2d26
 void cil_handleunknown_init(struct cil_handleunknown **unk);
44e2d26
 void cil_mls_init(struct cil_mls **mls);
44e2d26
+void cil_src_info_init(struct cil_src_info **info);
44e2d26
 void cil_userattribute_init(struct cil_userattribute **attribute);
44e2d26
 void cil_userattributeset_init(struct cil_userattributeset **attrset);
44e2d26
 
44e2d26
diff --git libsepol-2.5/cil/src/cil_lexer.h libsepol-2.5/cil/src/cil_lexer.h
44e2d26
index 1537d5e..ab555d8 100644
44e2d26
--- libsepol-2.5/cil/src/cil_lexer.h
44e2d26
+++ libsepol-2.5/cil/src/cil_lexer.h
44e2d26
@@ -37,8 +37,10 @@
44e2d26
 #define SYMBOL 3
44e2d26
 #define QSTRING 4
44e2d26
 #define COMMENT 5
44e2d26
-#define END_OF_FILE 6
44e2d26
-#define UNKNOWN 7
44e2d26
+#define HLL_LINEMARK 6
44e2d26
+#define NEWLINE 7
44e2d26
+#define END_OF_FILE 8
44e2d26
+#define UNKNOWN 9
44e2d26
 
44e2d26
 struct token {
44e2d26
 	uint32_t type;
44e2d26
diff --git libsepol-2.5/cil/src/cil_lexer.l libsepol-2.5/cil/src/cil_lexer.l
44e2d26
index 8e4c207..e28c33e 100644
44e2d26
--- libsepol-2.5/cil/src/cil_lexer.l
44e2d26
+++ libsepol-2.5/cil/src/cil_lexer.l
44e2d26
@@ -50,15 +50,17 @@ symbol		({digit}|{alpha}|{spec_char})+
44e2d26
 white		[ \t]
44e2d26
 newline		[\n\r]
44e2d26
 qstring		\"[^"\n]*\"
44e2d26
-comment		;[^\n]*
44e2d26
+hll_lm          ^;;\*
44e2d26
+comment		;
44e2d26
 
44e2d26
 %%
44e2d26
-{newline}	line++; 
44e2d26
+{newline}	line++; return NEWLINE;
44e2d26
+{hll_lm}	value=yytext; return HLL_LINEMARK;
44e2d26
 {comment}	value=yytext; return COMMENT;
44e2d26
 "("		value=yytext; return OPAREN;
44e2d26
-")"		value=yytext; return CPAREN;	
44e2d26
+")"		value=yytext; return CPAREN;
44e2d26
 {symbol}	value=yytext; return SYMBOL;
44e2d26
-{white}		//cil_log(CIL_INFO, "white, ");
44e2d26
+{white}		;
44e2d26
 {qstring}	value=yytext; return QSTRING;
44e2d26
 <<EOF>>		return END_OF_FILE;
44e2d26
 .		value=yytext; return UNKNOWN;
44e2d26
@@ -73,7 +75,7 @@ int cil_lexer_setup(char *buffer, uint32_t size)
44e2d26
 	}
44e2d26
 
44e2d26
 	line = 1;
44e2d26
-	
44e2d26
+
44e2d26
 	return SEPOL_OK;
44e2d26
 }
44e2d26
 
44e2d26
@@ -87,7 +89,6 @@ int cil_lexer_next(struct token *tok)
44e2d26
 	tok->type = yylex();
44e2d26
 	tok->value = value;
44e2d26
 	tok->line = line;
44e2d26
-	
44e2d26
+
44e2d26
 	return SEPOL_OK;
44e2d26
 }
44e2d26
-
5ec2ad1
diff --git libsepol-2.5/cil/src/cil_log.h libsepol-2.5/cil/src/cil_log.h
5ec2ad1
index 4112aaf..541569b 100644
5ec2ad1
--- libsepol-2.5/cil/src/cil_log.h
5ec2ad1
+++ libsepol-2.5/cil/src/cil_log.h
5ec2ad1
@@ -30,6 +30,7 @@
5ec2ad1
 #define CIL_LOG_H_
5ec2ad1
 
5ec2ad1
 #include <stdlib.h>
5ec2ad1
+#include <stdarg.h>
5ec2ad1
 #include <cil/cil.h>
5ec2ad1
 
5ec2ad1
 #define MAX_LOG_SIZE 512
44e2d26
diff --git libsepol-2.5/cil/src/cil_parser.c libsepol-2.5/cil/src/cil_parser.c
44e2d26
index d0e108c..101520c 100644
44e2d26
--- libsepol-2.5/cil/src/cil_parser.c
44e2d26
+++ libsepol-2.5/cil/src/cil_parser.c
44e2d26
@@ -36,9 +36,165 @@
44e2d26
 #include "cil_internal.h"
44e2d26
 #include "cil_log.h"
44e2d26
 #include "cil_mem.h"
44e2d26
-#include "cil_tree.h" 
44e2d26
+#include "cil_tree.h"
44e2d26
 #include "cil_lexer.h"
44e2d26
 #include "cil_strpool.h"
44e2d26
+#include "cil_stack.h"
44e2d26
+
44e2d26
+char *CIL_KEY_HLL_LMS;
44e2d26
+char *CIL_KEY_HLL_LMX;
44e2d26
+char *CIL_KEY_HLL_LME;
44e2d26
+
44e2d26
+struct hll_info {
44e2d26
+	int hll_lineno;
44e2d26
+	int hll_expand;
44e2d26
+};
44e2d26
+
44e2d26
+static void push_hll_info(struct cil_stack *stack, int hll_lineno, int hll_expand)
44e2d26
+{
44e2d26
+	struct hll_info *new = cil_malloc(sizeof(*new));
44e2d26
+
44e2d26
+	new->hll_lineno = hll_lineno;
44e2d26
+	new->hll_expand = hll_expand;
44e2d26
+
44e2d26
+	cil_stack_push(stack, CIL_NONE, new);
44e2d26
+}
44e2d26
+
44e2d26
+static void pop_hll_info(struct cil_stack *stack, int *hll_lineno, int *hll_expand)
44e2d26
+{
44e2d26
+	struct cil_stack_item *curr = cil_stack_pop(stack);
44e2d26
+	struct cil_stack_item *prev = cil_stack_peek(stack);
44e2d26
+	struct hll_info *old;
44e2d26
+
44e2d26
+	free(curr->data);
44e2d26
+
44e2d26
+	if (!prev) {
44e2d26
+		*hll_lineno = -1;
44e2d26
+		*hll_expand = -1;
44e2d26
+	} else {
44e2d26
+		old = prev->data;
44e2d26
+		*hll_lineno = old->hll_lineno;
44e2d26
+		*hll_expand = old->hll_expand;
44e2d26
+	}
44e2d26
+}
44e2d26
+
44e2d26
+static void create_node(struct cil_tree_node **node, struct cil_tree_node *current, int line, int hll_line, void *value)
44e2d26
+{
44e2d26
+	cil_tree_node_init(node);
44e2d26
+	(*node)->parent = current;
44e2d26
+	(*node)->flavor = CIL_NODE;
44e2d26
+	(*node)->line = line;
44e2d26
+	(*node)->hll_line = hll_line;
44e2d26
+	(*node)->data = value;
44e2d26
+}
44e2d26
+
44e2d26
+static void insert_node(struct cil_tree_node *node, struct cil_tree_node *current)
44e2d26
+{
44e2d26
+	if (current->cl_head == NULL) {
44e2d26
+		current->cl_head = node;
44e2d26
+	} else {
44e2d26
+		current->cl_tail->next = node;
44e2d26
+	}
44e2d26
+	current->cl_tail = node;
44e2d26
+}
44e2d26
+
44e2d26
+static int add_hll_linemark(struct cil_tree_node **current, int *hll_lineno, int *hll_expand, struct cil_stack *stack, char *path)
44e2d26
+{
44e2d26
+	char *hll_type;
44e2d26
+	struct cil_tree_node *node;
44e2d26
+	struct token tok;
44e2d26
+	char *hll_file;
44e2d26
+	char *end = NULL;
44e2d26
+
44e2d26
+	cil_lexer_next(&tok;;
44e2d26
+	hll_type = cil_strpool_add(tok.value);
44e2d26
+	if (hll_type == CIL_KEY_HLL_LME) {
44e2d26
+		if (cil_stack_is_empty(stack)) {
44e2d26
+			cil_log(CIL_ERR, "Line mark end without start\n");
44e2d26
+			goto exit;
44e2d26
+		}
44e2d26
+		pop_hll_info(stack, hll_lineno, hll_expand);
44e2d26
+		*current = (*current)->parent;
44e2d26
+	} else {
44e2d26
+		create_node(&node, *current, tok.line, *hll_lineno, NULL);
44e2d26
+		insert_node(node, *current);
44e2d26
+		*current = node;
44e2d26
+
44e2d26
+		create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_INFO);
44e2d26
+		insert_node(node, *current);
44e2d26
+
44e2d26
+		create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_HLL);
44e2d26
+		insert_node(node, *current);
44e2d26
+
44e2d26
+		if (hll_type == CIL_KEY_HLL_LMS) {
44e2d26
+			*hll_expand = 0;
44e2d26
+		} else if (hll_type == CIL_KEY_HLL_LMX) {
44e2d26
+			*hll_expand = 1;
44e2d26
+		} else {
44e2d26
+			cil_log(CIL_ERR, "Invalid line mark syntax\n");
44e2d26
+			goto exit;
44e2d26
+		}
44e2d26
+
44e2d26
+		cil_lexer_next(&tok;;
44e2d26
+		if (tok.type != SYMBOL) {
44e2d26
+			cil_log(CIL_ERR, "Invalid line mark syntax\n");
44e2d26
+			goto exit;
44e2d26
+		}
44e2d26
+		*hll_lineno = strtol(tok.value, &end, 10);
44e2d26
+		if (errno == ERANGE || *end != '\0') {
44e2d26
+			cil_log(CIL_ERR, "Problem parsing line number for line mark\n");
44e2d26
+			goto exit;
44e2d26
+		}
44e2d26
+
44e2d26
+		push_hll_info(stack, *hll_lineno, *hll_expand);
44e2d26
+
44e2d26
+		cil_lexer_next(&tok;;
44e2d26
+		if (tok.type != SYMBOL && tok.type != QSTRING) {
44e2d26
+			cil_log(CIL_ERR, "Invalid line mark syntax\n");
44e2d26
+			goto exit;
44e2d26
+		}
44e2d26
+
44e2d26
+		if (tok.type == QSTRING) {
44e2d26
+			tok.value[strlen(tok.value) - 1] = '\0';
44e2d26
+			tok.value = tok.value+1;
44e2d26
+		}
44e2d26
+
44e2d26
+		hll_file = cil_strpool_add(tok.value);
44e2d26
+
44e2d26
+		create_node(&node, *current, tok.line, *hll_lineno, hll_file);
44e2d26
+		insert_node(node, *current);
44e2d26
+	}
44e2d26
+
44e2d26
+	cil_lexer_next(&tok;;
44e2d26
+	if (tok.type != NEWLINE) {
44e2d26
+		cil_log(CIL_ERR, "Invalid line mark syntax\n");
44e2d26
+		goto exit;
44e2d26
+	}
44e2d26
+
44e2d26
+	return SEPOL_OK;
44e2d26
+
44e2d26
+exit:
44e2d26
+	cil_log(CIL_ERR, "Problem with high-level line mark at line %d of %s\n", tok.line, path);
44e2d26
+	return SEPOL_ERR;
44e2d26
+}
44e2d26
+
44e2d26
+static void add_cil_path(struct cil_tree_node **current, char *path)
44e2d26
+{
44e2d26
+	struct cil_tree_node *node;
44e2d26
+
44e2d26
+	create_node(&node, *current, 0, 0, NULL);
44e2d26
+	insert_node(node, *current);
44e2d26
+	*current = node;
44e2d26
+
44e2d26
+	create_node(&node, *current, 0, 0, CIL_KEY_SRC_INFO);
44e2d26
+	insert_node(node, *current);
44e2d26
+
44e2d26
+	create_node(&node, *current, 0, 0, CIL_KEY_SRC_CIL);
44e2d26
+	insert_node(node, *current);
44e2d26
+
44e2d26
+	create_node(&node, *current, 0, 0, path);
44e2d26
+	insert_node(node, *current);
44e2d26
+}
44e2d26
 
44e2d26
 int cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree)
44e2d26
 {
44e2d26
@@ -47,89 +203,112 @@ int cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse
44e2d26
 
44e2d26
 	struct cil_tree *tree = NULL;
44e2d26
 	struct cil_tree_node *node = NULL;
44e2d26
-	struct cil_tree_node *item = NULL;
44e2d26
 	struct cil_tree_node *current = NULL;
44e2d26
 	char *path = cil_strpool_add(_path);
44e2d26
-
44e2d26
+	struct cil_stack *stack;
44e2d26
+	int hll_lineno = -1;
44e2d26
+	int hll_expand = -1;
44e2d26
 	struct token tok;
44e2d26
+	int rc = SEPOL_OK;
44e2d26
+
44e2d26
+	CIL_KEY_HLL_LMS = cil_strpool_add("lms");
44e2d26
+	CIL_KEY_HLL_LMX = cil_strpool_add("lmx");
44e2d26
+	CIL_KEY_HLL_LME = cil_strpool_add("lme");
44e2d26
+
44e2d26
+	cil_stack_init(&stack);
44e2d26
 
44e2d26
 	cil_lexer_setup(buffer, size);
44e2d26
 
44e2d26
 	tree = *parse_tree;
44e2d26
-	current = tree->root;	
44e2d26
+	current = tree->root;
44e2d26
+
44e2d26
+	add_cil_path(&current, path);
44e2d26
 
44e2d26
 	do {
44e2d26
 		cil_lexer_next(&tok;;
44e2d26
 		switch (tok.type) {
44e2d26
+		case HLL_LINEMARK:
44e2d26
+			rc = add_hll_linemark(&current, &hll_lineno, &hll_expand, stack, path);
44e2d26
+			if (rc != SEPOL_OK) {
44e2d26
+				goto exit;
44e2d26
+			}
44e2d26
+			break;
44e2d26
 		case OPAREN:
44e2d26
 			paren_count++;
44e2d26
-			cil_tree_node_init(&node);
44e2d26
-			node->parent = current;
44e2d26
-			node->flavor = CIL_NODE;
44e2d26
-			node->line = tok.line;
44e2d26
-			node->path = path;
44e2d26
-			if (current->cl_head == NULL) {
44e2d26
-				current->cl_head = node;
44e2d26
-			} else {
44e2d26
-				current->cl_tail->next = node;
44e2d26
-			}
44e2d26
-			current->cl_tail = node;
44e2d26
+
44e2d26
+			create_node(&node, current, tok.line, hll_lineno, NULL);
44e2d26
+			insert_node(node, current);
44e2d26
 			current = node;
44e2d26
 			break;
44e2d26
 		case CPAREN:
44e2d26
 			paren_count--;
44e2d26
 			if (paren_count < 0) {
44e2d26
 				cil_log(CIL_ERR, "Close parenthesis without matching open at line %d of %s\n", tok.line, path);
44e2d26
-				return SEPOL_ERR;
44e2d26
+				goto exit;
44e2d26
 			}
44e2d26
 			current = current->parent;
44e2d26
 			break;
44e2d26
-		case SYMBOL:
44e2d26
 		case QSTRING:
44e2d26
+			tok.value[strlen(tok.value) - 1] = '\0';
44e2d26
+			tok.value = tok.value+1;
44e2d26
+		case SYMBOL:
44e2d26
 			if (paren_count == 0) {
44e2d26
 				cil_log(CIL_ERR, "Symbol not inside parenthesis at line %d of %s\n", tok.line, path);
44e2d26
-				return SEPOL_ERR;
44e2d26
+				goto exit;
44e2d26
 			}
44e2d26
-			cil_tree_node_init(&item);
44e2d26
-			item->parent = current;
44e2d26
-			if (tok.type == QSTRING) {
44e2d26
-				tok.value[strlen(tok.value) - 1] = '\0';
44e2d26
-				item->data = cil_strpool_add(tok.value + 1);
44e2d26
-			} else {
44e2d26
-				item->data = cil_strpool_add(tok.value);
44e2d26
-			}
44e2d26
-			item->flavor = CIL_NODE;
44e2d26
-			item->line = tok.line;
44e2d26
-			item->path = path;
44e2d26
-			if (current->cl_head == NULL) {
44e2d26
-				current->cl_head = item;
44e2d26
-			} else {
44e2d26
-				current->cl_tail->next = item;
44e2d26
+
44e2d26
+			create_node(&node, current, tok.line, hll_lineno, cil_strpool_add(tok.value));
44e2d26
+			insert_node(node, current);
44e2d26
+			break;
44e2d26
+		case NEWLINE :
44e2d26
+			if (!hll_expand) {
44e2d26
+				hll_lineno++;
44e2d26
 			}
44e2d26
-			current->cl_tail = item;
44e2d26
 			break;
44e2d26
+		case COMMENT:
44e2d26
+			while (tok.type != NEWLINE && tok.type != END_OF_FILE) {
44e2d26
+				cil_lexer_next(&tok;;
44e2d26
+			}
44e2d26
+			if (!hll_expand) {
44e2d26
+				hll_lineno++;
44e2d26
+			}
44e2d26
+			if (tok.type != END_OF_FILE) {
44e2d26
+				break;
44e2d26
+			}
44e2d26
+			// Fall through if EOF
44e2d26
 		case END_OF_FILE:
44e2d26
 			if (paren_count > 0) {
44e2d26
 				cil_log(CIL_ERR, "Open parenthesis without matching close at line %d of %s\n", tok.line, path);
44e2d26
-				return SEPOL_ERR;
44e2d26
+				goto exit;
44e2d26
+			}
44e2d26
+			if (!cil_stack_is_empty(stack)) {
44e2d26
+				cil_log(CIL_ERR, "High-level language line marker start without close at line %d of %s\n", tok.line, path);
44e2d26
+				goto exit;
44e2d26
 			}
44e2d26
-			break;
44e2d26
-		case COMMENT:
44e2d26
-			// ignore
44e2d26
 			break;
44e2d26
 		case UNKNOWN:
44e2d26
 			cil_log(CIL_ERR, "Invalid token '%s' at line %d of %s\n", tok.value, tok.line, path);
44e2d26
-			return SEPOL_ERR;
44e2d26
+			goto exit;
44e2d26
 		default:
44e2d26
 			cil_log(CIL_ERR, "Unknown token type '%d' at line %d of %s\n", tok.type, tok.line, path);
44e2d26
-			return SEPOL_ERR;
44e2d26
+			goto exit;
44e2d26
 		}
44e2d26
 	}
44e2d26
 	while (tok.type != END_OF_FILE);
44e2d26
 
44e2d26
 	cil_lexer_destroy();
44e2d26
 
44e2d26
+	cil_stack_destroy(&stack);
44e2d26
+
44e2d26
 	*parse_tree = tree;
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
+
44e2d26
+exit:
44e2d26
+	while (!cil_stack_is_empty(stack)) {
44e2d26
+		pop_hll_info(stack, &hll_lineno, &hll_expand);
44e2d26
+	}
44e2d26
+	cil_stack_destroy(&stack);
44e2d26
+
44e2d26
+	return SEPOL_ERR;
44e2d26
 }
44e2d26
diff --git libsepol-2.5/cil/src/cil_policy.c libsepol-2.5/cil/src/cil_policy.c
44e2d26
index 2c9b158..382129b 100644
44e2d26
--- libsepol-2.5/cil/src/cil_policy.c
44e2d26
+++ libsepol-2.5/cil/src/cil_policy.c
44e2d26
@@ -123,6 +123,8 @@ int cil_portcon_to_policy(FILE **file_arr, struct cil_sort *sort)
44e2d26
 			fprintf(file_arr[NETIFCONS], "udp ");
44e2d26
 		} else if (portcon->proto == CIL_PROTOCOL_TCP) {
44e2d26
 			fprintf(file_arr[NETIFCONS], "tcp ");
44e2d26
+		} else if (portcon->proto == CIL_PROTOCOL_DCCP) {
44e2d26
+			fprintf(file_arr[NETIFCONS], "dccp ");
44e2d26
 		}
44e2d26
 		fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low);
44e2d26
 		fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high);
44e2d26
diff --git libsepol-2.5/cil/src/cil_reset_ast.c libsepol-2.5/cil/src/cil_reset_ast.c
44e2d26
index 06146ca..de00679 100644
44e2d26
--- libsepol-2.5/cil/src/cil_reset_ast.c
44e2d26
+++ libsepol-2.5/cil/src/cil_reset_ast.c
44e2d26
@@ -23,7 +23,7 @@ static void cil_reset_class(struct cil_class *class)
44e2d26
 {
44e2d26
 	if (class->common != NULL) {
44e2d26
 		struct cil_class *common = class->common;
44e2d26
-		cil_symtab_map(&common->perms, __class_reset_perm_values, &common->num_perms);
44e2d26
+		cil_symtab_map(&class->perms, __class_reset_perm_values, &common->num_perms);
44e2d26
 		/* during a re-resolve, we need to reset the common, so a classcommon
44e2d26
 		 * statement isn't seen as a duplicate */
44e2d26
 		class->num_perms -= common->num_perms;
44e2d26
diff --git libsepol-2.5/cil/src/cil_resolve_ast.c libsepol-2.5/cil/src/cil_resolve_ast.c
aac9abe
index 1489680..8348d57 100644
44e2d26
--- libsepol-2.5/cil/src/cil_resolve_ast.c
44e2d26
+++ libsepol-2.5/cil/src/cil_resolve_ast.c
aac9abe
@@ -131,10 +131,10 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab,
aac9abe
 				}
aac9abe
 			}
aac9abe
 			if (rc != SEPOL_OK) {
aac9abe
-				cil_log(CIL_ERR, "Failed to resolve permission %s\n", (char*)curr->data);
aac9abe
-				goto exit;
aac9abe
+				cil_log(CIL_WARN, "Failed to resolve permission %s\n", (char*)curr->data);
aac9abe
+			} else {
aac9abe
+				cil_list_append(*perm_datums, CIL_DATUM, perm_datum);
aac9abe
 			}
aac9abe
-			cil_list_append(*perm_datums, CIL_DATUM, perm_datum);
aac9abe
 		} else {
aac9abe
 			cil_list_append(*perm_datums, curr->flavor, curr->data);
aac9abe
 		}
44e2d26
@@ -497,7 +497,7 @@ int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor f
44e2d26
 	int limit = 2;
44e2d26
 
44e2d26
 	if (alias->actual == NULL) {
44e2d26
-		cil_log(CIL_ERR, "Alias declared but not used at line %d of %s\n",current->line, current->path);
44e2d26
+		cil_tree_log(current, CIL_ERR, "Alias declared but not used");
44e2d26
 		return SEPOL_ERR;
44e2d26
 	}
44e2d26
 
44e2d26
@@ -1380,7 +1380,7 @@ struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists,
44e2d26
 			cil_list_for_each(curr, *ordered_lists) {
44e2d26
 				struct cil_ordered_list *ordered_list = curr->data;
44e2d26
 				if (ordered_list->merged == CIL_FALSE) {
44e2d26
-					cil_log(CIL_ERR, "Unable to merge ordered list at line %d of %s\n",ordered_list->node->line, ordered_list->node->path);
44e2d26
+					cil_tree_log(ordered_list->node, CIL_ERR, "Unable to merge ordered list");
44e2d26
 				}
44e2d26
 			}
44e2d26
 			goto exit;
44e2d26
@@ -2252,12 +2252,10 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_
44e2d26
 
44e2d26
 	cil_list_for_each(item, trace) {
44e2d26
 		curr = item->data;
44e2d26
-		cil_log(CIL_ERR, "  %s:%d: ", curr->path, curr->line);
44e2d26
-
44e2d26
 		if (curr->flavor == CIL_BLOCK) {
44e2d26
-			cil_log(CIL_ERR, "block %s\n", DATUM(curr->data)->name);
44e2d26
+			cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name);
44e2d26
 		} else {
44e2d26
-			cil_log(CIL_ERR, "blockinherit %s\n", ((struct cil_blockinherit *)curr->data)->block_str);
44e2d26
+			cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str);
44e2d26
 		}
44e2d26
 	}
44e2d26
 
44e2d26
@@ -2442,7 +2440,7 @@ int cil_resolve_in_list(void *extra_args)
44e2d26
 		}
44e2d26
 
44e2d26
 		if (unresolved > 0 && resolved == 0) {
44e2d26
-			cil_log(CIL_ERR, "Failed to resolve in-statement on line %d of %s\n", last_failed_node->line, last_failed_node->path);
44e2d26
+			cil_tree_log(last_failed_node, CIL_ERR, "Failed to resolve in-statement");
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -2485,7 +2483,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
44e2d26
 
44e2d26
 		if (user->bounds != NULL) {
44e2d26
 			struct cil_tree_node *node = user->bounds->datum.nodes->head->data;
44e2d26
-			cil_log(CIL_ERR, "User %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "User %s already bound by parent", bounds->child_str);
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -2498,7 +2496,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
44e2d26
 
44e2d26
 		if (role->bounds != NULL) {
44e2d26
 			struct cil_tree_node *node = role->bounds->datum.nodes->head->data;
44e2d26
-			cil_log(CIL_ERR, "Role %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Role %s already bound by parent", bounds->child_str);
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -2512,8 +2510,8 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
44e2d26
 
44e2d26
 		if (type->bounds != NULL) {
44e2d26
 			node = ((struct cil_symtab_datum *)type->bounds)->nodes->head->data;
44e2d26
-			cil_log(CIL_ERR, "Type %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path);
44e2d26
-			cil_log(CIL_ERR, "Now being bound to parent %s at line %u of %s\n", bounds->parent_str, current->line, current->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Type %s already bound by parent", bounds->child_str);
44e2d26
+			cil_tree_log(current, CIL_ERR, "Now being bound to parent %s", bounds->parent_str);
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -2542,7 +2540,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Bad bounds statement at line %u of %s\n", current->line, current->path);
44e2d26
+	cil_tree_log(current, CIL_ERR, "Bad bounds statement");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -2617,12 +2615,10 @@ void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_n
44e2d26
 
44e2d26
 	cil_list_for_each(item, trace) {
44e2d26
 		curr = item->data;
44e2d26
-		cil_log(CIL_ERR, "  %s:%d: ", curr->path, curr->line);
44e2d26
-
44e2d26
 		if (curr->flavor == CIL_MACRO) {
44e2d26
-			cil_log(CIL_ERR, "macro %s\n", DATUM(curr->data)->name);
44e2d26
+			cil_tree_log(curr, CIL_ERR, "macro %s", DATUM(curr->data)->name);
44e2d26
 		} else {
44e2d26
-			cil_log(CIL_ERR, "call %s\n", ((struct cil_call *)curr->data)->macro_str);
44e2d26
+			cil_tree_log(curr, CIL_ERR, "call %s", ((struct cil_call *)curr->data)->macro_str);
44e2d26
 		}
44e2d26
 	}
44e2d26
 
44e2d26
@@ -2700,7 +2696,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
44e2d26
 		struct cil_tree_node *pc = NULL;
44e2d26
 
44e2d26
 		if (new_call->args_tree == NULL) {
44e2d26
-			cil_log(CIL_ERR, "Missing arguments (%s, line: %d)\n", current->path, current->line);
44e2d26
+			cil_tree_log(current, CIL_ERR, "Missing arguments");
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -2713,7 +2709,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
44e2d26
 			enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
44e2d26
 
44e2d26
 			if (pc == NULL) {
44e2d26
-				cil_log(CIL_ERR, "Missing arguments (%s, line: %d)\n", current->path, current->line);
44e2d26
+				cil_tree_log(current, CIL_ERR, "Missing arguments");
44e2d26
 				rc = SEPOL_ERR;
44e2d26
 				goto exit;
44e2d26
 			}
44e2d26
@@ -2890,12 +2886,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
44e2d26
 		}
44e2d26
 
44e2d26
 		if (pc != NULL) {
44e2d26
-			cil_log(CIL_ERR, "Unexpected arguments (%s, line: %d)\n", current->path, current->line);
44e2d26
+			cil_tree_log(current, CIL_ERR, "Unexpected arguments");
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 	} else if (new_call->args_tree != NULL) {
44e2d26
-		cil_log(CIL_ERR, "Unexpected arguments (%s, line: %d)\n", current->path, current->line);
44e2d26
+		cil_tree_log(current, CIL_ERR, "Unexpected arguments");
44e2d26
 		rc = SEPOL_ERR;
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
@@ -3593,7 +3589,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
44e2d26
 	if (optstack != NULL) {
44e2d26
 		if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) {
44e2d26
 			/* tuanbles and macros are not allowed in optionals*/
44e2d26
-			cil_log(CIL_ERR, "%s statement is not allowed in optionals (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
44e2d26
+			cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node));
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -3601,7 +3597,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
44e2d26
 
44e2d26
 	if (blockstack != NULL) {
44e2d26
 		if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) {
44e2d26
-			cil_log(CIL_ERR, "%s statement is not allowed in blocks (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
44e2d26
+			cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node));
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -3612,7 +3608,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
44e2d26
 			node->flavor == CIL_BLOCK ||
44e2d26
 			node->flavor == CIL_BLOCKABSTRACT ||
44e2d26
 			node->flavor == CIL_MACRO) {
44e2d26
-			cil_log(CIL_ERR, "%s statement is not allowed in macros (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
44e2d26
+			cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node));
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -3626,9 +3622,9 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
44e2d26
 			node->flavor == CIL_TUNABLEIF ||
44e2d26
 			node->flavor == CIL_NAMETYPETRANSITION)) {
44e2d26
 			if (((struct cil_booleanif*)boolif->data)->preserved_tunable) {
44e2d26
-				cil_log(CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif) (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
44e2d26
+				cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node));
44e2d26
 			} else {
44e2d26
-				cil_log(CIL_ERR, "%s statement is not allowed in booleanifs (%s:%d)\n", cil_node_to_string(node), node->path, node->line);
44e2d26
+				cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node));
44e2d26
 			}
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
@@ -3658,14 +3654,13 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
44e2d26
 
44e2d26
 			struct cil_optional *opt = (struct cil_optional *)optstack->data;
44e2d26
 			struct cil_tree_node *opt_node = opt->datum.nodes->head->data;
44e2d26
-			cil_log(lvl, "Disabling optional '%s' at line %d of %s: ", opt->datum.name, opt_node->line, opt_node->path);
44e2d26
+			cil_tree_log(opt_node, lvl, "Disabling optional '%s'", opt->datum.name);
44e2d26
 			/* disable an optional if something failed to resolve */
44e2d26
 			opt->enabled = CIL_FALSE;
44e2d26
 			rc = SEPOL_OK;
44e2d26
 		}
44e2d26
 
44e2d26
-		cil_log(lvl, "Failed to resolve '%s' in %s statement at line %d of %s\n",
44e2d26
-		        args->last_resolved_name, cil_node_to_string(node), node->line, node->path);
aac9abe
+		cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
 
44e2d26
diff --git libsepol-2.5/cil/src/cil_tree.c libsepol-2.5/cil/src/cil_tree.c
44e2d26
index 1c23efc..9ff9d4b 100644
44e2d26
--- libsepol-2.5/cil/src/cil_tree.c
44e2d26
+++ libsepol-2.5/cil/src/cil_tree.c
44e2d26
@@ -59,6 +59,92 @@ __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) void cil_tree_e
44e2d26
 	exit(1);
44e2d26
 }
44e2d26
 
44e2d26
+struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil)
44e2d26
+{
44e2d26
+	if (!node) {
44e2d26
+		return NULL;
44e2d26
+	}
44e2d26
+
44e2d26
+	node = node->parent;
44e2d26
+
44e2d26
+	while (node) {
44e2d26
+		if (node->flavor == CIL_NODE && node->data == NULL) {
44e2d26
+			if (node->cl_head->data == CIL_KEY_SRC_INFO) {
44e2d26
+				/* Parse Tree */
44e2d26
+				*path = node->cl_head->next->next->data;
44e2d26
+				*is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL);
44e2d26
+				return node;
44e2d26
+			}
44e2d26
+			node = node->parent;
44e2d26
+		} else if (node->flavor == CIL_SRC_INFO) {
44e2d26
+				/* AST */
44e2d26
+				struct cil_src_info *info = node->data;
44e2d26
+				*path = info->path;
44e2d26
+				*is_cil = info->is_cil;
44e2d26
+				return node;
44e2d26
+		} else {
44e2d26
+			if (node->flavor == CIL_CALL) {
44e2d26
+				struct cil_call *call = node->data;
44e2d26
+				node = NODE(call->macro);
44e2d26
+			} else if (node->flavor == CIL_BLOCKINHERIT) {
44e2d26
+				struct cil_blockinherit *inherit = node->data;
44e2d26
+				node = NODE(inherit->block);
44e2d26
+			} else {
44e2d26
+				node = node->parent;
44e2d26
+			}
44e2d26
+		}
44e2d26
+	}
44e2d26
+
44e2d26
+	return NULL;
44e2d26
+}
44e2d26
+
44e2d26
+char *cil_tree_get_cil_path(struct cil_tree_node *node)
44e2d26
+{
44e2d26
+	char *path = NULL;
44e2d26
+	int is_cil;
44e2d26
+
44e2d26
+	while (node) {
44e2d26
+		node = cil_tree_get_next_path(node, &path, &is_cil);
44e2d26
+		if (node && is_cil) {
44e2d26
+			return path;
44e2d26
+		}
44e2d26
+	}
44e2d26
+
44e2d26
+	return NULL;
44e2d26
+}
44e2d26
+
44e2d26
+__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...)
44e2d26
+{
44e2d26
+	va_list ap;
44e2d26
+
44e2d26
+	va_start(ap, msg);
44e2d26
+	cil_vlog(lvl, msg, ap);
44e2d26
+	va_end(ap);
44e2d26
+
44e2d26
+	if (node) {
44e2d26
+		char *path = NULL;
44e2d26
+		int is_cil;
44e2d26
+		unsigned hll_line = node->hll_line;
44e2d26
+
44e2d26
+		path = cil_tree_get_cil_path(node);
44e2d26
+
44e2d26
+		if (path != NULL) {
44e2d26
+			cil_log(lvl, " at %s:%d", path, node->line);
44e2d26
+		}
44e2d26
+
44e2d26
+		while (node) {
44e2d26
+			node = cil_tree_get_next_path(node, &path, &is_cil);
44e2d26
+			if (node && !is_cil) {
44e2d26
+				cil_log(lvl," from %s:%d", path, hll_line);
44e2d26
+				path = NULL;
44e2d26
+				hll_line = node->hll_line;
44e2d26
+			}
44e2d26
+		}
44e2d26
+	}
44e2d26
+
44e2d26
+	cil_log(lvl,"\n");
44e2d26
+}
44e2d26
+
44e2d26
 int cil_tree_init(struct cil_tree **tree)
44e2d26
 {
44e2d26
 	struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree));
44e2d26
@@ -128,8 +214,8 @@ void cil_tree_node_init(struct cil_tree_node **node)
44e2d26
 	new_node->data = NULL;
44e2d26
 	new_node->next = NULL;
44e2d26
 	new_node->flavor = CIL_ROOT;
44e2d26
-	new_node->line = 0;	
44e2d26
-	new_node->path = NULL;
44e2d26
+	new_node->line = 0;
44e2d26
+	new_node->hll_line = 0;
44e2d26
 
44e2d26
 	*node = new_node;
44e2d26
 }
44e2d26
@@ -185,7 +271,7 @@ int cil_tree_walk_core(struct cil_tree_node *node,
44e2d26
 		if (process_node != NULL) {
44e2d26
 			rc = (*process_node)(node, &finished, extra_args);
44e2d26
 			if (rc != SEPOL_OK) {
44e2d26
-				cil_log(CIL_INFO, "Problem at line %d of %s\n", node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_INFO, "Problem");
44e2d26
 				return rc;
44e2d26
 			}
44e2d26
 		}
44e2d26
@@ -222,7 +308,7 @@ int cil_tree_walk(struct cil_tree_node *node,
44e2d26
 	if (first_child != NULL) {
44e2d26
 		rc = (*first_child)(node->cl_head, extra_args);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_INFO, "Problem at line %d of %s\n", node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_INFO, "Problem");
44e2d26
 			return rc;
44e2d26
 		}
44e2d26
 	}
44e2d26
@@ -235,7 +321,7 @@ int cil_tree_walk(struct cil_tree_node *node,
44e2d26
 	if (last_child != NULL) {
44e2d26
 		rc = (*last_child)(node->cl_tail, extra_args);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_INFO, "Problem at line %d of %s\n",node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_INFO, "Problem");
44e2d26
 			return rc;
44e2d26
 		}
44e2d26
 	}
44e2d26
@@ -1319,6 +1405,8 @@ void cil_tree_print_node(struct cil_tree_node *node)
44e2d26
 				cil_log(CIL_INFO, " udp");
44e2d26
 			} else if (portcon->proto == CIL_PROTOCOL_TCP) {
44e2d26
 				cil_log(CIL_INFO, " tcp");
44e2d26
+			} else if (portcon->proto == CIL_PROTOCOL_DCCP) {
44e2d26
+				cil_log(CIL_INFO, " dccp");
44e2d26
 			}
44e2d26
 			cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high);
44e2d26
 
44e2d26
diff --git libsepol-2.5/cil/src/cil_tree.h libsepol-2.5/cil/src/cil_tree.h
44e2d26
index 9bb602f..aeded56 100644
44e2d26
--- libsepol-2.5/cil/src/cil_tree.h
44e2d26
+++ libsepol-2.5/cil/src/cil_tree.h
44e2d26
@@ -46,10 +46,14 @@ struct cil_tree_node {
44e2d26
 	struct cil_tree_node *next;		//Each element in the list points to the next element
44e2d26
 	enum cil_flavor flavor;
44e2d26
 	uint32_t line;
44e2d26
-	char *path;
44e2d26
+	uint32_t hll_line;
44e2d26
 	void *data;
44e2d26
 };
44e2d26
 
44e2d26
+struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil);
44e2d26
+char *cil_tree_get_cil_path(struct cil_tree_node *node);
44e2d26
+__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...);
44e2d26
+
44e2d26
 int cil_tree_init(struct cil_tree **tree);
44e2d26
 void cil_tree_destroy(struct cil_tree **tree);
44e2d26
 void cil_tree_subtree_destroy(struct cil_tree_node *node);
44e2d26
diff --git libsepol-2.5/cil/src/cil_verify.c libsepol-2.5/cil/src/cil_verify.c
44e2d26
index 36ec45a..038f77a 100644
44e2d26
--- libsepol-2.5/cil/src/cil_verify.c
44e2d26
+++ libsepol-2.5/cil/src/cil_verify.c
44e2d26
@@ -377,25 +377,25 @@ int __cil_verify_ordered_node_helper(struct cil_tree_node *node, __attribute__((
44e2d26
 		if (node->flavor == CIL_SID) {
44e2d26
 			struct cil_sid *sid = node->data;
44e2d26
 			if (sid->ordered == CIL_FALSE) {
44e2d26
-				cil_log(CIL_ERR, "SID %s not in sidorder statement at line %d of %s\n", sid->datum.name, node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_ERR, "SID %s not in sidorder statement", sid->datum.name);
44e2d26
 				return SEPOL_ERR;
44e2d26
 			}
44e2d26
 		} else if (node->flavor == CIL_CLASS) {
44e2d26
 			struct cil_class *class = node->data;
44e2d26
 			if (class->ordered == CIL_FALSE) {
44e2d26
-				cil_log(CIL_ERR, "Class %s not in classorder statement at line %d of %s\n", class->datum.name, node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_ERR, "Class %s not in classorder statement", class->datum.name);
44e2d26
 				return SEPOL_ERR;
44e2d26
 			}
44e2d26
 		} else if (node->flavor == CIL_CAT) {
44e2d26
 			struct cil_cat *cat = node->data;
44e2d26
 			if (cat->ordered == CIL_FALSE) {
44e2d26
-				cil_log(CIL_ERR, "Category %s not in categoryorder statement at line %d of %s\n", cat->datum.name, node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_ERR, "Category %s not in categoryorder statement", cat->datum.name);
44e2d26
 				return SEPOL_ERR;
44e2d26
 			}
44e2d26
 		} else if (node->flavor == CIL_SENS) {
44e2d26
 			struct cil_sens *sens = node->data;
44e2d26
 			if (sens->ordered == CIL_FALSE) {
44e2d26
-				cil_log(CIL_ERR, "Sensitivity %s not in sensitivityorder statement at line %d of %s\n", sens->datum.name, node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_ERR, "Sensitivity %s not in sensitivityorder statement", sens->datum.name);
44e2d26
 				return SEPOL_ERR;
44e2d26
 			}
44e2d26
 		}
44e2d26
@@ -430,7 +430,7 @@ int __cil_verify_initsids(struct cil_list *sids)
44e2d26
 		struct cil_sid *sid = i->data;
44e2d26
 		if (sid->context == NULL) {
44e2d26
 			struct cil_tree_node *node = sid->datum.nodes->head->data;
44e2d26
-			cil_log(CIL_ERR, "No context assigned to SID %s declared at line %d in %s\n",sid->datum.name, node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "No context assigned to SID %s declared",sid->datum.name);
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 		}
44e2d26
 	}
44e2d26
@@ -598,7 +598,7 @@ int __cil_verify_named_levelrange(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid named range at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid named range");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -638,7 +638,7 @@ static int __cil_verify_user_pre_eval(struct cil_tree_node *node)
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid user at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid user");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -657,7 +657,7 @@ static int __cil_verify_user_post_eval(struct cil_db *db, struct cil_tree_node *
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid user at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid user");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -688,7 +688,7 @@ int __cil_verify_role(struct cil_tree_node *node)
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid role at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid role");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -719,7 +719,7 @@ int __cil_verify_type(struct cil_tree_node *node)
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid type at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid type");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -813,7 +813,7 @@ int __cil_verify_named_context(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid named context at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid named context");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -852,8 +852,7 @@ int __cil_verify_rule(struct cil_tree_node *node, struct cil_complex_symtab *sym
44e2d26
 		struct cil_complex_symtab_datum *datum = NULL;
44e2d26
 		cil_complex_symtab_search(symtab, &ckey, &datum);
44e2d26
 		if (datum == NULL) {
44e2d26
-			cil_log(CIL_ERR, "Duplicate rule defined on line %d of %s\n", 
44e2d26
-				node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Duplicate rule defined");
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
@@ -861,7 +860,7 @@ int __cil_verify_rule(struct cil_tree_node *node, struct cil_complex_symtab *sym
44e2d26
 
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid rule at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid rule");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -877,11 +876,9 @@ int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute__((unu
44e2d26
 		avrule = rule_node->data;
44e2d26
 		if (avrule->rule_kind == CIL_AVRULE_NEVERALLOW) {
44e2d26
 			if (bif->preserved_tunable) {
44e2d26
-				cil_log(CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables) at line %d or %s\n",
44e2d26
-					node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables)");
44e2d26
 			} else {
44e2d26
-				cil_log(CIL_ERR, "Neverallow found in booleanif block at line %d or %s\n",
44e2d26
-					node->line, node->path);
44e2d26
+				cil_tree_log(node, CIL_ERR, "Neverallow found in booleanif block");
44e2d26
 			}
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
@@ -942,11 +939,9 @@ int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute__((unu
44e2d26
 	default: {
44e2d26
 		const char * flavor = cil_node_to_string(node);
44e2d26
 		if (bif->preserved_tunable) {
44e2d26
-			cil_log(CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables) at line %d of %s\n",
44e2d26
-					flavor, node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables)", flavor);
44e2d26
 		} else {
44e2d26
-			cil_log(CIL_ERR, "Invalid %s statement in booleanif at line %d of %s\n",
44e2d26
-					flavor, node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Invalid %s statement in booleanif", flavor);
44e2d26
 		}
44e2d26
 		goto exit;
44e2d26
 	}
44e2d26
@@ -974,9 +969,9 @@ int __cil_verify_booleanif(struct cil_tree_node *node, struct cil_complex_symtab
44e2d26
 	return SEPOL_OK;
44e2d26
 exit:
44e2d26
 	if (bif->preserved_tunable) {
44e2d26
-		cil_log(CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables) at line %d of %s\n", node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables)");
44e2d26
 	} else {
44e2d26
-		cil_log(CIL_ERR, "Invalid booleanif at line %d of %s\n", node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_ERR, "Invalid booleanif");
44e2d26
 	}
44e2d26
 	return rc;
44e2d26
 }
44e2d26
@@ -1007,7 +1002,7 @@ int __cil_verify_netifcon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid netifcon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid netifcon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1028,7 +1023,7 @@ int __cil_verify_genfscon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid genfscon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid genfscon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1047,8 +1042,7 @@ int __cil_verify_filecon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	if (ctx->datum.name == NULL) {
44e2d26
 		rc = __cil_verify_context(db, ctx);
44e2d26
 		if (rc != SEPOL_OK) {
44e2d26
-			cil_log(CIL_ERR, "Invalid filecon at line %d of %s\n", 
44e2d26
-				node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Invalid filecon");
44e2d26
 			goto exit;
44e2d26
 		}
44e2d26
 	}
44e2d26
@@ -1076,7 +1070,7 @@ int __cil_verify_nodecon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid nodecon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid nodecon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1097,7 +1091,7 @@ int __cil_verify_portcon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid portcon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid portcon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1118,7 +1112,7 @@ int __cil_verify_pirqcon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid pirqcon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid pirqcon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1139,7 +1133,7 @@ int __cil_verify_iomemcon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid iomemcon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid iomemcon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1160,7 +1154,7 @@ int __cil_verify_ioportcon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid ioportcon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid ioportcon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1181,7 +1175,7 @@ int __cil_verify_pcidevicecon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid pcidevicecon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid pcidevicecon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1202,7 +1196,7 @@ int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid devicetreecon at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid devicetreecon");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1223,7 +1217,7 @@ int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
44e2d26
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid fsuse at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid fsuse");
44e2d26
 	return rc;
44e2d26
 }
44e2d26
 
44e2d26
@@ -1241,7 +1235,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node
44e2d26
 			kind_str = CIL_KEY_IOCTL;
44e2d26
 			break;
44e2d26
 		default:
44e2d26
-			cil_log(CIL_ERR, "Invalid permissionx kind (%d) at line %d of %s\n", permx->kind, node->line, node->path);
44e2d26
+			cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind);
44e2d26
 			rc = SEPOL_ERR;
44e2d26
 			goto exit;
44e2d26
 	}
44e2d26
@@ -1257,7 +1251,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node
71b1a80
 			}
71b1a80
 
44e2d26
 			if (rc == SEPOL_ENOENT) {
44e2d26
-				cil_log(CIL_ERR, "Invalid permissionx at line %d of %s: %s is not a permission of class %s\n", node->line, node->path, kind_str, class->datum.name);
44e2d26
+				cil_tree_log(node, CIL_ERR, "Invalid permissionx: %s is not a permission of class %s", kind_str, class->datum.name);
44e2d26
 				rc = SEPOL_ERR;
44e2d26
 				goto exit;
44e2d26
 			}
44e2d26
@@ -1312,7 +1306,7 @@ int __cil_verify_class(struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
71b1a80
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid class at line %d of %s\n", node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid class");
44e2d26
 	return rc;
44e2d26
 }
71b1a80
 
44e2d26
@@ -1329,8 +1323,7 @@ int __cil_verify_policycap(struct cil_tree_node *node)
44e2d26
 	return SEPOL_OK;
71b1a80
 
44e2d26
 exit:
44e2d26
-	cil_log(CIL_ERR, "Invalid policycap (%s) at line %d of %s\n", 
44e2d26
-		(const char*)polcap->datum.name, node->line, node->path);
44e2d26
+	cil_tree_log(node, CIL_ERR, "Invalid policycap (%s)", (const char*)polcap->datum.name);
44e2d26
 	return rc;
44e2d26
 }
71b1a80
 
44e2d26
@@ -1547,14 +1540,14 @@ static int __cil_verify_classpermission(struct cil_tree_node *node)
44e2d26
 	struct cil_classpermission *cp = node->data;
71b1a80
 
44e2d26
 	if (cp->classperms == NULL) {
44e2d26
-		cil_log(CIL_ERR, "Classpermission %s does not have a classpermissionset at line %d of %s\n", cp->datum.name, node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_ERR, "Classpermission %s does not have a classpermissionset", cp->datum.name);
a7ec325
 		rc = SEPOL_ERR;
44e2d26
 		goto exit;
71b1a80
 	}
0a1d1e5
 
44e2d26
 	rc = __cil_verify_classperms(cp->classperms, &cp->datum);
44e2d26
 	if (rc != SEPOL_OK) {
44e2d26
-		cil_log(CIL_ERR, "Found circular class permissions involving the set %s at line %d of %s\n",cp->datum.name, node->line, node->path);
44e2d26
+		cil_tree_log(node, CIL_ERR, "Found circular class permissions involving the set %s",cp->datum.name);
44e2d26
 		goto exit;
0a1d1e5
 	}
0a1d1e5
 
44e2d26
@@ -1577,14 +1570,14 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k,
44e2d26
 	struct cil_perm *cmp = (struct cil_perm *)d;
a7ec325
 
44e2d26
 	if (cmp->classperms == NULL) {
44e2d26
-		cil_log(CIL_ERR, "Map class %s does not have a classmapping for %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path);
44e2d26
+		cil_tree_log(map_args->node, CIL_ERR, "Map class %s does not have a classmapping for %s", map_args->class->datum.name, cmp->datum.name);
44e2d26
 		map_args->rc = SEPOL_ERR;
44e2d26
 		goto exit;
44e2d26
 	}
a7ec325
 
44e2d26
 	rc = __cil_verify_classperms(cmp->classperms, &cmp->datum);
44e2d26
 	if (rc != SEPOL_OK) {
44e2d26
-		cil_log(CIL_ERR, "Found circular class permissions involving the map class %s and permission %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path);
44e2d26
+		cil_tree_log(map_args->node, CIL_ERR, "Found circular class permissions involving the map class %s and permission %s", map_args->class->datum.name, cmp->datum.name);
44e2d26
 		map_args->rc = SEPOL_ERR;
44e2d26
 		goto exit;
44e2d26
 	}
a7ec325
diff --git libsepol-2.5/include/sepol/port_record.h libsepol-2.5/include/sepol/port_record.h
a7ec325
index 697cea4..c07d1fa 100644
a7ec325
--- libsepol-2.5/include/sepol/port_record.h
a7ec325
+++ libsepol-2.5/include/sepol/port_record.h
a7ec325
@@ -14,6 +14,7 @@ typedef struct sepol_port_key sepol_port_key_t;
a7ec325
 
a7ec325
 #define SEPOL_PROTO_UDP 0
a7ec325
 #define SEPOL_PROTO_TCP 1
a7ec325
+#define SEPOL_PROTO_DCCP 2
a7ec325
 
a7ec325
 /* Key */
a7ec325
 extern int sepol_port_compare(const sepol_port_t * port,
44e2d26
diff --git libsepol-2.5/src/Makefile libsepol-2.5/src/Makefile
44e2d26
index db6c2ba..b0c901f 100644
44e2d26
--- libsepol-2.5/src/Makefile
44e2d26
+++ libsepol-2.5/src/Makefile
44e2d26
@@ -18,15 +18,15 @@ TARGET=libsepol.so
44e2d26
 LIBPC=libsepol.pc
44e2d26
 LIBMAP=libsepol.map
44e2d26
 LIBSO=$(TARGET).$(LIBVERSION)
44e2d26
-OBJS= $(patsubst %.c,%.o,$(wildcard *.c))
44e2d26
-LOBJS= $(patsubst %.c,%.lo,$(wildcard *.c))
44e2d26
+OBJS= $(patsubst %.c,%.o,$(sort $(wildcard *.c)))
44e2d26
+LOBJS= $(patsubst %.c,%.lo,$(sort $(wildcard *.c)))
44e2d26
 CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2
44e2d26
 
44e2d26
 override CFLAGS += -I. -I../include -D_GNU_SOURCE
44e2d26
 
44e2d26
 ifneq ($(DISABLE_CIL),y)
44e2d26
-OBJS += $(sort $(patsubst %.c,%.o,$(wildcard $(CILDIR)/src/*.c) $(CIL_GENERATED)))
44e2d26
-LOBJS += $(sort $(patsubst %.c,%.lo,$(wildcard $(CILDIR)/src/*.c) $(CIL_GENERATED)))
44e2d26
+OBJS += $(sort $(patsubst %.c,%.o,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED)))
44e2d26
+LOBJS += $(sort $(patsubst %.c,%.lo,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED)))
44e2d26
 override CFLAGS += -I$(CILDIR)/include
44e2d26
 endif
44e2d26
 
44e2d26
@@ -76,7 +76,7 @@ relabel:
44e2d26
 	/sbin/restorecon $(SHLIBDIR)/$(LIBSO)
44e2d26
 
44e2d26
 clean: 
44e2d26
-	-rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED)
44e2d26
+	-rm -f $(LIBPC) $(LIBMAP) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED)
44e2d26
 
44e2d26
 indent:
44e2d26
 	../../scripts/Lindent $(wildcard *.[ch])
71b1a80
diff --git libsepol-2.5/src/assertion.c libsepol-2.5/src/assertion.c
44e2d26
index fbf397f..a4be880 100644
71b1a80
--- libsepol-2.5/src/assertion.c
71b1a80
+++ libsepol-2.5/src/assertion.c
71b1a80
@@ -147,36 +147,49 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle,
71b1a80
 	avtab_key_t tmp_key;
71b1a80
 	avtab_extended_perms_t *xperms;
71b1a80
 	avtab_extended_perms_t error;
44e2d26
+	ebitmap_t *sattr = &p->type_attr_map[stype];
44e2d26
+	ebitmap_t *tattr = &p->type_attr_map[ttype];
71b1a80
+	ebitmap_node_t *snode, *tnode;
71b1a80
+	unsigned int i, j;
71b1a80
 	int rc = 1;
71b1a80
 	int ret = 0;
71b1a80
 
71b1a80
 	memcpy(&tmp_key, k, sizeof(avtab_key_t));
71b1a80
 	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
71b1a80
 
71b1a80
-	for (node = avtab_search_node(avtab, &tmp_key);
71b1a80
-	     node;
71b1a80
-	     node = avtab_search_node_next(node, tmp_key.specified)) {
71b1a80
-		xperms = node->datum.xperms;
71b1a80
-		if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
71b1a80
-				&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
71b1a80
+	ebitmap_for_each_bit(sattr, snode, i) {
71b1a80
+		if (!ebitmap_node_get_bit(snode, i))
71b1a80
 			continue;
71b1a80
+		ebitmap_for_each_bit(tattr, tnode, j) {
71b1a80
+			if (!ebitmap_node_get_bit(tnode, j))
71b1a80
+				continue;
71b1a80
+			tmp_key.source_type = i + 1;
71b1a80
+			tmp_key.target_type = j + 1;
71b1a80
+			for (node = avtab_search_node(avtab, &tmp_key);
71b1a80
+			     node;
71b1a80
+			     node = avtab_search_node_next(node, tmp_key.specified)) {
71b1a80
+				xperms = node->datum.xperms;
71b1a80
+				if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
71b1a80
+						&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
71b1a80
+					continue;
71b1a80
 
71b1a80
-		rc = check_extended_permissions(avrule->xperms, xperms);
71b1a80
-		/* failure on the extended permission check_extended_permissionss */
71b1a80
-		if (rc) {
71b1a80
-			extended_permissions_violated(&error, avrule->xperms, xperms);
71b1a80
-			ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
71b1a80
-					"allowxperm %s %s:%s %s;",
71b1a80
-					avrule->source_line, avrule->source_filename, avrule->line,
71b1a80
-					p->p_type_val_to_name[stype],
71b1a80
-					p->p_type_val_to_name[ttype],
71b1a80
-					p->p_class_val_to_name[curperm->tclass - 1],
71b1a80
-					sepol_extended_perms_to_string(&error));
71b1a80
-
71b1a80
-			rc = 0;
71b1a80
-			ret++;
71b1a80
+				rc = check_extended_permissions(avrule->xperms, xperms);
44e2d26
+				/* failure on the extended permission check_extended_permissions */
71b1a80
+				if (rc) {
71b1a80
+					extended_permissions_violated(&error, avrule->xperms, xperms);
71b1a80
+					ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n"
71b1a80
+							"allowxperm %s %s:%s %s;",
71b1a80
+							avrule->source_line, avrule->source_filename, avrule->line,
44e2d26
+							p->p_type_val_to_name[i],
44e2d26
+							p->p_type_val_to_name[j],
71b1a80
+							p->p_class_val_to_name[curperm->tclass - 1],
71b1a80
+							sepol_extended_perms_to_string(&error));
71b1a80
+
71b1a80
+					rc = 0;
71b1a80
+					ret++;
71b1a80
+				}
71b1a80
+			}
71b1a80
 		}
71b1a80
-
71b1a80
 	}
71b1a80
 
71b1a80
 	/* failure on the regular permissions */
44e2d26
@@ -304,9 +317,57 @@ oom:
44e2d26
 }
44e2d26
 
44e2d26
 /*
44e2d26
- * If the ioctl permission is granted in check_assertion_avtab_match for the
44e2d26
- * source/target/class matching the current avrule neverallow, a lookup is
44e2d26
- * performed to determine if extended permissions exist for the source/target/class.
44e2d26
+ * Look up the extended permissions in avtab and verify that neverallowed
44e2d26
+ * permissions are not granted.
44e2d26
+ */
44e2d26
+static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab,
44e2d26
+						unsigned int stype, unsigned int ttype,
71b1a80
+						avtab_key_t *k, policydb_t *p)
44e2d26
+{
44e2d26
+	avtab_ptr_t node;
44e2d26
+	avtab_key_t tmp_key;
44e2d26
+	avtab_extended_perms_t *xperms;
44e2d26
+	av_extended_perms_t *neverallow_xperms = avrule->xperms;
44e2d26
+	ebitmap_t *sattr = &p->type_attr_map[stype];
44e2d26
+	ebitmap_t *tattr = &p->type_attr_map[ttype];
71b1a80
+	ebitmap_node_t *snode, *tnode;
71b1a80
+	unsigned int i, j;
44e2d26
+	int rc = 1;
44e2d26
+
44e2d26
+	memcpy(&tmp_key, k, sizeof(avtab_key_t));
44e2d26
+	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
44e2d26
+
71b1a80
+	ebitmap_for_each_bit(sattr, snode, i) {
71b1a80
+		if (!ebitmap_node_get_bit(snode, i))
44e2d26
+			continue;
71b1a80
+		ebitmap_for_each_bit(tattr, tnode, j) {
71b1a80
+			if (!ebitmap_node_get_bit(tnode, j))
71b1a80
+				continue;
71b1a80
+			tmp_key.source_type = i + 1;
71b1a80
+			tmp_key.target_type = j + 1;
71b1a80
+			for (node = avtab_search_node(avtab, &tmp_key);
71b1a80
+			     node;
71b1a80
+			     node = avtab_search_node_next(node, tmp_key.specified)) {
71b1a80
+				xperms = node->datum.xperms;
71b1a80
+
71b1a80
+				if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
71b1a80
+						&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
71b1a80
+					continue;
71b1a80
+				rc = check_extended_permissions(neverallow_xperms, xperms);
71b1a80
+				if (rc)
71b1a80
+					break;
71b1a80
+			}
71b1a80
+		}
44e2d26
+	}
44e2d26
+
44e2d26
+	return rc;
44e2d26
+}
44e2d26
+
44e2d26
+/*
44e2d26
+ * When the ioctl permission is granted on an avtab entry that matches an
44e2d26
+ * avrule neverallowxperm entry, enumerate over the matching
44e2d26
+ * source/target/class sets to determine if the extended permissions exist
44e2d26
+ * and if the neverallowed ioctls are granted.
44e2d26
  *
44e2d26
  * Four scenarios of interest:
44e2d26
  * 1. PASS - the ioctl permission is not granted for this source/target/class
44e2d26
@@ -319,33 +380,72 @@ oom:
44e2d26
  *    granted
44e2d26
  */
44e2d26
 static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab,
44e2d26
-						avtab_key_t *k)
44e2d26
+						avtab_key_t *k, policydb_t *p)
44e2d26
 {
44e2d26
-	avtab_ptr_t node;
44e2d26
-	avtab_key_t tmp_key;
44e2d26
-	avtab_extended_perms_t *xperms;
44e2d26
-	av_extended_perms_t *neverallow_xperms = avrule->xperms;
44e2d26
-	int rc = 1;
44e2d26
+	ebitmap_t src_matches, tgt_matches, matches;
44e2d26
+	unsigned int i, j;
44e2d26
+	ebitmap_node_t *snode, *tnode;
44e2d26
+	class_perm_node_t *cp;
44e2d26
+	int rc;
44e2d26
+	int ret = 1;
44e2d26
 
44e2d26
-	memcpy(&tmp_key, k, sizeof(avtab_key_t));
44e2d26
-	tmp_key.specified = AVTAB_XPERMS_ALLOWED;
44e2d26
+	ebitmap_init(&src_matches);
44e2d26
+	ebitmap_init(&tgt_matches);
44e2d26
+	ebitmap_init(&matches);
44e2d26
+	rc = ebitmap_and(&src_matches, &avrule->stypes.types,
44e2d26
+			 &p->attr_type_map[k->source_type - 1]);
44e2d26
+	if (rc)
44e2d26
+		goto oom;
44e2d26
 
44e2d26
-	for (node = avtab_search_node(avtab, &tmp_key);
44e2d26
-	     node;
44e2d26
-	     node = avtab_search_node_next(node, tmp_key.specified)) {
44e2d26
-		xperms = node->datum.xperms;
44e2d26
-		if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
44e2d26
-				&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
44e2d26
-			continue;
44e2d26
+	if (ebitmap_length(&src_matches) == 0)
44e2d26
+		goto exit;
44e2d26
 
44e2d26
-		rc = check_extended_permissions(neverallow_xperms, xperms);
44e2d26
+	if (avrule->flags == RULE_SELF) {
44e2d26
+		rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1],
44e2d26
+				&p->attr_type_map[k->target_type - 1]);
44e2d26
 		if (rc)
44e2d26
-			break;
44e2d26
+			goto oom;
44e2d26
+		rc = ebitmap_and(&tgt_matches, &avrule->stypes.types, &matches);
44e2d26
+		if (rc)
44e2d26
+			goto oom;
44e2d26
+	} else {
44e2d26
+		rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types,
44e2d26
+				&p->attr_type_map[k->target_type -1]);
44e2d26
+		if (rc)
44e2d26
+			goto oom;
71b1a80
 	}
71b1a80
 
44e2d26
-	return rc;
44e2d26
-}
44e2d26
+	if (ebitmap_length(&tgt_matches) == 0)
44e2d26
+		goto exit;
44e2d26
 
44e2d26
+	for (cp = avrule->perms; cp; cp = cp->next) {
44e2d26
+		if (cp->tclass != k->target_class)
44e2d26
+			continue;
44e2d26
+		ebitmap_for_each_bit(&src_matches, snode, i) {
44e2d26
+			if (!ebitmap_node_get_bit(snode, i))
44e2d26
+				continue;
44e2d26
+			ebitmap_for_each_bit(&tgt_matches, tnode, j) {
44e2d26
+				if (!ebitmap_node_get_bit(tnode, j))
44e2d26
+					continue;
44e2d26
+
44e2d26
+				ret = check_assertion_extended_permissions_avtab(
44e2d26
+						avrule, avtab, i, j, k, p);
44e2d26
+				if (ret)
44e2d26
+					goto exit;
44e2d26
+			}
44e2d26
+		}
44e2d26
+	}
44e2d26
+	goto exit;
44e2d26
+
44e2d26
+oom:
44e2d26
+	ERR(NULL, "Out of memory - unable to check neverallows");
44e2d26
+
44e2d26
+exit:
44e2d26
+	ebitmap_destroy(&src_matches);
44e2d26
+	ebitmap_destroy(&tgt_matches);
44e2d26
+	ebitmap_destroy(&matches);
44e2d26
+	return ret;
44e2d26
+}
44e2d26
 
44e2d26
 static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
44e2d26
 {
44e2d26
@@ -355,7 +455,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a
44e2d26
 	avrule_t *avrule = a->avrule;
44e2d26
 	avtab_t *avtab = a->avtab;
44e2d26
 
44e2d26
-	if (k->specified != AVTAB_ALLOWED && k->specified != AVTAB_XPERMS_ALLOWED)
44e2d26
+	if (k->specified != AVTAB_ALLOWED)
44e2d26
 		goto exit;
44e2d26
 
44e2d26
 	if (!match_any_class_permissions(avrule->perms, k->target_class, d->data))
44e2d26
@@ -386,7 +486,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a
71b1a80
 		goto exit;
71b1a80
 
71b1a80
 	if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) {
71b1a80
-		rc = check_assertion_extended_permissions(avrule, avtab, k);
71b1a80
+		rc = check_assertion_extended_permissions(avrule, avtab, k, p);
71b1a80
 		if (rc == 0)
71b1a80
 			goto exit;
71b1a80
 	}
0a1d1e5
diff --git libsepol-2.5/src/genbools.c libsepol-2.5/src/genbools.c
0a1d1e5
index 6a06ec9..c81e848 100644
0a1d1e5
--- libsepol-2.5/src/genbools.c
0a1d1e5
+++ libsepol-2.5/src/genbools.c
0a1d1e5
@@ -79,7 +79,7 @@ static int load_booleans(struct policydb *policydb, const char *path,
0a1d1e5
 	if (boolf == NULL)
0a1d1e5
 		goto localbool;
0a1d1e5
 
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
         if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) {
0a1d1e5
           ERR(NULL, "out of memory");
0a1d1e5
 	  return -1;
0a1d1e5
@@ -111,7 +111,7 @@ static int load_booleans(struct policydb *policydb, const char *path,
0a1d1e5
 	boolf = fopen(localbools, "r");
0a1d1e5
 	if (boolf != NULL) {
0a1d1e5
 
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
 
0a1d1e5
 	  while(fgets(buffer, 255, boolf) != NULL) {
0a1d1e5
 #else
0a1d1e5
diff --git libsepol-2.5/src/genusers.c libsepol-2.5/src/genusers.c
0a1d1e5
index 7826b71..0b98a76 100644
0a1d1e5
--- libsepol-2.5/src/genusers.c
0a1d1e5
+++ libsepol-2.5/src/genusers.c
0a1d1e5
@@ -7,7 +7,7 @@
0a1d1e5
 
0a1d1e5
 #include <sepol/policydb/policydb.h>
0a1d1e5
 
0a1d1e5
-#ifndef DARWIN
0a1d1e5
+#ifndef __APPLE__
0a1d1e5
 #include <stdio_ext.h>
0a1d1e5
 #endif
0a1d1e5
 
0a1d1e5
@@ -47,7 +47,7 @@ static int load_users(struct policydb *policydb, const char *path)
0a1d1e5
 	if (fp == NULL)
0a1d1e5
 		return -1;
0a1d1e5
 
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
 	if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) {
0a1d1e5
 	  ERR(NULL, "out of memory");
0a1d1e5
 	  return -1;
d88ffa1
diff --git libsepol-2.5/src/hierarchy.c libsepol-2.5/src/hierarchy.c
0a1d1e5
index 6f73195..778541a 100644
d88ffa1
--- libsepol-2.5/src/hierarchy.c
d88ffa1
+++ libsepol-2.5/src/hierarchy.c
d88ffa1
@@ -121,18 +121,6 @@ static int bounds_expand_rule(sepol_handle_t *handle, policydb_t *p,
d88ffa1
 		}
d88ffa1
 	}
d88ffa1
 
d88ffa1
-	if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], parent - 1)) {
d88ffa1
-		avtab_key.target_type = parent;
d88ffa1
-		ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) {
d88ffa1
-			if (!ebitmap_node_get_bit(tnode, i))
d88ffa1
-				continue;
d88ffa1
-			avtab_key.source_type = i + 1;
d88ffa1
-			rc = bounds_insert_rule(handle, avtab, global, other,
d88ffa1
-						&avtab_key, &datum);
d88ffa1
-			if (rc) goto exit;
d88ffa1
-		}
d88ffa1
-	}
d88ffa1
-
d88ffa1
 exit:
d88ffa1
 	return rc;
d88ffa1
 }
0a1d1e5
@@ -313,45 +301,21 @@ static int bounds_check_rule(sepol_handle_t *handle, policydb_t *p,
0a1d1e5
 		ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
0a1d1e5
 			if (!ebitmap_node_get_bit(tnode, i))
0a1d1e5
 				continue;
0a1d1e5
-			avtab_key.target_type = i + 1;
0a1d1e5
-			d = bounds_not_covered(global_avtab, cur_avtab,
0a1d1e5
-					       &avtab_key, data);
0a1d1e5
-			if (!d) continue;
0a1d1e5
 			td = p->type_val_to_struct[i];
0a1d1e5
 			if (td && td->bounds) {
0a1d1e5
 				avtab_key.target_type = td->bounds;
0a1d1e5
 				d = bounds_not_covered(global_avtab, cur_avtab,
0a1d1e5
 						       &avtab_key, data);
0a1d1e5
-				if (!d) continue;
0a1d1e5
-			}
0a1d1e5
-			(*numbad)++;
0a1d1e5
-			rc = bounds_add_bad(handle, child, i+1, class, d, bad);
0a1d1e5
-			if (rc) goto exit;
0a1d1e5
-		}
0a1d1e5
-	}
d88ffa1
-	if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], child - 1)) {
d88ffa1
-		avtab_key.target_type = parent;
d88ffa1
-		ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) {
d88ffa1
-			if (!ebitmap_node_get_bit(tnode, i))
d88ffa1
-				continue;
d88ffa1
-			avtab_key.source_type = i + 1;
d88ffa1
-			if (avtab_key.source_type == child) {
d88ffa1
-				/* Checked above */
d88ffa1
-				continue;
d88ffa1
-			}
d88ffa1
-			d = bounds_not_covered(global_avtab, cur_avtab,
d88ffa1
-					       &avtab_key, data);
d88ffa1
-			if (!d) continue;
d88ffa1
-			td = p->type_val_to_struct[i];
d88ffa1
-			if (td && td->bounds) {
d88ffa1
-				avtab_key.source_type = td->bounds;
0a1d1e5
+			} else {
0a1d1e5
+				avtab_key.target_type = i + 1;
0a1d1e5
 				d = bounds_not_covered(global_avtab, cur_avtab,
0a1d1e5
 						       &avtab_key, data);
d88ffa1
-				if (!d) continue;
0a1d1e5
 			}
d88ffa1
-			(*numbad)++;
d88ffa1
-			rc = bounds_add_bad(handle, i+1, child, class, d, bad);
d88ffa1
-			if (rc) goto exit;
0a1d1e5
+			if (d) {
0a1d1e5
+				(*numbad)++;
0a1d1e5
+				rc = bounds_add_bad(handle, child, i+1, class, d, bad);
0a1d1e5
+				if (rc) goto exit;
0a1d1e5
+			}
0a1d1e5
 		}
0a1d1e5
 	}
d88ffa1
 
a7ec325
diff --git libsepol-2.5/src/module_to_cil.c libsepol-2.5/src/module_to_cil.c
44e2d26
index 18ec6b9..b9a4af7 100644
a7ec325
--- libsepol-2.5/src/module_to_cil.c
a7ec325
+++ libsepol-2.5/src/module_to_cil.c
71b1a80
@@ -26,6 +26,9 @@
71b1a80
 #include <getopt.h>
71b1a80
 #include <libgen.h>
71b1a80
 #include <netinet/in.h>
71b1a80
+#ifndef IPPROTO_DCCP
71b1a80
+#define IPPROTO_DCCP 33
71b1a80
+#endif
71b1a80
 #include <signal.h>
71b1a80
 #include <stdarg.h>
71b1a80
 #include <stdio.h>
44e2d26
@@ -1070,6 +1073,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a
44e2d26
 	struct type_set *ts;
44e2d26
 
44e2d26
 	for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) {
44e2d26
+		if (avrule->specified == AVRULE_NEVERALLOW && avrule->source_filename) {
44e2d26
+			cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename);
44e2d26
+		}
44e2d26
+
44e2d26
 		ts = &avrule->stypes;
44e2d26
 		rc = process_typeset(indent, pdb, ts, attr_list, &snames, &num_snames);
44e2d26
 		if (rc != 0) {
44e2d26
@@ -1100,6 +1107,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a
44e2d26
 
44e2d26
 		names_destroy(&snames, &num_snames);
44e2d26
 		names_destroy(&tnames, &num_tnames);
44e2d26
+
44e2d26
+		if (avrule->specified == AVRULE_NEVERALLOW && avrule->source_filename) {
44e2d26
+			cil_println(0, ";;* lme\n");
44e2d26
+		}
44e2d26
 	}
44e2d26
 
44e2d26
 	return 0;
44e2d26
@@ -2537,6 +2548,7 @@ static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *p
a7ec325
 		switch (portcon->u.port.protocol) {
a7ec325
 		case IPPROTO_TCP: protocol = "tcp"; break;
a7ec325
 		case IPPROTO_UDP: protocol = "udp"; break;
a7ec325
+		case IPPROTO_DCCP: protocol = "dccp"; break;
a7ec325
 		default:
a7ec325
 			log_err("Unknown portcon protocol: %i", portcon->u.port.protocol);
a7ec325
 			rc = -1;
0a1d1e5
diff --git libsepol-2.5/src/node_record.c libsepol-2.5/src/node_record.c
0a1d1e5
index bd48ba0..21043b6 100644
0a1d1e5
--- libsepol-2.5/src/node_record.c
0a1d1e5
+++ libsepol-2.5/src/node_record.c
0a1d1e5
@@ -70,7 +70,7 @@ static int node_parse_addr(sepol_handle_t * handle,
0a1d1e5
 				return STATUS_ERR;
0a1d1e5
 			}
0a1d1e5
 
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
 			memcpy(addr_bytes, in_addr.s6_addr, 16);
0a1d1e5
 #else
0a1d1e5
 			memcpy(addr_bytes, in_addr.s6_addr32, 16);
0a1d1e5
@@ -162,7 +162,7 @@ static int node_expand_addr(sepol_handle_t * handle,
0a1d1e5
 		{
0a1d1e5
 			struct in6_addr addr;
0a1d1e5
 			memset(&addr, 0, sizeof(struct in6_addr));
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
 			memcpy(&addr.s6_addr[0], addr_bytes, 16);
0a1d1e5
 #else
0a1d1e5
 			memcpy(&addr.s6_addr32[0], addr_bytes, 16);
5ec2ad1
diff --git libsepol-2.5/src/nodes.c libsepol-2.5/src/nodes.c
5ec2ad1
index 50cf21d..820346d 100644
5ec2ad1
--- libsepol-2.5/src/nodes.c
5ec2ad1
+++ libsepol-2.5/src/nodes.c
5ec2ad1
@@ -273,6 +273,7 @@ int sepol_node_query(sepol_handle_t * handle,
5ec2ad1
 							   c, SEPOL_PROTO_IP6,
5ec2ad1
 							   response) < 0)
5ec2ad1
 						goto err;
5ec2ad1
+					return STATUS_SUCCESS;
5ec2ad1
 				}
5ec2ad1
 			}
5ec2ad1
 			break;
a7ec325
diff --git libsepol-2.5/src/port_record.c libsepol-2.5/src/port_record.c
a7ec325
index 6a33d93..ed9093b 100644
a7ec325
--- libsepol-2.5/src/port_record.c
a7ec325
+++ libsepol-2.5/src/port_record.c
a7ec325
@@ -184,6 +184,8 @@ const char *sepol_port_get_proto_str(int proto)
a7ec325
 		return "udp";
a7ec325
 	case SEPOL_PROTO_TCP:
a7ec325
 		return "tcp";
a7ec325
+	case SEPOL_PROTO_DCCP:
a7ec325
+		return "dccp";
a7ec325
 	default:
a7ec325
 		return "???";
a7ec325
 	}
a7ec325
diff --git libsepol-2.5/src/ports.c libsepol-2.5/src/ports.c
71b1a80
index 607a629..62ec602 100644
a7ec325
--- libsepol-2.5/src/ports.c
a7ec325
+++ libsepol-2.5/src/ports.c
71b1a80
@@ -1,4 +1,7 @@
71b1a80
 #include <netinet/in.h>
71b1a80
+#ifndef IPPROTO_DCCP
71b1a80
+#define IPPROTO_DCCP 33
71b1a80
+#endif
71b1a80
 #include <stdlib.h>
71b1a80
 
71b1a80
 #include "debug.h"
71b1a80
@@ -16,6 +19,8 @@ static inline int sepol2ipproto(sepol_handle_t * handle, int proto)
a7ec325
 		return IPPROTO_TCP;
a7ec325
 	case SEPOL_PROTO_UDP:
a7ec325
 		return IPPROTO_UDP;
a7ec325
+	case SEPOL_PROTO_DCCP:
a7ec325
+		return IPPROTO_DCCP;
a7ec325
 	default:
a7ec325
 		ERR(handle, "unsupported protocol %u", proto);
a7ec325
 		return STATUS_ERR;
71b1a80
@@ -30,6 +35,8 @@ static inline int ipproto2sepol(sepol_handle_t * handle, int proto)
a7ec325
 		return SEPOL_PROTO_TCP;
a7ec325
 	case IPPROTO_UDP:
a7ec325
 		return SEPOL_PROTO_UDP;
a7ec325
+	case IPPROTO_DCCP:
a7ec325
+		return SEPOL_PROTO_DCCP;
a7ec325
 	default:
a7ec325
 		ERR(handle, "invalid protocol %u " "found in policy", proto);
a7ec325
 		return STATUS_ERR;
0a1d1e5
diff --git libsepol-2.5/src/private.h libsepol-2.5/src/private.h
0a1d1e5
index 8a6d4bb..9c700c9 100644
0a1d1e5
--- libsepol-2.5/src/private.h
0a1d1e5
+++ libsepol-2.5/src/private.h
0a1d1e5
@@ -5,7 +5,7 @@
0a1d1e5
 #include <sepol/policydb/policydb.h>
0a1d1e5
 
0a1d1e5
 
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
 #include <sys/types.h>
0a1d1e5
 #include <machine/endian.h>
0a1d1e5
 #else
0a1d1e5
@@ -16,7 +16,7 @@
0a1d1e5
 #include <errno.h>
0a1d1e5
 #include <dso.h>
0a1d1e5
 
0a1d1e5
-#ifdef DARWIN
0a1d1e5
+#ifdef __APPLE__
0a1d1e5
 #define __BYTE_ORDER  BYTE_ORDER
0a1d1e5
 #define __LITTLE_ENDIAN  LITTLE_ENDIAN
0a1d1e5
 #endif
44e2d26
diff --git libsepol-2.5/src/services.c libsepol-2.5/src/services.c
44e2d26
index d64a8e8..d2b80b4 100644
44e2d26
--- libsepol-2.5/src/services.c
44e2d26
+++ libsepol-2.5/src/services.c
44e2d26
@@ -1152,20 +1152,16 @@ int hidden sepol_compute_av(sepol_security_id_t ssid,
44e2d26
 int hidden sepol_string_to_security_class(const char *class_name,
44e2d26
 			sepol_security_class_t *tclass)
44e2d26
 {
44e2d26
-	char *class = NULL;
44e2d26
-	sepol_security_class_t id;
44e2d26
-
44e2d26
-	for (id = 1;; id++) {
44e2d26
-		class = policydb->p_class_val_to_name[id - 1];
44e2d26
-		if (class == NULL) {
44e2d26
-			ERR(NULL, "could not convert %s to class id", class_name);
44e2d26
-			return STATUS_ERR;
44e2d26
-		}
44e2d26
-		if ((strcmp(class, class_name)) == 0) {
44e2d26
-			*tclass = id;
44e2d26
-			return STATUS_SUCCESS;
44e2d26
-		}
44e2d26
+	class_datum_t *tclass_datum;
44e2d26
+
44e2d26
+	tclass_datum = hashtab_search(policydb->p_classes.table,
44e2d26
+				      (hashtab_key_t) class_name);
44e2d26
+	if (!tclass_datum) {
44e2d26
+		ERR(NULL, "unrecognized class %s", class_name);
44e2d26
+		return STATUS_ERR;
44e2d26
 	}
44e2d26
+	*tclass = tclass_datum->s.value;
44e2d26
+	return STATUS_SUCCESS;
44e2d26
 }
44e2d26
 
44e2d26
 /*
44e2d26
diff --git libsepol-2.5/tests/.gitignore libsepol-2.5/tests/.gitignore
44e2d26
new file mode 100644
44e2d26
index 0000000..c3f60fd
44e2d26
--- /dev/null
44e2d26
+++ libsepol-2.5/tests/.gitignore
44e2d26
@@ -0,0 +1 @@
44e2d26
+libsepol-tests
44e2d26
diff --git libsepol-2.5/tests/policies/.gitignore libsepol-2.5/tests/policies/.gitignore
44e2d26
new file mode 100644
44e2d26
index 0000000..5a547a8
44e2d26
--- /dev/null
44e2d26
+++ libsepol-2.5/tests/policies/.gitignore
44e2d26
@@ -0,0 +1,3 @@
44e2d26
+test-downgrade/
44e2d26
+test-*/*.mls
44e2d26
+test-*/*.std