Coverage Report

Created: 2026-02-26 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/selinux/libsepol/src/assertion.c
Line
Count
Source
1
/* Authors: Joshua Brindle <jbrindle@tresys.com>
2
 *
3
 * Assertion checker for avtab entries, taken from
4
 * checkpolicy.c by Stephen Smalley <stephen.smalley.work@gmail.com>
5
 *
6
 * Copyright (C) 2005 Tresys Technology, LLC
7
 *
8
 *  This library is free software; you can redistribute it and/or
9
 *  modify it under the terms of the GNU Lesser General Public
10
 *  License as published by the Free Software Foundation; either
11
 *  version 2.1 of the License, or (at your option) any later version.
12
 *
13
 *  This library is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
 *  Lesser General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU Lesser General Public
19
 *  License along with this library; if not, write to the Free Software
20
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21
 */
22
23
#include <stdbool.h>
24
#include <sepol/policydb/avtab.h>
25
#include <sepol/policydb/policydb.h>
26
#include <sepol/policydb/expand.h>
27
#include <sepol/policydb/util.h>
28
29
#include "private.h"
30
#include "debug.h"
31
32
struct avtab_match_args {
33
  sepol_handle_t *handle;
34
  policydb_t *p;
35
  const avrule_t *narule;
36
  unsigned long errors;
37
  bool conditional;
38
};
39
40
0
static const char* policy_name(const policydb_t *p) {
41
0
  return p->name ?: "policy.conf";
42
0
}
43
44
static void report_failure(sepol_handle_t *handle, const policydb_t *p, const avrule_t *narule,
45
         unsigned int stype, unsigned int ttype,
46
         const class_perm_node_t *curperm, uint32_t perms)
47
0
{
48
0
  char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
49
50
0
  if (narule->source_filename) {
51
0
    ERR(handle, "neverallow on line %lu of %s (or line %lu of %s) violated by allow %s %s:%s {%s };",
52
0
        narule->source_line, narule->source_filename, narule->line, policy_name(p),
53
0
        p->p_type_val_to_name[stype],
54
0
        p->p_type_val_to_name[ttype],
55
0
        p->p_class_val_to_name[curperm->tclass - 1],
56
0
        permstr ?: "<format-failure>");
57
0
  } else if (narule->line) {
58
0
    ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };",
59
0
        narule->line, p->p_type_val_to_name[stype],
60
0
        p->p_type_val_to_name[ttype],
61
0
        p->p_class_val_to_name[curperm->tclass - 1],
62
0
        permstr ?: "<format-failure>");
63
0
  } else {
64
0
    ERR(handle, "neverallow violated by allow %s %s:%s {%s };",
65
0
        p->p_type_val_to_name[stype],
66
0
        p->p_type_val_to_name[ttype],
67
0
        p->p_class_val_to_name[curperm->tclass - 1],
68
0
        permstr ?: "<format-failure>");
69
0
  }
70
71
0
  free(permstr);
72
0
}
73
74
static bool match_any_class_permissions(const class_perm_node_t *cp, uint32_t class, uint32_t data)
75
27.6M
{
76
49.1M
  for (; cp; cp = cp->next) {
77
27.7M
    if ((cp->tclass == class) && (cp->data & data))
78
6.28M
      return true;
79
27.7M
  }
80
81
21.3M
  return false;
82
27.6M
}
83
84
0
static bool extended_permissions_and(const uint32_t *perms1, const uint32_t *perms2) {
85
0
  size_t i;
86
0
  for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
87
0
    if (perms1[i] & perms2[i])
88
0
      return true;
89
0
  }
90
91
0
  return false;
92
0
}
93
94
static bool check_extended_permissions(const av_extended_perms_t *neverallow, const avtab_extended_perms_t *allow)
95
0
{
96
0
  bool rc = false;
97
0
  if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
98
0
      && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
99
0
    if (neverallow->driver == allow->driver)
100
0
      rc = extended_permissions_and(neverallow->perms, allow->perms);
101
0
  } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
102
0
      && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
103
0
    rc = xperm_test(neverallow->driver, allow->perms);
104
0
  } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
105
0
      && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
106
0
    rc = xperm_test(allow->driver, neverallow->perms);
107
0
  } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
