Coverage Report

Created: 2026-08-31 06:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
#ifndef VERBOSE
16
24.7k
#define VERBOSE 0
17
#endif
18
19
static int write_binary_policy(policydb_t *p, FILE *outfp)
20
1.05k
{
21
1.05k
  struct policy_file pf;
22
23
1.05k
  policy_file_init(&pf);
24
1.05k
  pf.type = PF_USE_STDIO;
25
1.05k
  pf.fp = outfp;
26
1.05k
  return policydb_write(p, &pf);
27
1.05k
}
28
29
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
30
12.2k
{
31
12.2k
  policydb_t policydb = {}, out = {};
32
12.2k
  sidtab_t sidtab = {};
33
12.2k
  struct policy_file pf;
34
12.2k
  FILE *devnull = NULL;
35
36
12.2k
  sepol_debug(VERBOSE);
37
38
12.2k
  policy_file_init(&pf);
39
12.2k
  pf.type = PF_USE_MEMORY;
40
12.2k
  pf.data = (char *)data;
41
12.2k
  pf.len = size;
42
43
12.2k
  if (policydb_init(&policydb))
44
0
    goto exit;
45
46
12.2k
  if (policydb_read(&policydb, &pf, VERBOSE))
47
11.1k
    goto exit;
48
49
1.05k
  if (policydb_load_isids(&policydb, &sidtab))
50
4
    goto exit;
51
52
1.05k
  if (policydb.policy_type == POLICY_KERN) {
53
881
    (void)policydb_optimize(&policydb);
54
55
881
    if (policydb_validate(NULL, &policydb) == -1)
56
0
      abort();
57
881
  }
58
59
1.05k
  if (policydb.global->branch_list)
60
1.03k
    (void)check_assertions(NULL, &policydb,
61
1.03k
               policydb.global->branch_list->avrules);
62
63
1.05k
  (void)hierarchy_check_constraints(NULL, &policydb);
64
65
1.05k
  devnull = fopen("/dev/null", "we");
66
1.05k
  if (!devnull)
67
0
    goto exit;
68
69
1.05k
  if (write_binary_policy(&policydb, devnull))
70
0
    abort();
71
72
1.05k
  if (policydb.policy_type == POLICY_KERN) {
73
881
    if (sepol_kernel_policydb_to_conf(devnull, &policydb))
74
0
      abort();
75
76
881
    if (sepol_kernel_policydb_to_cil(devnull, &policydb))
77
0
      abort();
78
881
  } else {
79
170
    if (sepol_module_policydb_to_cil(devnull, &policydb, 0))
80
0
      abort();
81
82
170
    if (policydb.policy_type == POLICY_BASE) {
83
163
      if (link_modules(NULL, &policydb, NULL, 0, VERBOSE))
84
42
        goto exit;
85
86
121
      if (policydb_init(&out))
87
0
        goto exit;
88
89
121
      if (expand_module(NULL, &policydb, &out, VERBOSE,
90
121
            /*check_assertions=*/0))
91
121
        goto exit;
92
93
0
      if (policydb_validate(NULL, &out))
94
0
        goto exit;
95
96
0
      (void)check_assertions(
97
0
        NULL, &out, out.global->branch_list->avrules);
98
0
      (void)hierarchy_check_constraints(NULL, &out);
99
100
0
      if (write_binary_policy(&out, devnull))
101
0
        abort();
102
103
0
      if (sepol_kernel_policydb_to_conf(devnull, &out))
104
0
        abort();
105
106
0
      if (sepol_kernel_policydb_to_cil(devnull, &out))
107
0
        abort();
108
0
    }
109
170
  }
110
111
12.2k
exit:
112
12.2k
  if (devnull != NULL)
113
1.05k
    fclose(devnull);
114
115
12.2k
  policydb_destroy(&out);
116
12.2k
  policydb_destroy(&policydb);
117
12.2k
  sepol_sidtab_destroy(&sidtab);
118
119
  /* Non-zero return values are reserved for future use. */
120
12.2k
  return 0;
121
1.05k
}
122
123
#ifdef DEFINEMAIN
124
#include <sys/stat.h>
125
#include <sys/mman.h>
126
127
int main(int argc, char **argv)
128
{
129
  if (argc < 2) {
130
    fprintf(stderr, "usage: %s fuzzer-input-file\n", argv[0]);
131
    exit(1);
132
  }
133
134
  FILE *fp = fopen(argv[1], "rb");
135
  if (!fp) {
136
    perror(argv[1]);
137
    exit(1);
138
  }
139
140
  struct stat sb;
141
  int rc;
142
143
  rc = fstat(fileno(fp), &sb);
144
  if (rc < 0) {
145
    perror("fstat");
146
    exit(1);
147
  }
148
149
  void *address = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE,
150
           MAP_PRIVATE, fileno(fp), 0);
151
  if (address == MAP_FAILED) {
152
    perror("mmap");
153
    exit(1);
154
  }
155
156
  return LLVMFuzzerTestOneInput(address, sb.st_size);
157
}
158
#endif