diff mbox series

[6/7] libsepol/fuzz: handle empty and non kernel policies

Message ID 20231128182334.57740-6-cgzones@googlemail.com (mailing list archive)
State Accepted
Commit 00cfecf62914
Delegated to: Petr Lautrbach
Headers show
Series [1/7] libsepol: validate conditional type rules have a simple default type | expand

Commit Message

Christian Göttsche Nov. 28, 2023, 6:23 p.m. UTC
Do not check assertions for policies without any av rules.

Only output kernel policies in traditional and CIL format.

Perform hierarchy constraint checks.

Try to link, expand and output base module policies.

Also rework argument passing of verbose flags to improve debugging
usability.

Reported-by: oss-fuzz (issues 64515, 64531)
Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
---
 libsepol/fuzz/binpolicy-fuzzer.c | 53 +++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 8 deletions(-)
diff mbox series

Patch

diff --git a/libsepol/fuzz/binpolicy-fuzzer.c b/libsepol/fuzz/binpolicy-fuzzer.c
index 79d42b0e..c21241ed 100644
--- a/libsepol/fuzz/binpolicy-fuzzer.c
+++ b/libsepol/fuzz/binpolicy-fuzzer.c
@@ -1,12 +1,20 @@ 
 #include <sepol/debug.h>
 #include <sepol/kernel_to_cil.h>
 #include <sepol/kernel_to_conf.h>
+#include <sepol/policydb/expand.h>
+#include <sepol/policydb/hierarchy.h>
+#include <sepol/policydb/link.h>
 #include <sepol/policydb/policydb.h>
 
 extern int policydb_validate(sepol_handle_t *handle, const policydb_t *p);
 
 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
 
+
+// set to 1 to enable more verbose libsepol logging
+#define VERBOSE 0
+
+
 static int write_binary_policy(policydb_t *p, FILE *outfp)
 {
 	struct policy_file pf;
@@ -19,12 +27,12 @@  static int write_binary_policy(policydb_t *p, FILE *outfp)
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 {
-	policydb_t policydb = {};
+	policydb_t policydb = {}, out = {};
 	sidtab_t sidtab = {};
 	struct policy_file pf;
 	FILE *devnull = NULL;
 
-	sepol_debug(0);
+	sepol_debug(VERBOSE);
 
 	policy_file_init(&pf);
 	pf.type = PF_USE_MEMORY;
@@ -34,7 +42,7 @@  int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 	if (policydb_init(&policydb))
 		goto exit;
 
-	if (policydb_read(&policydb, &pf, /*verbose=*/0))
+	if (policydb_read(&policydb, &pf, VERBOSE))
 		goto exit;
 
 	if (policydb_load_isids(&policydb, &sidtab))
@@ -47,7 +55,10 @@  int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 			abort();
 	}
 
-	(void) check_assertions(NULL, &policydb, policydb.global->branch_list->avrules);
+	if (policydb.global->branch_list)
+		(void) check_assertions(NULL, &policydb, policydb.global->branch_list->avrules);
+
+	(void) hierarchy_check_constraints(NULL, &policydb);
 
 	devnull = fopen("/dev/null", "we");
 	if (!devnull)
@@ -56,16 +67,42 @@  int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
 	if (write_binary_policy(&policydb, devnull))
 		abort();
 
-	if (sepol_kernel_policydb_to_conf(devnull, &policydb))
-		abort();
+	if (policydb.policy_type == POLICY_KERN) {
+		if (sepol_kernel_policydb_to_conf(devnull, &policydb))
+			abort();
 
-	if (sepol_kernel_policydb_to_cil(devnull, &policydb))
-		abort();
+		if (sepol_kernel_policydb_to_cil(devnull, &policydb))
+			abort();
+
+	} else if (policydb.policy_type == POLICY_BASE) {
+		if (link_modules(NULL, &policydb, NULL, 0, VERBOSE))
+			goto exit;
+
+		if (policydb_init(&out))
+			goto exit;
+
+		if (expand_module(NULL, &policydb, &out, VERBOSE, /*check_assertions=*/0))
+			goto exit;
+
+		(void) check_assertions(NULL, &out, out.global->branch_list->avrules);
+		(void) hierarchy_check_constraints(NULL, &out);
+
+		if (write_binary_policy(&out, devnull))
+			abort();
+
+		if (sepol_kernel_policydb_to_conf(devnull, &out))
+			abort();
+
+		if (sepol_kernel_policydb_to_cil(devnull, &out))
+			abort();
+
+	}
 
 exit:
 	if (devnull != NULL)
 		fclose(devnull);
 
+	policydb_destroy(&out);
 	policydb_destroy(&policydb);
 	sepol_sidtab_destroy(&sidtab);