/src/selinux/libsepol/fuzz/binpolicy-fuzzer.c
Line | Count | Source (jump to first uncovered line) |
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 | 25.4k | #define VERBOSE 0 |
16 | | |
17 | | |
18 | | static int write_binary_policy(policydb_t *p, FILE *outfp) |
19 | 1.41k | { |
20 | 1.41k | struct policy_file pf; |
21 | | |
22 | 1.41k | policy_file_init(&pf); |
23 | 1.41k | pf.type = PF_USE_STDIO; |
24 | 1.41k | pf.fp = outfp; |
25 | 1.41k | return policydb_write(p, &pf); |
26 | 1.41k | } |
27 | | |
28 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
29 | 12.5k | { |
30 | 12.5k | policydb_t policydb = {}, out = {}; |
31 | 12.5k | sidtab_t sidtab = {}; |
32 | 12.5k | struct policy_file pf; |
33 | 12.5k | FILE *devnull = NULL; |
34 | | |
35 | 12.5k | sepol_debug(VERBOSE); |
36 | | |
37 | 12.5k | policy_file_init(&pf); |
38 | 12.5k | pf.type = PF_USE_MEMORY; |
39 | 12.5k | pf.data = (char *) data; |
40 | 12.5k | pf.len = size; |
41 | | |
42 | 12.5k | if (policydb_init(&policydb)) |
43 | 0 | goto exit; |
44 | | |
45 | 12.5k | if (policydb_read(&policydb, &pf, VERBOSE)) |
46 | 11.3k | goto exit; |
47 | | |
48 | 1.25k | if (policydb_load_isids(&policydb, &sidtab)) |
49 | 6 | goto exit; |
50 | | |
51 | 1.25k | if (policydb.policy_type == POLICY_KERN) { |
52 | 946 | (void) policydb_optimize(&policydb); |
53 | | |
54 | 946 | if (policydb_validate(NULL, &policydb) == -1) |
55 | 0 | abort(); |
56 | 946 | } |
57 | | |
58 | 1.25k | if (policydb.global->branch_list) |
59 | 1.22k | (void) check_assertions(NULL, &policydb, policydb.global->branch_list->avrules); |
60 | | |
61 | 1.25k | (void) hierarchy_check_constraints(NULL, &policydb); |
62 | | |
63 | 1.25k | devnull = fopen("/dev/null", "we"); |
64 | 1.25k | if (!devnull) |
65 | 0 | goto exit; |
66 | | |
67 | 1.25k | if (write_binary_policy(&policydb, devnull)) |
68 | 0 | abort(); |
69 | | |
70 | 1.25k | if (policydb.policy_type == POLICY_KERN) { |
71 | 946 | if (sepol_kernel_policydb_to_conf(devnull, &policydb)) |
72 | 0 | abort(); |
73 | | |
74 | 946 | if (sepol_kernel_policydb_to_cil(devnull, &policydb)) |
75 | 0 | abort(); |
76 | | |
77 | 946 | } else if (policydb.policy_type == POLICY_BASE) { |
78 | 192 | if (link_modules(NULL, &policydb, NULL, 0, VERBOSE)) |
79 | 29 | goto exit; |
80 | | |
81 | 163 | if (policydb_init(&out)) |
82 | 0 | goto exit; |
83 | | |
84 | 163 | if (expand_module(NULL, &policydb, &out, VERBOSE, /*check_assertions=*/0)) |
85 | 2 | goto exit; |
86 | | |
87 | 161 | (void) check_assertions(NULL, &out, out.global->branch_list->avrules); |
88 | 161 | (void) hierarchy_check_constraints(NULL, &out); |
89 | | |
90 | 161 | if (write_binary_policy(&out, devnull)) |
91 | 0 | abort(); |
92 | | |
93 | 161 | if (sepol_kernel_policydb_to_conf(devnull, &out)) |
94 | 0 | abort(); |
95 | | |
96 | 161 | if (sepol_kernel_policydb_to_cil(devnull, &out)) |
97 | 0 | abort(); |
98 | | |
99 | 161 | } |
100 | | |
101 | 12.5k | exit: |
102 | 12.5k | if (devnull != NULL) |
103 | 1.25k | fclose(devnull); |
104 | | |
105 | 12.5k | policydb_destroy(&out); |
106 | 12.5k | policydb_destroy(&policydb); |
107 | 12.5k | sepol_sidtab_destroy(&sidtab); |
108 | | |
109 | | /* Non-zero return values are reserved for future use. */ |
110 | 12.5k | return 0; |
111 | 1.25k | } |