/src/selinux/libsepol/fuzz/module-package-fuzzer.c
Line | Count | Source |
1 | | #include <sepol/debug.h> |
2 | | #include <sepol/module.h> |
3 | | #include <sepol/module_to_cil.h> |
4 | | |
5 | | extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); |
6 | | |
7 | | // set to 1 to enable more verbose libsepol logging |
8 | | #ifndef VERBOSE |
9 | 19.2k | #define VERBOSE 0 |
10 | | #endif |
11 | | |
12 | | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) |
13 | 9.61k | { |
14 | 9.61k | sepol_module_package_t *mod = NULL; |
15 | 9.61k | struct sepol_policy_file *spf = NULL; |
16 | 9.61k | FILE *devnull = NULL; |
17 | | |
18 | 9.61k | sepol_debug(VERBOSE); |
19 | | |
20 | 9.61k | if (sepol_policy_file_create(&spf)) |
21 | 0 | goto exit; |
22 | | |
23 | 9.61k | sepol_policy_file_set_mem(spf, (char *)data, size); |
24 | | |
25 | 9.61k | if (sepol_module_package_create(&mod)) |
26 | 0 | goto exit; |
27 | | |
28 | 9.61k | if (sepol_module_package_read(mod, spf, VERBOSE)) |
29 | 8.61k | goto exit; |
30 | | |
31 | 997 | devnull = fopen("/dev/null", "we"); |
32 | 997 | if (!devnull) |
33 | 0 | goto exit; |
34 | | |
35 | | /* sepol_module_package_read() stores contexts sections as raw blobs |
36 | | * without validating their text syntax; sepol_module_package_to_cil() |
37 | | * is the first place that parses them, so a graceful error return here |
38 | | * is expected behaviour for malformed input, not a bug. */ |
39 | 997 | (void)sepol_module_package_to_cil(devnull, mod); |
40 | | |
41 | 9.61k | exit: |
42 | 9.61k | if (devnull) |
43 | 997 | fclose(devnull); |
44 | 9.61k | sepol_module_package_free(mod); |
45 | 9.61k | sepol_policy_file_free(spf); |
46 | | |
47 | | /* Non-zero return values are reserved for future use. */ |
48 | 9.61k | return 0; |
49 | 997 | } |
50 | | |
51 | | #ifdef DEFINEMAIN |
52 | | #include <sys/mman.h> |
53 | | #include <sys/stat.h> |
54 | | |
55 | | int main(int argc, char **argv) |
56 | | { |
57 | | if (argc < 2) { |
58 | | fprintf(stderr, "usage: %s fuzzer-input-file\n", argv[0]); |
59 | | exit(1); |
60 | | } |
61 | | |
62 | | FILE *fp = fopen(argv[1], "rb"); |
63 | | if (!fp) { |
64 | | perror(argv[1]); |
65 | | exit(1); |
66 | | } |
67 | | |
68 | | struct stat sb; |
69 | | int rc; |
70 | | |
71 | | rc = fstat(fileno(fp), &sb); |
72 | | if (rc < 0) { |
73 | | perror("fstat"); |
74 | | exit(1); |
75 | | } |
76 | | |
77 | | void *address = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, |
78 | | MAP_PRIVATE, fileno(fp), 0); |
79 | | if (address == MAP_FAILED) { |
80 | | perror("mmap"); |
81 | | exit(1); |
82 | | } |
83 | | |
84 | | return LLVMFuzzerTestOneInput(address, sb.st_size); |
85 | | } |
86 | | #endif |