diff mbox series

[RFC,1/3] libsepol: update sort order for netifcon definitions

Message ID 20241217135941.536152-3-cgoettsche@seltendoof.de (mailing list archive)
State New
Headers show
Series [RFC,1/3] libsepol: update sort order for netifcon definitions | expand

Commit Message

Christian Göttsche Dec. 17, 2024, 1:59 p.m. UTC
From: Christian Göttsche <cgzones@googlemail.com>

Order netifcon definitions with a wildcard interface name last in object
contexts, so the kernel tries to match literal names first.

Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libsepol/cil/src/cil_post.c     | 36 ++++++++++++++++++++++++++++++---
 libsepol/src/kernel_to_common.c | 36 ++++++++++++++++++++++++++++++---
 2 files changed, 66 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
index d63a5496..70e5b734 100644
--- a/libsepol/cil/src/cil_post.c
+++ b/libsepol/cil/src/cil_post.c
@@ -316,10 +316,40 @@  int cil_post_genfscon_compare(const void *a, const void *b)
 
 int cil_post_netifcon_compare(const void *a, const void *b)
 {
-	struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a;
-	struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b;
+	/* keep in sync with kernel_to_common.c:netif_data_cmp() */
+	const struct cil_netifcon *anetifcon = *(struct cil_netifcon**)a;
+	const struct cil_netifcon *bnetifcon = *(struct cil_netifcon**)b;
+	const char *a_name = anetifcon->interface_str;
+	const char *b_name = bnetifcon->interface_str;
+	size_t a_stem = strcspn(a_name, "*?");
+	size_t b_stem = strcspn(b_name, "*?");
+	size_t a_len = strlen(a_name);
+	size_t b_len = strlen(b_name);
+	int a_iswildcard = a_stem != a_len;
+	int b_iswildcard = b_stem != b_len;
+	int rc;
+
+	/* order non-wildcards first */
+	rc = spaceship_cmp(a_iswildcard, b_iswildcard);
+	if (rc)
+		return rc;
+
+	/* order non-wildcards alphabetically */
+	if (!a_iswildcard)
+		return strcmp(a_name, b_name);
+
+	/* order by decreasing stem length */
+	rc = spaceship_cmp(a_stem, b_stem);
+	if (rc)
+		return -rc;
+
+	/* order '?' (0x3f) before '*' (0x2A) */
+	rc = spaceship_cmp(a_name[a_stem], b_name[b_stem]);
+	if (rc)
+		return -rc;
 
-	return  strcmp(anetifcon->interface_str, bnetifcon->interface_str);
+	/* order alphabetically */
+	return strcmp(a_name, b_name);
 }
 
 int cil_post_ibendportcon_compare(const void *a, const void *b)
diff --git a/libsepol/src/kernel_to_common.c b/libsepol/src/kernel_to_common.c
index 44f0be23..e4338ec6 100644
--- a/libsepol/src/kernel_to_common.c
+++ b/libsepol/src/kernel_to_common.c
@@ -441,10 +441,40 @@  static int portcon_data_cmp(const void *a, const void *b)
 
 static int netif_data_cmp(const void *a, const void *b)
 {
-	struct ocontext *const *aa = a;
-	struct ocontext *const *bb = b;
+	/* keep in sync with cil_post.c:cil_post_netifcon_compare() */
+	const struct ocontext *const *aa = a;
+	const struct ocontext *const *bb = b;
+	const char *a_name = (*aa)->u.name;
+	const char *b_name = (*bb)->u.name;
+	size_t a_stem = strcspn(a_name, "*?");
+	size_t b_stem = strcspn(b_name, "*?");
+	size_t a_len = strlen(a_name);
+	size_t b_len = strlen(b_name);
+	int a_iswildcard = a_stem != a_len;
+	int b_iswildcard = b_stem != b_len;
+	int rc;
 
-	return strcmp((*aa)->u.name, (*bb)->u.name);
+	/* order non-wildcards first */
+	rc = spaceship_cmp(a_iswildcard, b_iswildcard);
+	if (rc)
+		return rc;
+
+	/* order non-wildcards alphabetically */
+	if (!a_iswildcard)
+		return strcmp(a_name, b_name);
+
+	/* order by decreasing stem length */
+	rc = spaceship_cmp(a_stem, b_stem);
+	if (rc)
+		return -rc;
+
+	/* order '?' (0x3f) before '*' (0x2A) */
+	rc = spaceship_cmp(a_name[a_stem], b_name[b_stem]);
+	if (rc)
+		return -rc;
+
+	/* order alphabetically */
+	return strcmp(a_name, b_name);
 }
 
 static int node_data_cmp(const void *a, const void *b)