108
0
      && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
109
0
    rc = extended_permissions_and(neverallow->perms, allow->perms);
110
0
  } else if ((neverallow->specified == AVRULE_XPERMS_NLMSG)
111
0
      && (allow->specified == AVTAB_XPERMS_NLMSG)) {
112
0
    if (neverallow->driver == allow->driver)
113
0
      rc = extended_permissions_and(neverallow->perms, allow->perms);
114
0
  }
115
116
0
  return rc;
117
0
}
118
119
/* Compute which allowed extended permissions violate the neverallow rule */
120
static void extended_permissions_violated(avtab_extended_perms_t *result,
121
          const av_extended_perms_t *neverallow,
122
          const avtab_extended_perms_t *allow)
123
0
{
124
0
  size_t i;
125
0
  if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
126
0
      && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
127
0
    result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
128
0
    result->driver = allow->driver;
129
0
    for (i = 0; i < EXTENDED_PERMS_LEN; i++)
130
0
      result->perms[i] = neverallow->perms[i] & allow->perms[i];
131
0
  } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION)
132
0
      && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
133
0
    result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
134
0
    result->driver = neverallow->driver;
135
0
    memcpy(result->perms, neverallow->perms, sizeof(result->perms));
136
0
  } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
137
0
      && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) {
138
0
    result->specified = AVTAB_XPERMS_IOCTLFUNCTION;
139
0
    result->driver = allow->driver;
140
0
    memcpy(result->perms, allow->perms, sizeof(result->perms));
141
0
  } else if ((neverallow->specified == AVRULE_XPERMS_IOCTLDRIVER)
142
0
      && (allow->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
143
0
    result->specified = AVTAB_XPERMS_IOCTLDRIVER;
144
0
    for (i = 0; i < EXTENDED_PERMS_LEN; i++)
145
0
      result->perms[i] = neverallow->perms[i] & allow->perms[i];
146
0
  } else if ((neverallow->specified == AVRULE_XPERMS_NLMSG)
147
0
      && (allow->specified == AVTAB_XPERMS_NLMSG)) {
148
0
    result->specified = AVTAB_XPERMS_NLMSG;
149
0
    result->driver = allow->driver;
150
0
    for (i = 0; i < EXTENDED_PERMS_LEN; i++)
151
0
      result->perms[i] = neverallow->perms[i] & allow->perms[i];
152
0
  }
153
0
}
154
155
static bool match_node_key(const struct avtab_node *node, const avtab_key_t *key)
156
0
{
157
0
  return node->key.source_type == key->source_type
158
0
    && node->key.target_type == key->target_type
159
0
    && node->key.target_class == key->target_class;
160
0
}
161
162
/* Same scenarios of interest as check_assertion_extended_permissions */
163
static int report_assertion_extended_permissions(sepol_handle_t *handle,
164
        policydb_t *p, const avrule_t *narule,
165
        unsigned int stype, unsigned int ttype,
166
        const class_perm_node_t *curperm, uint32_t perms,
167
        const avtab_key_t *k, bool conditional)
