[PATCH v2 1/1] Detect identical genfscon

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

 



From: Pierre-Hugues Husson <phhusson@xxxxxxxxx>

Currently secilc doesn't deal with duplicate genfscon rules

This commit fixes this, and implements multiple_decls behaviour.

To reduce the code changes, the compare function returns in its LSB
whether the rules are only a matching rule match, or a full match.
---
 libsepol/cil/src/cil_post.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index a2122454..c054e9ce 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -53,6 +53,26 @@
 static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db);
 static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db);
 
+/* compare function returns whether a,b have the same context in the LSB */
+static int compact(void* array, uint32_t *count, int len, int (*compare)(const void *, const void *), int multiple_decls) {
+	char *a = (char*)array;
+	uint32_t i, j = 0;
+	int c;
+	for(i=1; i<*count; i++) {
+		c = compare(a+i*len, a+j*len);
+		/* If LSB is set, it means the rules match except for the context
+		 * We never want this */
+		if(c&1) return SEPOL_ERR;
+
+		if(!multiple_decls && c == 0) return SEPOL_ERR;
+
+		if(c) j++;
+		if(i != j) memcpy(a+j*len, a+i*len, len);
+	}
+	*count = j;
+	return SEPOL_OK;
+}
+
 static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
 {
 	struct cil_list_item *curr;
@@ -202,9 +222,14 @@ int cil_post_genfscon_compare(const void *a, const void *b)
 	struct cil_genfscon *agenfscon = *(struct cil_genfscon**)a;
 	struct cil_genfscon *bgenfscon = *(struct cil_genfscon**)b;
 
-	rc = strcmp(agenfscon->fs_str, bgenfscon->fs_str);
+	rc = 2*strcmp(agenfscon->fs_str, bgenfscon->fs_str);
 	if (rc == 0) {
-		rc = strcmp(agenfscon->path_str, bgenfscon->path_str);
+		rc = 2*strcmp(agenfscon->path_str, bgenfscon->path_str);
+		if(rc == 0) {
+			rc = strcmp(agenfscon->context_str, bgenfscon->context_str);
+			if(rc > 0) rc = 1;
+			if(rc < 0) rc = -1;
+		}
 	}
 
 	return rc;
@@ -2118,6 +2143,11 @@ static int cil_post_db(struct cil_db *db)
 
 	qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare);
 	qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare);
+	rc = compact(db->genfscon->array, &db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare, db->multiple_decls);
+	if (rc != SEPOL_OK) {
+		cil_log(CIL_INFO, "Failed to de-dupe genfscon\n");
+		goto exit;
+	}
 	qsort(db->ibpkeycon->array, db->ibpkeycon->count, sizeof(db->ibpkeycon->array), cil_post_ibpkeycon_compare);
 	qsort(db->ibendportcon->array, db->ibendportcon->count, sizeof(db->ibendportcon->array), cil_post_ibendportcon_compare);
 	qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare);
-- 
2.15.1





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

  Powered by Linux