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 #include #include +#include +#include +#include #include 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);