168
0
{
169
0
  avtab_ptr_t node;
170
0
  avtab_key_t tmp_key;
171
0
  avtab_extended_perms_t *xperms;
172
0
  avtab_extended_perms_t error;
173
0
  const ebitmap_t *sattr = &p->type_attr_map[stype];
174
0
  const ebitmap_t *tattr = &p->type_attr_map[ttype];
175
0
  ebitmap_node_t *snode, *tnode;
176
0
  unsigned int i, j;
177
0
  bool found_xperm = false, found_cond_conflict = false;
178
0
  int errors = 0;
179
180
0
  memcpy(&tmp_key, k, sizeof(avtab_key_t));
181
0
  tmp_key.specified = AVTAB_XPERMS_ALLOWED;
182
183
0
  ebitmap_for_each_positive_bit(sattr, snode, i) {
184
0
    tmp_key.source_type = i + 1;
185
0
    ebitmap_for_each_positive_bit(tattr, tnode, j) {
186
0
      tmp_key.target_type = j + 1;
187
0
      for (node = avtab_search_node(&p->te_avtab, &tmp_key);
188
0
           node;
189
0
           node = avtab_search_node_next(node, tmp_key.specified)) {
190
0
        xperms = node->datum.xperms;
191
0
        if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
192
0
            && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
193
0
            && (xperms->specified != AVTAB_XPERMS_NLMSG))
194
0
          continue;
195
0
        found_xperm = true;
196
        /* failure on the extended permission check_extended_permissions */
197
0
        if (check_extended_permissions(narule->xperms, xperms)) {
198
0
          char *permstring;
199
200
0
          extended_permissions_violated(&error, narule->xperms, xperms);
201
0
          permstring = sepol_extended_perms_to_string(&error);
202
203
0
          ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
204
0
              "  allowxperm %s %s:%s %s;",
205
0
              narule->source_line, narule->source_filename, narule->line, policy_name(p),
206
0
              p->p_type_val_to_name[i],
207
0
              p->p_type_val_to_name[j],
208
0
              p->p_class_val_to_name[curperm->tclass - 1],
209
0
              permstring ?: "<format-failure>");
210
211
0
          free(permstring);
212
0
          errors++;
213
0
        }
214
0
      }
215
216
0
      for (const cond_list_t *cl = p->cond_list; cl; cl = cl->next) {
217
0
        bool found_true_base = false, found_true_xperm = false;
218
0
        bool found_false_base = false, found_false_xperm = false;
219
220
0
        for (const cond_av_list_t *cal = cl->true_list; cal; cal = cal->next) {
221
0
          node = cal->node; /* node->next is not from the same condition */
222
0
          if (!node)
223
0
            continue;
224
225
0
          if (!match_node_key(node, &tmp_key))
226
0
            continue;
227
228
0
          if (match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) {
229
0
            found_true_base = true;
230
0
            continue;
231
0
          }
232
233
0
          if (!(node->key.specified & AVTAB_XPERMS_ALLOWED))
234
0
            continue;
235
236
0
          xperms = node->datum.xperms;
237
0
          if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
238
0
              && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
239
0
              && (xperms->specified != AVTAB_XPERMS_NLMSG))
240
0
            continue;
241
0
          found_true_xperm = true;
242
          /* failure on the extended permission check_extended_permissions */
243
0
          if (check_extended_permissions(narule->xperms, xperms)) {
244
0
            char *permstring;
245
246
0
            extended_permissions_violated(&error, narule->xperms, xperms);
247
0
            permstring = sepol_extended_perms_to_string(&error);
248
249
0
            ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
250
0
                "  allowxperm %s %s:%s %s;",
251
0
                narule->source_line, narule->source_filename, narule->line, policy_name(p),
252
0
                p->p_type_val_to_name[i],
253
0
                p->p_type_val_to_name[j],
254
0
                p->p_class_val_to_name[curperm->tclass - 1],
255
0
                permstring ?: "<format-failure>");
256
257
0
            free(permstring);
258
0
            errors++;
259
0
          }
260
0
        }
261
262
0
        for (const cond_av_list_t *cal = cl->false_list; cal; cal = cal->next) {
263
0
          node = cal->node; /* node->next is not from the same condition */
264
0
          if (!node)
265
0
            continue;
266
267
0
          if (!match_node_key(node, &tmp_key))
268
0
            continue;
269
270
0
          if (match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) {
271
0
            found_false_base = true;
272
0
            continue;
273
0
          }
274
275
0
          if (!(node->key.specified & AVTAB_XPERMS_ALLOWED))
276
0
            continue;
277
278
0
          xperms = node->datum.xperms;
279
0
          if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
280
0
              && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
281
0
              && (xperms->specified != AVTAB_XPERMS_NLMSG))
282
0
            continue;
283
0
          found_false_xperm = true;
284
          /* failure on the extended permission check_extended_permissions */
285
0
          if (check_extended_permissions(narule->xperms, xperms)) {
286
0
            char *permstring;
287
288
0
            extended_permissions_violated(&error, narule->xperms, xperms);
289
0
            permstring = sepol_extended_perms_to_string(&error);
290
291
0
            ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
292
0
                "  allowxperm %s %s:%s %s;",
293
0
                narule->source_line, narule->source_filename, narule->line, policy_name(p),
294
0
                p->p_type_val_to_name[i],
295
0
                p->p_type_val_to_name[j],
296
0
                p->p_class_val_to_name[curperm->tclass - 1],
297
0
                permstring ?: "<format-failure>");
