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