xref: /aosp_15_r20/external/selinux/libsepol/fuzz/binpolicy-fuzzer.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1 #include <sepol/debug.h>
2 #include <sepol/kernel_to_cil.h>
3 #include <sepol/kernel_to_conf.h>
4 #include <sepol/policydb/expand.h>
5 #include <sepol/policydb/hierarchy.h>
6 #include <sepol/policydb/link.h>
7 #include <sepol/policydb/policydb.h>
8 
9 extern int policydb_validate(sepol_handle_t *handle, const policydb_t *p);
10 
11 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
12 
13 
14 // set to 1 to enable more verbose libsepol logging
15 #define VERBOSE 0
16 
17 
write_binary_policy(policydb_t * p,FILE * outfp)18 static int write_binary_policy(policydb_t *p, FILE *outfp)
19 {
20 	struct policy_file pf;
21 
22 	policy_file_init(&pf);
23 	pf.type = PF_USE_STDIO;
24 	pf.fp = outfp;
25 	return policydb_write(p, &pf);
26 }
27 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)28 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
29 {
30 	policydb_t policydb = {}, out = {};
31 	sidtab_t sidtab = {};
32 	struct policy_file pf;
33 	FILE *devnull = NULL;
34 
35 	sepol_debug(VERBOSE);
36 
37 	policy_file_init(&pf);
38 	pf.type = PF_USE_MEMORY;
39 	pf.data = (char *) data;
40 	pf.len = size;
41 
42 	if (policydb_init(&policydb))
43 		goto exit;
44 
45 	if (policydb_read(&policydb, &pf, VERBOSE))
46 		goto exit;
47 
48 	if (policydb_load_isids(&policydb, &sidtab))
49 		goto exit;
50 
51 	if (policydb.policy_type == POLICY_KERN) {
52 		(void) policydb_optimize(&policydb);
53 
54 		if (policydb_validate(NULL, &policydb) == -1)
55 			abort();
56 	}
57 
58 	if (policydb.global->branch_list)
59 		(void) check_assertions(NULL, &policydb, policydb.global->branch_list->avrules);
60 
61 	(void) hierarchy_check_constraints(NULL, &policydb);
62 
63 	devnull = fopen("/dev/null", "we");
64 	if (!devnull)
65 		goto exit;
66 
67 	if (write_binary_policy(&policydb, devnull))
68 		abort();
69 
70 	if (policydb.policy_type == POLICY_KERN) {
71 		if (sepol_kernel_policydb_to_conf(devnull, &policydb))
72 			abort();
73 
74 		if (sepol_kernel_policydb_to_cil(devnull, &policydb))
75 			abort();
76 
77 	} else if (policydb.policy_type == POLICY_BASE) {
78 		if (link_modules(NULL, &policydb, NULL, 0, VERBOSE))
79 			goto exit;
80 
81 		if (policydb_init(&out))
82 			goto exit;
83 
84 		if (expand_module(NULL, &policydb, &out, VERBOSE, /*check_assertions=*/0))
85 			goto exit;
86 
87 		(void) check_assertions(NULL, &out, out.global->branch_list->avrules);
88 		(void) hierarchy_check_constraints(NULL, &out);
89 
90 		if (write_binary_policy(&out, devnull))
91 			abort();
92 
93 		if (sepol_kernel_policydb_to_conf(devnull, &out))
94 			abort();
95 
96 		if (sepol_kernel_policydb_to_cil(devnull, &out))
97 			abort();
98 
99 	}
100 
101 exit:
102 	if (devnull != NULL)
103 		fclose(devnull);
104 
105 	policydb_destroy(&out);
106 	policydb_destroy(&policydb);
107 	sepol_sidtab_destroy(&sidtab);
108 
109 	/* Non-zero return values are reserved for future use. */
110 	return 0;
111 }
112