298
299
0
            free(permstring);
300
0
            errors++;
301
0
          }
302
0
        }
303
304
0
        if (found_true_xperm && found_false_xperm)
305
0
          found_xperm = true;
306
0
        else if (conditional && ((found_true_base && !found_true_xperm) || (found_false_base && !found_false_xperm)))
307
0
          found_cond_conflict = true;
308
0
      }
309
0
    }
310
0
  }
311
312
0
  if ((!found_xperm && !conditional) || found_cond_conflict) {
313
    /* failure on the regular permissions */
314
0
    char *permstr = sepol_av_to_string(p, curperm->tclass, perms);
315
316
0
    ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n"
317
0
        "  allow %s %s:%s {%s };",
318
0
        narule->source_line, narule->source_filename, narule->line, policy_name(p),
319
0
        p->p_type_val_to_name[stype],
320
0
        p->p_type_val_to_name[ttype],
321
0
        p->p_class_val_to_name[curperm->tclass - 1],
322
0
        permstr ?: "<format-failure>");
323
324
0
    free(permstr);
325
0
    errors++;
326
0
  }
327
328
0
  return errors;
329
0
}
330
331
static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void *args)
332
0
{
333
0
  int rc = 0;
334
0
  struct avtab_match_args *a = (struct avtab_match_args *)args;
335
0
  sepol_handle_t *handle = a->handle;
336
0
  policydb_t *p = a->p;
337
0
  const avrule_t *narule = a->narule;
338
0
  const class_perm_node_t *cp;
339
0
  uint32_t perms;
340
0
  ebitmap_t src_matches, tgt_matches, self_matches;
341
0
  ebitmap_node_t *snode, *tnode;
342
0
  unsigned int i, j;
343
0
  const bool is_narule_self = (narule->flags & RULE_SELF) != 0;
344
0
  const bool is_narule_notself = (narule->flags & RULE_NOTSELF) != 0;
345
346
0
  if ((k->specified & AVTAB_ALLOWED) == 0)
347
0
    return 0;
348
349
0
  if (!match_any_class_permissions(narule->perms, k->target_class, d->data))
350
0
    return 0;
351
352
0
  ebitmap_init(&src_matches);
353
0
  ebitmap_init(&tgt_matches);
354
0
  ebitmap_init(&self_matches);
355
356
0
  rc = ebitmap_and(&src_matches, &narule->stypes.types,
357
0
       &p->attr_type_map[k->source_type - 1]);
358
0
  if (rc < 0)
359
0
    goto oom;
360
361
0
  if (ebitmap_is_empty(&src_matches))
362
0
    goto exit;
363
364
0
  if (is_narule_notself) {
365
0
    if (ebitmap_is_empty(&narule->ttypes.types)) {
366
      /* avrule tgt is of the form ~self */
367
0
      rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
368
0
    } else {
369
      /* avrule tgt is of the form {ATTR -self} */
370
0
      rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
371
0
    }
372
0
    if (rc)
373
0
      goto oom;
374
0
  } else {
375
0
    rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type -1]);
376
0
    if (rc < 0)
377
0
      goto oom;
378
379
0
    if (is_narule_self) {
380
0
      rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
381
0
      if (rc < 0)
382
0
        goto oom;
383
384
0
      if (!ebitmap_is_empty(&self_matches)) {
385
0
        rc = ebitmap_union(&tgt_matches, &self_matches);
386
0
        if (rc < 0)
387
0
          goto oom;
388
0
      }
389
0
    }
390
0
  }
391
392
0
  if (ebitmap_is_empty(&tgt_matches))
393
0
    goto exit;
394
395
0
  for (cp = narule->perms; cp; cp = cp->next) {
396
397
0
    perms = cp->data & d->data;
398
0
    if ((cp->tclass != k->target_class) || !perms) {
399
0
      continue;
400
0
    }
401
402
0
    ebitmap_for_each_positive_bit(&src_matches, snode, i) {
403
0
      ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
404
0
        if (is_narule_self && i != j)
405
0
          continue;
406
0
        if (is_narule_notself && i == j)
407
0
          continue;
408
0
        if (narule->specified == AVRULE_XPERMS_NEVERALLOW) {
409
0
          a->errors += report_assertion_extended_permissions(handle,p, narule,
410
0
                      i, j, cp, perms, k,
411
0
                      a->conditional);
412
0
        } else {
413
0
          a->errors++;
414
0
          report_failure(handle, p, narule, i, j, cp, perms);
415
0
        }
416
0
      }
417
0
    }
418
0
  }
419
420
0
oom:
421
0
exit:
422
0
  ebitmap_destroy(&src_matches);
423
0
  ebitmap_destroy(&tgt_matches);
424
0
  ebitmap_destroy(&self_matches);
425
0
  return rc;
426
0
}
427
428
static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, const avrule_t *narule)
429
0
{
430
0
  int rc;
431
0
  struct avtab_match_args args = {
432
0
    .handle = handle,
433
0
    .p = p,
434
0
    .narule = narule,
435
0
    .errors = 0,
436
0
  };
437
438
0
  args.conditional = false;
439
0
  rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args);
440
0
  if (rc < 0)
441
0
    goto oom;
442
443
0
  args.conditional = true;
444
0
  rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args);
445
0
  if (rc < 0)
446
0
    goto oom;
447
448
0
  return args.errors;
449
450
0
oom:
451
0
  return rc;
452
0
}
453
454
/*
455
 * Look up the extended permissions in avtab and verify that neverallowed
456
 * permissions are not granted.
457
 */
458
static bool check_assertion_extended_permissions_avtab(const avrule_t *narule,
459
            unsigned int stype, unsigned int ttype,
460
            const avtab_key_t *k, policydb_t *p,
461
            bool conditional)
462
0
{
463
0
  avtab_ptr_t node;
464
0
  avtab_key_t tmp_key;
465
0
  const avtab_extended_perms_t *xperms;
466
0
  const av_extended_perms_t *neverallow_xperms = narule->xperms;
467
0
  const ebitmap_t *sattr = &p->type_attr_map[stype];
468
0
  const ebitmap_t *tattr = &p->type_attr_map[ttype];
469
0
  ebitmap_node_t *snode, *tnode;
470
0
  unsigned int i, j;
471
0
  bool found_xperm = false, found_cond_conflict = false;
472
473
0
  memcpy(&tmp_key, k, sizeof(avtab_key_t));
474
0
  tmp_key.specified = AVTAB_XPERMS_ALLOWED;
475
476
0
  ebitmap_for_each_positive_bit(sattr, snode, i) {
477
0
    tmp_key.source_type = i + 1;
478
0
    ebitmap_for_each_positive_bit(tattr, tnode, j) {
479
0
      tmp_key.target_type = j + 1;
480
0
      for (node = avtab_search_node(&p->te_avtab, &tmp_key);
481
0
           node;
482
0
           node = avtab_search_node_next(node, tmp_key.specified)) {
483
0
        xperms = node->datum.xperms;
484
485
0
        if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
486
0
            && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
487
0
            && (xperms->specified != AVTAB_XPERMS_NLMSG))
488
0
          continue;
489
0
        found_xperm = true;
490
0
        if (check_extended_permissions(neverallow_xperms, xperms))
491
0
          return true;
492
0
      }
493
494
0
      for (const cond_list_t *cl = p->cond_list; cl; cl = cl->next) {
495
0
        bool found_true_base = false, found_true_xperm = false;
496
0
        bool found_false_base = false, found_false_xperm = false;
497
498
0
        for (const cond_av_list_t *cal = cl->true_list; cal; cal = cal->next) {
499
0
          node = cal->node; /* node->next is not from the same condition */
500
0
          if (!node)
501
0
            continue;
502
503
0
          if (!match_node_key(node, &tmp_key))
504
0
            continue;
505
506
0
          if ((node->key.specified & AVTAB_ALLOWED) && match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) {
507
0
            found_true_base = true;
508
0
            continue;
509
0
          }
510
511
0
          if (!(node->key.specified & AVTAB_XPERMS_ALLOWED))
512
0
            continue;
513
514
0
          xperms = node->datum.xperms;
515
516
0
          if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
517
0
              && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
518
0
              && (xperms->specified != AVTAB_XPERMS_NLMSG))
519
0
            continue;
520
0
          found_true_xperm = true;
521
0
          if (check_extended_permissions(neverallow_xperms, xperms))
522
0
            return true;
523
0
        }
524
525
0
        for (const cond_av_list_t *cal = cl->false_list; cal; cal = cal->next) {
526
0
          node = cal->node; /* node->next is not from the same condition */
527
0
          if (!node)
528
0
            continue;
529
530
0
          if (!match_node_key(node, &tmp_key))
531
0
            continue;
532
533
0
          if ((node->key.specified & AVTAB_ALLOWED) && match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) {
534
0
            found_false_base = true;
535
0
            continue;
536
0
          }
537
538
0
          if (!(node->key.specified & AVTAB_XPERMS_ALLOWED))
539
0
            continue;
540
541
0
          xperms = node->datum.xperms;
542
543
0
          if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
544
0
              && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
545
0
              && (xperms->specified != AVTAB_XPERMS_NLMSG))
546
0
            continue;
547
0
          found_false_xperm = true;
548
0
          if (check_extended_permissions(neverallow_xperms, xperms))
549
0
            return true;
550
0
        }
551
552
0
        if (found_true_xperm && found_false_xperm)
553
0
          found_xperm = true;
554
0
        else if (conditional && ((found_true_base && !found_true_xperm) || (found_false_base && !found_false_xperm)))
555
0
          found_cond_conflict = true;
556
0
      }
557
0
    }
558
0
  }
559
560
0
  return (!conditional && !found_xperm) || found_cond_conflict;
561
0
}
562
563
/*
564
 * When the ioctl permission is granted on an avtab entry that matches an
565
 * avrule neverallowxperm entry, enumerate over the matching
566
 * source/target/class sets to determine if the extended permissions exist
567
 * and if the neverallowed ioctls are granted.
568
 *
569
 * Four scenarios of interest:
570
 * 1. PASS - the ioctl permission is not granted for this source/target/class
571
 *    This case is handled in check_assertion_avtab_match
572
 * 2. PASS - The ioctl permission is granted AND the extended permission
573
 *    is NOT granted
574
 * 3. FAIL - The ioctl permission is granted AND no extended permissions
575
 *    exist
576
 * 4. FAIL - The ioctl permission is granted AND the extended permission is
577
 *    granted
578
 */
579
static int check_assertion_extended_permissions(const avrule_t *narule,
580
            const avtab_key_t *k, policydb_t *p,
581
            bool conditional)
582
0
{
583
0
  ebitmap_t src_matches, tgt_matches, self_matches;
584
0
  unsigned int i, j;
585
0
  ebitmap_node_t *snode, *tnode;
586
0
  const bool is_narule_self = (narule->flags & RULE_SELF) != 0;
587
0
  const bool is_narule_notself = (narule->flags & RULE_NOTSELF) != 0;
588
0
  int rc;
589
590
0
  ebitmap_init(&src_matches);
591
0
  ebitmap_init(&tgt_matches);
592
0
  ebitmap_init(&self_matches);
593
594
0
  rc = ebitmap_and(&src_matches, &narule->stypes.types,
595
0
       &p->attr_type_map[k->source_type - 1]);
596
0
  if (rc < 0)
597
0
    goto oom;
598
599
0
  if (ebitmap_is_empty(&src_matches)) {
600
0
    rc = 0;
601
0
    goto exit;
602
0
  }
603
604
0
  if (is_narule_notself) {
605
0
    if (ebitmap_is_empty(&narule->ttypes.types)) {
606
      /* avrule tgt is of the form ~self */
607
0
      rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]);
608
0
    } else {
609
      /* avrule tgt is of the form {ATTR -self} */
610
0
      rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
611
0
    }
612
0
    if (rc < 0)
613
0
      goto oom;
614
0
  } else {
615
0
    rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type -1]);
616
0
    if (rc < 0)
617
0
      goto oom;
618
619
0
    if (is_narule_self) {
620
0
      rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]);
621
0
      if (rc < 0)
622
0
        goto oom;
623
624
0
      if (!ebitmap_is_empty(&self_matches)) {
625
0
        rc = ebitmap_union(&tgt_matches, &self_matches);
626
0
        if (rc < 0)
627
0
          goto oom;
628
0
      }
629
0
    }
630
0
  }
631
632
0
  if (ebitmap_is_empty(&tgt_matches)) {
633
0
    rc = 0;
634
0
    goto exit;
635
0
  }
636
637
0
  ebitmap_for_each_positive_bit(&src_matches, snode, i) {
638
0
    ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) {
639
0
      if (is_narule_self && i != j)
640
0
        continue;
641
0
      if (is_narule_notself && i == j)
642
0
        continue;
643
0
      if (check_assertion_extended_permissions_avtab(narule, i, j, k, p, conditional)) {
644
0
        rc = 1;
645
0
        goto exit;
646
0
      }
647
0
    }
648
0
  }
649
650
0
  rc = 0;
651
652
0
oom:
653
0
exit:
654
0
  ebitmap_destroy(&src_matches);
655
0
  ebitmap_destroy(&tgt_matches);
656
0
  ebitmap_destroy(&self_matches);
657
0
  return rc;
658
0
}
659
660
static int check_assertion_notself_match(const avtab_key_t *k, const avrule_t *narule, policydb_t *p)
661
24.3k
{
662
24.3k
  ebitmap_t src_matches, tgt_matches;
663
24.3k
  unsigned int num_src_matches, num_tgt_matches;
664
24.3k
  int rc;
665
666
24.3k
  ebitmap_init(&src_matches);
667
24.3k
  ebitmap_init(&tgt_matches);
668
669
24.3k
  rc = ebitmap_and(&src_matches, &narule->stypes.types, &p->attr_type_map[k->source_type - 1]);
670
24.3k
  if (rc < 0)
671
0
    goto oom;
672
673
24.3k
  if (ebitmap_is_empty(&narule->ttypes.types)) {
674
    /* avrule tgt is of the form ~self */
675
4.49k
    rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type - 1]);
676
19.8k
  } else {
677
    /* avrule tgt is of the form {ATTR -self} */
678
19.8k
    rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type - 1]);
679
19.8k
  }
680
24.3k
  if (rc < 0)
681
0
    goto oom;
682
683
24.3k
  num_src_matches = ebitmap_cardinality(&src_matches);
684
24.3k
  num_tgt_matches = ebitmap_cardinality(&tgt_matches);
685
24.3k
  if (num_src_matches == 0 || num_tgt_matches == 0) {
686
17.3k
    rc = 0;
687
17.3k
    goto nomatch;
688
17.3k
  }
689
7.00k
  if (num_src_matches == 1 && num_tgt_matches == 1) {
690
4.73k
    ebitmap_t matches;
691
4.73k
    unsigned int num_matches;
692
4.73k
    rc = ebitmap_and(&matches, &src_matches, &tgt_matches);
693
4.73k
    if (rc < 0) {
694
0
      ebitmap_destroy(&matches);
695
0
      goto oom;
696
0
    }
697
4.73k
    num_matches = ebitmap_cardinality(&matches);
698
4.73k
    ebitmap_destroy(&matches);
699
4.73k
    if (num_matches == 1) {
700
      /* The only non-match is of the form TYPE TYPE */
701
1.11k
      rc = 0;
702
1.11k
      goto nomatch;
703
1.11k
    }
704
4.73k
  }
705
706
5.88k
  rc = 1;
707
708
5.88k
oom:
709
24.3k
nomatch:
710
24.3k
  ebitmap_destroy(&src_matches);
711
24.3k
  ebitmap_destroy(&tgt_matches);
712
24.3k
  return rc;
713
5.88k
}
714
715
static int check_assertion_self_match(const avtab_key_t *k, const avrule_t *narule, policydb_t *p)
716
3.66k
{
717
3.66k
  ebitmap_t src_matches;
718
3.66k
  int rc;
719
720
  /* The key's target must match something in the matches of the avrule's source
721
   * and the key's source.
722
   */
723
724
3.66k
  rc = ebitmap_and(&src_matches, &narule->stypes.types, &p->attr_type_map[k->source_type - 1]);
725
3.66k
  if (rc < 0)
726
0
    goto oom;
727
728
3.66k
  if (!ebitmap_match_any(&src_matches, &p->attr_type_map[k->target_type - 1])) {
729
2.00k
    rc = 0;
730
2.00k
    goto nomatch;
731
2.00k
  }
732
733
1.66k
  rc = 1;
734
735
1.66k
oom:
736
3.66k
nomatch:
737
3.66k
  ebitmap_destroy(&src_matches);
738
3.66k
  return rc;
739
1.66k
}
740
741
static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args)
742
28.3M
{
743
28.3M
  int rc;
744
28.3M
  struct avtab_match_args *a = (struct avtab_match_args *)args;
745
28.3M
  policydb_t *p = a->p;
746
28.3M
  const avrule_t *narule = a->narule;
747
748
28.3M
  if ((k->specified & AVTAB_ALLOWED) == 0)
749
643k
    goto nomatch;
750
751
27.6M
  if (!match_any_class_permissions(narule->perms, k->target_class, d->data))
752
21.3M
    goto nomatch;
753
754
6.28M
  if (!ebitmap_match_any(&narule->stypes.types, &p->attr_type_map[k->source_type - 1]))
755
5.97M
    goto nomatch;
756
757
313k
  if (narule->flags & RULE_NOTSELF) {
758
24.3k
    rc = check_assertion_notself_match(k, narule, p);
759
24.3k
    if (rc < 0)
760
0
      goto oom;
761
24.3k
    if (rc == 0)
762
18.4k
      goto nomatch;
763
288k
  } else {
764
    /* neverallow may have tgts even if it uses SELF */
765
288k
    if (!ebitmap_match_any(&narule->ttypes.types, &p->attr_type_map[k->target_type -1])) {
766
283k
      if (narule->flags == RULE_SELF) {
767
3.66k
        rc = check_assertion_self_match(k, narule, p);
768
3.66k
        if (rc < 0)
769
0
          goto oom;
770
3.66k
        if (rc == 0)
771
2.00k
          goto nomatch;
772
280k
      } else {
773
280k
        goto nomatch;
774
280k
      }
775
283k
    }
776
288k
  }
777
778
12.5k
  if (narule->specified == AVRULE_XPERMS_NEVERALLOW) {
779
0
    rc = check_assertion_extended_permissions(narule, k, p, a->conditional);
780
0
    if (rc < 0)
781
0
      goto oom;
782
0
    if (rc == 0)
783
0
      goto nomatch;
784
0
  }
785
12.5k
  return 1;
786
787
28.3M
nomatch:
788
28.3M
  return 0;
789
790
0
oom:
791
0
  return rc;
792
12.5k
}
793
794
int check_assertion(policydb_t *p, const avrule_t *narule)
795
33.2k
{
796
33.2k
  int rc;
797
33.2k
  struct avtab_match_args args = {
798
33.2k
    .handle = NULL,
799
33.2k
    .p = p,
800
33.2k
    .narule = narule,
801
33.2k
    .errors = 0,
802
33.2k
  };
803
804
33.2k
  args.conditional = false;
805
33.2k
  rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args);
806
807
33.2k
  if (rc == 0) {
808
20.6k
    args.conditional = true;
809
20.6k
    rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args);
810
20.6k
  }
811
812
33.2k
  return rc;
813
33.2k
}
814
815
int check_assertions(sepol_handle_t * handle, policydb_t * p,
816
         const avrule_t * narules)
817
2.26k
{
818
2.26k
  int rc;
819
2.26k
  const avrule_t *a;
820
2.26k
  unsigned long errors = 0;
821
822
2.26k
  for (a = narules; a != NULL; a = a->next) {
823
6
    if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW)))
824
5
      continue;
825
1
    rc = check_assertion(p, a);
826
1
    if (rc < 0) {
827
0
      ERR(handle, "Error occurred while checking neverallows");
828
0
      return -1;
829
0
    }
830
1
    if (rc) {
831
0
      rc = report_assertion_failures(handle, p, a);
832
0
      if (rc < 0) {
833
0
        ERR(handle, "Error occurred while checking neverallows");
834
0
        return -1;
835
0
      }
836
0
      errors += rc;
837
0
    }
838
1
  }
839
840
2.26k
  if (errors)
841
2.26k
    ERR(handle, "%lu neverallow failures occurred", errors);
842
843
2.26k
  return errors ? -1 : 0;
844
2.26k
}