Coverage Report

Created: 2026-10-19 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/selinux/checkpolicy/policy_define.c
Line
Count
Source
1
/*
2
 * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
3
 */
4
5
/*
6
 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
7
 *
8
 *  Support for enhanced MLS infrastructure.
9
 *
10
 * Updated: David Caplan, <dac@tresys.com>
11
 *
12
 *  Added conditional policy language extensions
13
 *
14
 * Updated: Joshua Brindle <jbrindle@tresys.com>
15
 *      Karl MacMillan <kmacmillan@mentalrootkit.com>
16
 *          Jason Tang     <jtang@tresys.com>
17
 *
18
 *  Added support for binary policy modules
19
 *
20
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
21
 * Copyright (C) 2003 - 2008 Tresys Technology, LLC
22
 * Copyright (C) 2007 Red Hat Inc.
23
 * Copyright (C) 2017 Mellanox Techonologies Inc.
24
 *  This program is free software; you can redistribute it and/or modify
25
 *    it under the terms of the GNU General Public License as published by
26
 *  the Free Software Foundation, version 2.
27
 */
28
29
/* FLASK */
30
31
#include <sys/types.h>
32
#include <assert.h>
33
#include <stdarg.h>
34
#include <stdint.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <sys/socket.h>
39
#include <netinet/in.h>
40
#ifndef IPPROTO_DCCP
41
#define IPPROTO_DCCP 33
42
#endif
43
#ifndef IPPROTO_SCTP
44
#define IPPROTO_SCTP 132
45
#endif
46
#include <arpa/inet.h>
47
#include <limits.h>
48
#include <inttypes.h>
49
#include <ctype.h>
50
51
#include <sepol/policydb/expand.h>
52
#include <sepol/policydb/policydb.h>
53
#include <sepol/policydb/services.h>
54
#include <sepol/policydb/conditional.h>
55
#include <sepol/policydb/hierarchy.h>
56
#include <sepol/policydb/polcaps.h>
57
#include <sepol/policydb/dtpath.h>
58
#include "queue.h"
59
#include "module_compiler.h"
60
#include "policy_define.h"
61
62
extern void init_parser(int pass_number, const char *input_name);
63
__attribute__((format(printf, 1, 2))) extern void yyerror2(const char *fmt,
64
                 ...);
65
66
policydb_t *policydbp;
67
queue_t id_queue = NULL;
68
unsigned int pass;
69
int mlspol = 0;
70
71
extern unsigned long policydb_lineno;
72
extern unsigned long source_lineno;
73
extern unsigned int policydb_errors;
74
extern char source_file[PATH_MAX];
75
extern void set_source_file(const char *name);
76
77
extern int yywarn(const char *msg);
78
extern int yyerror(const char *msg);
79
80
/* initialize all of the state variables for the scanner/parser */
81
void init_parser(int pass_number, const char *input_name)
82
14.9k
{
83
14.9k
  policydb_lineno = 1;
84
14.9k
  source_lineno = 1;
85
14.9k
  policydb_errors = 0;
86
14.9k
  pass = pass_number;
87
14.9k
  set_source_file(input_name);
88
14.9k
  queue_clear(id_queue);
89
14.9k
}
90
91
void yyerror2(const char *fmt, ...)
92
21.7k
{
93
21.7k
  char errormsg[256];
94
21.7k
  va_list ap;
95
21.7k
  va_start(ap, fmt);
96
21.7k
  vsnprintf(errormsg, sizeof(errormsg), fmt, ap);
97
21.7k
  yyerror(errormsg);
98
21.7k
  va_end(ap);
99
21.7k
}
100
101
__attribute__((format(printf, 1, 2))) static void yywarn2(const char *fmt, ...)
102
0
{
103
0
  char warnmsg[256];
104
0
  va_list ap;
105
0
  va_start(ap, fmt);
106
0
  vsnprintf(warnmsg, sizeof(warnmsg), fmt, ap);
107
0
  yywarn(warnmsg);
108
0
  va_end(ap);
109
0
}
110
111
int insert_separator(int push)
112
723k
{
113
723k
  int error;
114
115
723k
  if (push)
116
85.7k
    error = queue_push(id_queue, NULL);
117
637k
  else
118
637k
    error = queue_insert(id_queue, NULL);
119
120
723k
  if (error) {
121
0
    yyerror("queue overflow");
122
0
    return -1;
123
0
  }
124
723k
  return 0;
125
723k
}
126
127
int insert_id(const char *id, int push)
128
2.38M
{
129
2.38M
  char *newid = NULL;
130
2.38M
  int error;
131
132
2.38M
  newid = strdup(id);
133
2.38M
  if (!newid) {
134
0
    yyerror("out of memory");
135
0
    return -1;
136
0
  }
137
2.38M
  if (push)
138
86.8k
    error = queue_push(id_queue, (queue_element_t)newid);
139
2.29M
  else
140
2.29M
    error = queue_insert(id_queue, (queue_element_t)newid);
141
142
2.38M
  if (error) {
143
0
    yyerror("queue overflow");
144
0
    free(newid);
145
0
    return -1;
146
0
  }
147
2.38M
  return 0;
148
2.38M
}
149
150
/* If the identifier has a dot within it and that its first character
151
   is not a dot then return 1, else return 0. */
152
static int id_has_dot(const char *id)
153
20.9k
{
154
20.9k
  if (strchr(id, '.') >= id + 1) {
155
627
    return 1;
156
627
  }
157
20.2k
  return 0;
158
20.9k
}
159
160
int define_class(void)
161
28.7k
{
162
28.7k
  char *id = NULL;
163
28.7k
  class_datum_t *datum = NULL;
164
28.7k
  int ret = -1;
165
28.7k
  uint32_t value;
166
167
28.7k
  if (pass == 2) {
168
12.0k
    id = queue_remove(id_queue);
169
12.0k
    free(id);
170
12.0k
    return 0;
171
12.0k
  }
172
173
16.6k
  id = (char *)queue_remove(id_queue);
174
16.6k
  if (!id) {
175
0
    yyerror("no class name for class definition?");
176
0
    return -1;
177
0
  }
178
16.6k
  datum = calloc(1, sizeof(class_datum_t));
179
16.6k
  if (!datum) {
180
0
    yyerror("out of memory");
181
0
    goto cleanup;
182
0
  }
183
16.6k
  ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
184
16.6k
  switch (ret) {
185
0
  case -3: {
186
0
    yyerror("Out of memory!");
187
0
    goto cleanup;
188
0
  }
189
3
  case -2: {
190
3
    yyerror2("duplicate declaration of class %s", id);
191
3
    goto cleanup;
192
0
  }
193
0
  case -1: {
194
0
    yyerror("could not declare class here");
195
0
    goto cleanup;
196
0
  }
197
16.6k
  case 0: {
198
16.6k
    break;
199
0
  }
200
0
  case 1: {
201
0
    goto cleanup;
202
0
  }
203
0
  default: {
204
0
    assert(0); /* should never get here */
205
0
  }
206
16.6k
  }
207
16.6k
  datum->s.value = value;
208
16.6k
  return 0;
209
210
3
cleanup:
211
3
  free(id);
212
3
  free(datum);
213
3
  return ret == 1 ? 0 : -1;
214
16.6k
}
215
216
int define_permissive(void)
217
620
{
218
620
  char *type = NULL;
219
620
  struct type_datum *t;
220
620
  int rc = 0;
221
222
620
  type = queue_remove(id_queue);
223
224
620
  if (!type) {
225
1
    yyerror2("forgot to include type in permissive definition?");
226
1
    rc = -1;
227
1
    goto out;
228
1
  }
229
230
619
  if (pass == 1)
231
410
    goto out;
232
233
209
  if (!is_id_in_scope(SYM_TYPES, type)) {
234
1
    yyerror2("type %s is not within scope", type);
235
1
    rc = -1;
236
1
    goto out;
237
1
  }
238
239
208
  t = hashtab_search(policydbp->p_types.table, type);
240
208
  if (!t) {
241
3
    yyerror2("type is not defined: %s", type);
242
3
    rc = -1;
243
3
    goto out;
244
3
  }
245
246
205
  if (t->flavor == TYPE_ATTRIB) {
247
1
    yyerror2("attributes may not be permissive: %s", type);
248
1
    rc = -1;
249
1
    goto out;
250
1
  }
251
252
204
  t->flags |= TYPE_FLAGS_PERMISSIVE;
253
254
620
out:
255
620
  free(type);
256
620
  return rc;
257
204
}
258
259
int define_neveraudit(void)
260
214
{
261
214
  char *type = NULL;
262
214
  struct type_datum *t;
263
214
  int rc = 0;
264
265
214
  type = queue_remove(id_queue);
266
267
214
  if (!type) {
268
1
    yyerror2("forgot to include type in neveraudit definition?");
269
1
    rc = -1;
270
1
    goto out;
271
1
  }
272
273
213
  if (pass == 1)
274
207
    goto out;
275
276
6
  if (!is_id_in_scope(SYM_TYPES, type)) {
277
1
    yyerror2("type %s is not within scope", type);
278
1
    rc = -1;
279
1
    goto out;
280
1
  }
281
282
5
  t = hashtab_search(policydbp->p_types.table, type);
283
5
  if (!t) {
284
1
    yyerror2("type is not defined: %s", type);
285
1
    rc = -1;
286
1
    goto out;
287
1
  }
288
289
4
  if (t->flavor == TYPE_ATTRIB) {
290
1
    yyerror2("attributes may not be neveraudit: %s", type);
291
1
    rc = -1;
292
1
    goto out;
293
1
  }
294
295
3
  t->flags |= TYPE_FLAGS_NEVERAUDIT;
296
297
214
out:
298
214
  free(type);
299
214
  return rc;
300
3
}
301
302
int define_polcap(void)
303
367
{
304
367
  char *id = NULL;
305
367
  int capnum;
306
307
367
  if (pass == 2) {
308
79
    id = queue_remove(id_queue);
309
79
    free(id);
310
79
    return 0;
311
79
  }
312
313
288
  id = (char *)queue_remove(id_queue);
314
288
  if (!id) {
315
1
    yyerror("no capability name for policycap definition?");
316
1
    goto bad;
317
1
  }
318
319
  /* Check for valid cap name -> number mapping */
320
287
  capnum = sepol_polcap_getnum(id);
321
287
  if (capnum < 0) {
322
117
    yyerror2("invalid policy capability name %s", id);
323
117
    goto bad;
324
117
  }
325
326
  /* Store it */
327
170
  if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
328
0
    yyerror("out of memory");
329
0
    goto bad;
330
0
  }
331
332
170
  free(id);
333
170
  return 0;
334
335
118
bad:
336
118
  free(id);
337
118
  return -1;
338
170
}
339
340
int define_initial_sid(void)
341
21.6k
{
342
21.6k
  char *id = NULL;
343
21.6k
  ocontext_t *newc = NULL, *c, *head;
344
345
21.6k
  if (pass == 2) {
346
9.09k
    id = queue_remove(id_queue);
347
9.09k
    free(id);
348
9.09k
    return 0;
349
9.09k
  }
350
351
12.5k
  id = (char *)queue_remove(id_queue);
352
12.5k
  if (!id) {
353
0
    yyerror("no sid name for SID definition?");
354
0
    return -1;
355
0
  }
356
12.5k
  newc = calloc(1, sizeof(ocontext_t));
357
12.5k
  if (!newc) {
358
0
    yyerror("out of memory");
359
0
    goto bad;
360
0
  }
361
12.5k
  newc->u.name = id;
362
12.5k
  context_init(&newc->context[0]);
363
12.5k
  head = policydbp->ocontexts[OCON_ISID];
364
365
19.8k
  for (c = head; c; c = c->next) {
366
7.36k
    if (!strcmp(newc->u.name, c->u.name)) {
367
3
      yyerror2("duplicate initial SID %s", id);
368
3
      goto bad;
369
3
    }
370
7.36k
  }
371
372
12.5k
  if (head) {
373
3.90k
    newc->sid[0] = head->sid[0] + 1;
374
8.62k
  } else {
375
8.62k
    newc->sid[0] = 1;
376
8.62k
  }
377
12.5k
  newc->next = head;
378
12.5k
  policydbp->ocontexts[OCON_ISID] = newc;
379
380
12.5k
  return 0;
381
382
3
bad:
383
3
  free(id);
384
3
  free(newc);
385
3
  return -1;
386
12.5k
}
387
388
static int read_classes(ebitmap_t *e_classes)
389
38.7k
{
390
38.7k
  char *id;
391
38.7k
  class_datum_t *cladatum;
392
393
77.4k
  while ((id = queue_remove(id_queue))) {
394
38.7k
    if (!is_id_in_scope(SYM_CLASSES, id)) {
395
0
      yyerror2("class %s is not within scope", id);
396
0
      free(id);
397
0
      return -1;
398
0
    }
399
38.7k
    cladatum = hashtab_search(policydbp->p_classes.table, id);
400
38.7k
    if (!cladatum) {
401
42
      yyerror2("unknown class %s", id);
402
42
      free(id);
403
42
      return -1;
404
42
    }
405
38.7k
    free(id);
406
38.7k
    if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
407
0
      yyerror("Out of memory");
408
0
      return -1;
409
0
    }
410
38.7k
  }
411
38.7k
  return 0;
412
38.7k
}
413
414
int define_default_user(int which)
415
341
{
416
341
  char *id;
417
341
  class_datum_t *cladatum;
418
419
341
  if (pass == 1) {
420
942
    while ((id = queue_remove(id_queue)))
421
617
      free(id);
422
325
    return 0;
423
325
  }
424
425
41
  while ((id = queue_remove(id_queue))) {
426
32
    if (!is_id_in_scope(SYM_CLASSES, id)) {
427
0
      yyerror2("class %s is not within scope", id);
428
0
      free(id);
429
0
      return -1;
430
0
    }
431
32
    cladatum = hashtab_search(policydbp->p_classes.table, id);
432
32
    if (!cladatum) {
433
6
      yyerror2("unknown class %s", id);
434
6
      free(id);
435
6
      return -1;
436
6
    }
437
26
    if (cladatum->default_user && cladatum->default_user != which) {
438
1
      yyerror2(
439
1
        "conflicting default user information for class %s",
440
1
        id);
441
1
      free(id);
442
1
      return -1;
443
1
    }
444
25
    cladatum->default_user = which;
445
25
    free(id);
446
25
  }
447
448
9
  return 0;
449
16
}
450
451
int define_default_role(int which)
452
4.31k
{
453
4.31k
  char *id;
454
4.31k
  class_datum_t *cladatum;
455
456
4.31k
  if (pass == 1) {
457
4.90k
    while ((id = queue_remove(id_queue)))
458
2.56k
      free(id);
459
2.34k
    return 0;
460
2.34k
  }
461
462
3.95k
  while ((id = queue_remove(id_queue))) {
463
1.99k
    if (!is_id_in_scope(SYM_CLASSES, id)) {
464
0
      yyerror2("class %s is not within scope", id);
465
0
      free(id);
466
0
      return -1;
467
0
    }
468
1.99k
    cladatum = hashtab_search(policydbp->p_classes.table, id);
469
1.99k
    if (!cladatum) {
470
16
      yyerror2("unknown class %s", id);
471
16
      free(id);
472
16
      return -1;
473
16
    }
474
1.97k
    if (cladatum->default_role && cladatum->default_role != which) {
475
1
      yyerror2(
476
1
        "conflicting default role information for class %s",
477
1
        id);
478
1
      free(id);
479
1
      return -1;
480
1
    }
481
1.97k
    cladatum->default_role = which;
482
1.97k
    free(id);
483
1.97k
  }
484
485
1.95k
  return 0;
486
1.97k
}
487
488
int define_default_type(int which)
489
2.48k
{
490
2.48k
  char *id;
491
2.48k
  class_datum_t *cladatum;
492
493
2.48k
  if (pass == 1) {
494
2.98k
    while ((id = queue_remove(id_queue)))
495
1.59k
      free(id);
496
1.38k
    return 0;
497
1.38k
  }
498
499
2.18k
  while ((id = queue_remove(id_queue))) {
500
1.10k
    if (!is_id_in_scope(SYM_CLASSES, id)) {
501
0
      yyerror2("class %s is not within scope", id);
502
0
      free(id);
503
0
      return -1;
504
0
    }
505
1.10k
    cladatum = hashtab_search(policydbp->p_classes.table, id);
506
1.10k
    if (!cladatum) {
507
11
      yyerror2("unknown class %s", id);
508
11
      free(id);
509
11
      return -1;
510
11
    }
511
1.09k
    if (cladatum->default_type && cladatum->default_type != which) {
512
1
      yyerror2(
513
1
        "conflicting default type information for class %s",
514
1
        id);
515
1
      free(id);
516
1
      return -1;
517
1
    }
518
1.09k
    cladatum->default_type = which;
519
1.09k
    free(id);
520
1.09k
  }
521
522
1.08k
  return 0;
523
1.09k
}
524
525
int define_default_range(int which)
526
210
{
527
210
  char *id;
528
210
  class_datum_t *cladatum;
529
530
210
  if (pass == 1) {
531
1.13k
    while ((id = queue_remove(id_queue)))
532
931
      free(id);
533
208
    return 0;
534
208
  }
535
536
3
  while ((id = queue_remove(id_queue))) {
537
3
    if (!is_id_in_scope(SYM_CLASSES, id)) {
538
0
      yyerror2("class %s is not within scope", id);
539
0
      free(id);
540
0
      return -1;
541
0
    }
542
3
    cladatum = hashtab_search(policydbp->p_classes.table, id);
543
3
    if (!cladatum) {
544
2
      yyerror2("unknown class %s", id);
545
2
      free(id);
546
2
      return -1;
547
2
    }
548
1
    if (cladatum->default_range &&
549
0
        cladatum->default_range != which) {
550
0
      yyerror2(
551
0
        "conflicting default range information for class %s",
552
0
        id);
553
0
      free(id);
554
0
      return -1;
555
0
    }
556
1
    cladatum->default_range = which;
557
1
    free(id);
558
1
  }
559
560
0
  return 0;
561
2
}
562
563
int define_common_perms(void)
564
179
{
565
179
  char *id = NULL, *perm = NULL;
566
179
  common_datum_t *comdatum = NULL;
567
179
  perm_datum_t *perdatum = NULL;
568
179
  int ret;
569
570
179
  if (pass == 2) {
571
69
    while ((id = queue_remove(id_queue)))
572
55
      free(id);
573
14
    return 0;
574
14
  }
575
576
165
  id = (char *)queue_remove(id_queue);
577
165
  if (!id) {
578
0
    yyerror("no common name for common perm definition?");
579
0
    return -1;
580
0
  }
581
165
  comdatum = hashtab_search(policydbp->p_commons.table, id);
582
165
  if (comdatum) {
583
1
    yyerror2("duplicate declaration for common %s", id);
584
1
    free(id);
585
1
    return -1;
586
1
  }
587
164
  comdatum = calloc(1, sizeof(common_datum_t));
588
164
  if (!comdatum) {
589
0
    yyerror("out of memory");
590
0
    goto bad;
591
0
  }
592
164
  ret = hashtab_insert(policydbp->p_commons.table, (hashtab_key_t)id,
593
164
           (hashtab_datum_t)comdatum);
594
595
164
  if (ret == SEPOL_EEXIST) {
596
0
    yyerror("duplicate common definition");
597
0
    goto bad;
598
0
  }
599
164
  if (ret == SEPOL_ENOMEM) {
600
0
    yyerror("hash table overflow");
601
0
    goto bad;
602
0
  }
603
164
  comdatum->s.value = policydbp->p_commons.nprim + 1;
604
164
  if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
605
0
    yyerror("out of memory");
606
0
    goto bad;
607
0
  }
608
164
  policydbp->p_commons.nprim++;
609
456
  while ((perm = queue_remove(id_queue))) {
610
296
    perdatum = calloc(1, sizeof(perm_datum_t));
611
296
    if (!perdatum) {
612
0
      yyerror("out of memory");
613
0
      goto bad_perm;
614
0
    }
615
296
    perdatum->s.value = comdatum->permissions.nprim + 1;
616
617
296
    if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
618
1
      yyerror2(
619
1
        "too many permissions (%d) to fit in an access vector",
620
1
        perdatum->s.value);
621
1
      goto bad_perm;
622
1
    }
623
295
    ret = hashtab_insert(comdatum->permissions.table,
624
295
             (hashtab_key_t)perm,
625
295
             (hashtab_datum_t)perdatum);
626
627
295
    if (ret == SEPOL_EEXIST) {
628
3
      yyerror2("duplicate permission %s in common %s", perm,
629
3
         id);
630
3
      goto bad_perm;
631
3
    }
632
292
    if (ret == SEPOL_ENOMEM) {
633
0
      yyerror("hash table overflow");
634
0
      goto bad_perm;
635
0
    }
636
292
    comdatum->permissions.nprim++;
637
292
  }
638
639
160
  return 0;
640
641
0
bad:
642
0
  free(id);
643
0
  free(comdatum);
644
0
  return -1;
645
646
4
bad_perm:
647
4
  free(perm);
648
4
  free(perdatum);
649
4
  return -1;
650
164
}
651
652
int define_av_perms(int inherits)
653
14.1k
{
654
14.1k
  char *id;
655
14.1k
  class_datum_t *cladatum;
656
14.1k
  common_datum_t *comdatum;
657
14.1k
  perm_datum_t *perdatum = NULL, *perdatum2 = NULL;
658
14.1k
  int ret;
659
660
14.1k
  if (pass == 2) {
661
25.1k
    while ((id = queue_remove(id_queue)))
662
19.4k
      free(id);
663
5.70k
    return 0;
664
5.70k
  }
665
666
8.41k
  id = (char *)queue_remove(id_queue);
667
8.41k
  if (!id) {
668
0
    yyerror("no tclass name for av perm definition?");
669
0
    return -1;
670
0
  }
671
8.41k
  cladatum = (class_datum_t *)hashtab_search(policydbp->p_classes.table,
672
8.41k
               (hashtab_key_t)id);
673
8.41k
  if (!cladatum) {
674
2
    yyerror2("class %s is not defined", id);
675
2
    goto bad;
676
2
  }
677
678
8.41k
  if (cladatum->comdatum || cladatum->permissions.nprim) {
679
4
    yyerror2("duplicate access vector definition for class %s", id);
680
4
    goto bad;
681
4
  }
682
683
8.41k
  free(id);
684
8.41k
  id = NULL;
685
686
8.41k
  if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
687
0
    yyerror("out of memory");
688
0
    return -1;
689
0
  }
690
8.41k
  if (inherits) {
691
2
    id = (char *)queue_remove(id_queue);
692
2
    if (!id) {
693
0
      yyerror("no inherits name for access vector definition?");
694
0
      return -1;
695
0
    }
696
2
    comdatum = (common_datum_t *)hashtab_search(
697
2
      policydbp->p_commons.table, (hashtab_key_t)id);
698
699
2
    if (!comdatum) {
700
2
      yyerror2("common %s is not defined", id);
701
2
      goto bad;
702
2
    }
703
0
    cladatum->comkey = id;
704
0
    cladatum->comdatum = comdatum;
705
706
    /*
707
     * Class-specific permissions start with values 
708
     * after the last common permission.
709
     */
710
0
    cladatum->permissions.nprim += comdatum->permissions.nprim;
711
0
  }
712
25.2k
  while ((id = queue_remove(id_queue))) {
713
16.8k
    perdatum = calloc(1, sizeof(perm_datum_t));
714
16.8k
    if (!perdatum) {
715
0
      yyerror("out of memory");
716
0
      goto bad;
717
0
    }
718
16.8k
    perdatum->s.value = ++cladatum->permissions.nprim;
719
720
16.8k
    if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
721
1
      yyerror2(
722
1
        "too many permissions (%d) to fit in an access vector",
723
1
        perdatum->s.value);
724
1
      goto bad;
725
1
    }
726
16.8k
    if (inherits) {
727
      /*
728
       * Class-specific permissions and 
729
       * common permissions exist in the same
730
       * name space.
731
       */
732
0
      perdatum2 = (perm_datum_t *)hashtab_search(
733
0
        cladatum->comdatum->permissions.table,
734
0
        (hashtab_key_t)id);
735
0
      if (perdatum2) {
736
0
        yyerror2("permission %s conflicts with an "
737
0
           "inherited permission",
738
0
           id);
739
0
        goto bad;
740
0
      }
741
0
    }
742
16.8k
    ret = hashtab_insert(cladatum->permissions.table,
743
16.8k
             (hashtab_key_t)id,
744
16.8k
             (hashtab_datum_t)perdatum);
745
746
16.8k
    if (ret == SEPOL_EEXIST) {
747
4
      yyerror2("duplicate permission %s", id);
748
4
      goto bad;
749
4
    }
750
16.8k
    if (ret == SEPOL_ENOMEM) {
751
0
      yyerror("hash table overflow");
752
0
      goto bad;
753
0
    }
754
16.8k
    if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
755
0
      yyerror("out of memory");
756
0
      goto bad;
757
0
    }
758
16.8k
  }
759
760
8.40k
  return 0;
761
762
13
bad:
763
13
  free(id);
764
13
  free(perdatum);
765
13
  return -1;
766
8.41k
}
767
768
int define_sens(void)
769
7.21k
{
770
7.21k
  char *id;
771
7.21k
  mls_level_t *level = NULL;
772
7.21k
  level_datum_t *datum = NULL, *aliasdatum = NULL;
773
7.21k
  int ret;
774
7.21k
  uint32_t value; /* dummy variable -- its value is never used */
775
776
7.21k
  if (!mlspol) {
777
2
    yyerror("sensitivity definition in non-MLS configuration");
778
2
    return -1;
779
2
  }
780
781
7.21k
  if (pass == 2) {
782
6.93k
    while ((id = queue_remove(id_queue)))
783
3.48k
      free(id);
784
3.44k
    return 0;
785
3.44k
  }
786
787
3.76k
  id = (char *)queue_remove(id_queue);
788
3.76k
  if (!id) {
789
0
    yyerror("no sensitivity name for sensitivity definition?");
790
0
    return -1;
791
0
  }
792
3.76k
  if (id_has_dot(id)) {
793
1
    yyerror2("sensitivity identifier %s may not contain periods",
794
1
       id);
795
1
    goto bad;
796
1
  }
797
3.76k
  level = malloc(sizeof(mls_level_t));
798
3.76k
  if (!level) {
799
0
    yyerror("out of memory");
800
0
    goto bad;
801
0
  }
802
3.76k
  mls_level_init(level);
803
3.76k
  level->sens = 0; /* actual value set in define_dominance */
804
3.76k
  ebitmap_init(&level->cat); /* actual value set in define_level */
805
806
3.76k
  datum = malloc(sizeof(level_datum_t));
807
3.76k
  if (!datum) {
808
0
    yyerror("out of memory");
809
0
    goto bad;
810
0
  }
811
3.76k
  level_datum_init(datum);
812
3.76k
  datum->isalias = FALSE;
813
3.76k
  datum->level = level;
814
3.76k
  datum->notdefined = TRUE;
815
816
3.76k
  ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
817
3.76k
  switch (ret) {
818
0
  case -3: {
819
0
    yyerror("Out of memory!");
820
0
    goto bad;
821
0
  }
822
1
  case -2: {
823
1
    yyerror2("duplicate declaration of sensitivity level %s", id);
824
1
    goto bad;
825
0
  }
826
0
  case -1: {
827
0
    yyerror2("could not declare sensitivity level %s here", id);
828
0
    goto bad;
829
0
  }
830
3.76k
  case 0: {
831
3.76k
    break;
832
0
  }
833
0
  case 1: {
834
0
    level_datum_destroy(datum);
835
0
    free(datum);
836
0
    free(id);
837
0
    break;
838
0
  }
839
0
  default: {
840
0
    assert(0); /* should never get here */
841
0
  }
842
3.76k
  }
843
844
3.94k
  while ((id = queue_remove(id_queue))) {
845
181
    if (id_has_dot(id)) {
846
1
      yyerror2("sensitivity alias %s may not contain periods",
847
1
         id);
848
1
      free(id);
849
1
      return -1;
850
1
    }
851
180
    aliasdatum = malloc(sizeof(level_datum_t));
852
180
    if (!aliasdatum) {
853
0
      yyerror("out of memory");
854
0
      free(id);
855
0
      return -1;
856
0
    }
857
180
    level_datum_init(aliasdatum);
858
180
    aliasdatum->isalias = TRUE;
859
180
    aliasdatum->level = level;
860
180
    aliasdatum->notdefined = TRUE;
861
862
180
    ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
863
180
    switch (ret) {
864
0
    case -3: {
865
0
      yyerror("Out of memory!");
866
0
      goto bad_alias;
867
0
    }
868
2
    case -2: {
869
2
      yyerror2(
870
2
        "duplicate declaration of sensitivity alias %s",
871
2
        id);
872
2
      goto bad_alias;
873
0
    }
874
0
    case -1: {
875
0
      yyerror2("could not declare sensitivity alias %s here",
876
0
         id);
877
0
      goto bad_alias;
878
0
    }
879
178
    case 0: {
880
178
      break;
881
0
    }
882
0
    case 1: {
883
0
      level_datum_destroy(aliasdatum);
884
0
      free(aliasdatum);
885
0
      free(id);
886
0
      break;
887
0
    }
888
0
    default: {
889
0
      assert(0); /* should never get here */
890
0
    }
891
180
    }
892
180
  }
893
894
3.76k
  return 0;
895
896
2
bad:
897
2
  free(id);
898
2
  free(level);
899
2
  if (datum) {
900
1
    level_datum_destroy(datum);
901
1
    free(datum);
902
1
  }
903
2
  return -1;
904
905
2
bad_alias:
906
2
  free(id);
907
2
  if (aliasdatum) {
908
2
    level_datum_destroy(aliasdatum);
909
2
    free(aliasdatum);
910
2
  }
911
2
  return -1;
912
3.76k
}
913
914
int define_dominance(void)
915
7.16k
{
916
7.16k
  level_datum_t *datum;
917
7.16k
  uint32_t order;
918
7.16k
  char *id;
919
920
7.16k
  if (!mlspol) {
921
0
    yyerror("dominance definition in non-MLS configuration");
922
0
    return -1;
923
0
  }
924
925
7.16k
  if (pass == 2) {
926
6.89k
    while ((id = queue_remove(id_queue)))
927
3.44k
      free(id);
928
3.44k
    return 0;
929
3.44k
  }
930
931
3.71k
  order = 0;
932
7.44k
  while ((id = (char *)queue_remove(id_queue))) {
933
3.73k
    datum = (level_datum_t *)hashtab_search(
934
3.73k
      policydbp->p_levels.table, (hashtab_key_t)id);
935
3.73k
    if (!datum) {
936
3
      yyerror2("unknown sensitivity %s used in dominance "
937
3
         "definition",
938
3
         id);
939
3
      free(id);
940
3
      return -1;
941
3
    }
942
3.72k
    if (datum->level->sens != 0) {
943
1
      yyerror2("sensitivity %s occurs multiply in dominance "
944
1
         "definition",
945
1
         id);
946
1
      free(id);
947
1
      return -1;
948
1
    }
949
3.72k
    datum->level->sens = ++order;
950
951
    /* no need to keep sensitivity name */
952
3.72k
    free(id);
953
3.72k
  }
954
955
3.71k
  if (order != policydbp->p_levels.nprim) {
956
2
    yyerror("all sensitivities must be specified in dominance definition");
957
2
    return -1;
958
2
  }
959
3.70k
  return 0;
960
3.71k
}
961
962
int define_category(void)
963
7.11k
{
964
7.11k
  char *id;
965
7.11k
  cat_datum_t *datum = NULL, *aliasdatum = NULL;
966
7.11k
  int ret;
967
7.11k
  uint32_t value;
968
969
7.11k
  if (!mlspol) {
970
0
    yyerror("category definition in non-MLS configuration");
971
0
    return -1;
972
0
  }
973
974
7.11k
  if (pass == 2) {
975
6.94k
    while ((id = queue_remove(id_queue)))
976
3.51k
      free(id);
977
3.43k
    return 0;
978
3.43k
  }
979
980
3.68k
  id = (char *)queue_remove(id_queue);
981
3.68k
  if (!id) {
982
0
    yyerror("no category name for category definition?");
983
0
    return -1;
984
0
  }
985
3.68k
  if (id_has_dot(id)) {
986
1
    yyerror2("category identifier %s may not contain periods", id);
987
1
    goto bad;
988
1
  }
989
3.68k
  datum = malloc(sizeof(cat_datum_t));
990
3.68k
  if (!datum) {
991
0
    yyerror("out of memory");
992
0
    goto bad;
993
0
  }
994
3.68k
  cat_datum_init(datum);
995
3.68k
  datum->isalias = FALSE;
996
997
3.68k
  ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
998
3.68k
  switch (ret) {
999
0
  case -3: {
1000
0
    yyerror("Out of memory!");
1001
0
    goto bad;
1002
0
  }
1003
1
  case -2: {
1004
1
    yyerror2("duplicate declaration of category %s", id);
1005
1
    goto bad;
1006
0
  }
1007
0
  case -1: {
1008
0
    yyerror2("could not declare category %s here", id);
1009
0
    goto bad;
1010
0
  }
1011
3.68k
  case 0: {
1012
3.68k
    datum->s.value = value;
1013
3.68k
    break;
1014
0
  }
1015
0
  case 1: {
1016
0
    cat_datum_destroy(datum);
1017
0
    free(datum);
1018
0
    free(id);
1019
0
    break;
1020
0
  }
1021
0
  default: {
1022
0
    assert(0); /* should never get here */
1023
0
  }
1024
3.68k
  }
1025
1026
3.85k
  while ((id = queue_remove(id_queue))) {
1027
168
    if (id_has_dot(id)) {
1028
1
      yyerror2("category alias %s may not contain periods",
1029
1
         id);
1030
1
      free(id);
1031
1
      return -1;
1032
1
    }
1033
167
    aliasdatum = malloc(sizeof(cat_datum_t));
1034
167
    if (!aliasdatum) {
1035
0
      yyerror("out of memory");
1036
0
      free(id);
1037
0
      return -1;
1038
0
    }
1039
167
    cat_datum_init(aliasdatum);
1040
167
    aliasdatum->isalias = TRUE;
1041
167
    aliasdatum->s.value = value;
1042
1043
167
    ret = declare_symbol(SYM_CATS, id, aliasdatum, NULL, &value);
1044
167
    switch (ret) {
1045
0
    case -3: {
1046
0
      yyerror("Out of memory!");
1047
0
      goto bad_alias;
1048
0
    }
1049
1
    case -2: {
1050
1
      yyerror2("duplicate declaration of category alias %s",
1051
1
         id);
1052
1
      goto bad_alias;
1053
0
    }
1054
0
    case -1: {
1055
0
      yyerror2("could not declare category alias %s here",
1056
0
         id);
1057
0
      goto bad_alias;
1058
0
    }
1059
166
    case 0: {
1060
166
      break;
1061
0
    }
1062
0
    case 1: {
1063
0
      cat_datum_destroy(aliasdatum);
1064
0
      free(aliasdatum);
1065
0
      free(id);
1066
0
      break;
1067
0
    }
1068
0
    default: {
1069
0
      assert(0); /* should never get here */
1070
0
    }
1071
167
    }
1072
167
  }
1073
1074
3.68k
  return 0;
1075
1076
2
bad:
1077
2
  free(id);
1078
2
  if (datum) {
1079
1
    cat_datum_destroy(datum);
1080
1
    free(datum);
1081
1
  }
1082
2
  return -1;
1083
1084
1
bad_alias:
1085
1
  free(id);
1086
1
  if (aliasdatum) {
1087
1
    cat_datum_destroy(aliasdatum);
1088
1
    free(aliasdatum);
1089
1
  }
1090
1
  return -1;
1091
3.68k
}
1092
1093
static int clone_level(hashtab_key_t key __attribute__((unused)),
1094
           hashtab_datum_t datum, void *arg)
1095
4.37k
{
1096
4.37k
  level_datum_t *levdatum = (level_datum_t *)datum;
1097
4.37k
  mls_level_t *level = (mls_level_t *)arg, *newlevel;
1098
1099
4.37k
  if (levdatum->notdefined && levdatum->level == level) {
1100
3.77k
    if (!levdatum->isalias) {
1101
3.68k
      levdatum->notdefined = FALSE;
1102
3.68k
      return 0;
1103
3.68k
    }
1104
89
    newlevel = malloc(sizeof(mls_level_t));
1105
89
    if (!newlevel)
1106
0
      return -1;
1107
89
    if (mls_level_cpy(newlevel, level)) {
1108
0
      free(newlevel);
1109
0
      return -1;
1110
0
    }
1111
89
    levdatum->level = newlevel;
1112
89
    levdatum->notdefined = FALSE;
1113
89
  }
1114
695
  return 0;
1115
4.37k
}
1116
1117
int define_level(void)
1118
7.49k
{
1119
7.49k
  char *id;
1120
7.49k
  level_datum_t *levdatum;
1121
1122
7.49k
  if (!mlspol) {
1123
0
    yyerror("level definition in non-MLS configuration");
1124
0
    return -1;
1125
0
  }
1126
1127
7.49k
  if (pass == 2) {
1128
10.2k
    while ((id = queue_remove(id_queue)))
1129
6.83k
      free(id);
1130
3.46k
    return 0;
1131
3.46k
  }
1132
1133
4.03k
  id = (char *)queue_remove(id_queue);
1134
4.03k
  if (!id) {
1135
0
    yyerror("no level name for level definition?");
1136
0
    return -1;
1137
0
  }
1138
4.03k
  levdatum = (level_datum_t *)hashtab_search(policydbp->p_levels.table,
1139
4.03k
               (hashtab_key_t)id);
1140
4.03k
  if (!levdatum) {
1141
2
    yyerror2("unknown sensitivity %s used in level definition", id);
1142
2
    free(id);
1143
2
    return -1;
1144
2
  }
1145
4.03k
  if (ebitmap_length(&levdatum->level->cat)) {
1146
1
    yyerror2("sensitivity %s used in multiple level definitions",
1147
1
       id);
1148
1
    free(id);
1149
1
    return -1;
1150
1
  }
1151
4.03k
  free(id);
1152
1153
8.15k
  while ((id = queue_remove(id_queue))) {
1154
4.13k
    cat_datum_t *cdatum;
1155
4.13k
    uint32_t range_start, range_end, i;
1156
1157
4.13k
    if (id_has_dot(id)) {
1158
161
      char *id_start = id;
1159
161
      char *id_end = strchr(id, '.');
1160
1161
161
      *(id_end++) = '\0';
1162
1163
161
      cdatum = (cat_datum_t *)hashtab_search(
1164
161
        policydbp->p_cats.table,
1165
161
        (hashtab_key_t)id_start);
1166
161
      if (!cdatum) {
1167
1
        yyerror2("unknown category %s", id_start);
1168
1
        free(id);
1169
1
        return -1;
1170
1
      }
1171
160
      range_start = cdatum->s.value - 1;
1172
160
      cdatum = (cat_datum_t *)hashtab_search(
1173
160
        policydbp->p_cats.table, (hashtab_key_t)id_end);
1174
160
      if (!cdatum) {
1175
1
        yyerror2("unknown category %s", id_end);
1176
1
        free(id);
1177
1
        return -1;
1178
1
      }
1179
159
      range_end = cdatum->s.value - 1;
1180
1181
159
      if (range_end < range_start) {
1182
0
        yyerror2("category range %d-%d is invalid",
1183
0
           range_start, range_end);
1184
0
        free(id);
1185
0
        return -1;
1186
0
      }
1187
3.97k
    } else {
1188
3.97k
      cdatum = (cat_datum_t *)hashtab_search(
1189
3.97k
        policydbp->p_cats.table, (hashtab_key_t)id);
1190
3.97k
      if (!cdatum) {
1191
7
        yyerror2("unknown category %s", id);
1192
7
        free(id);
1193
7
        return -1;
1194
7
      }
1195
3.96k
      range_start = range_end = cdatum->s.value - 1;
1196
3.96k
    }
1197
1198
8.24k
    for (i = range_start; i <= range_end; i++) {
1199
4.12k
      if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
1200
0
        yyerror("out of memory");
1201
0
        free(id);
1202
0
        return -1;
1203
0
      }
1204
4.12k
    }
1205
1206
4.12k
    free(id);
1207
4.12k
  }
1208
1209
4.02k
  if (hashtab_map(policydbp->p_levels.table, clone_level,
1210
4.02k
      levdatum->level)) {
1211
0
    yyerror("out of memory");
1212
0
    return -1;
1213
0
  }
1214
1215
4.02k
  return 0;
1216
4.02k
}
1217
1218
int define_attrib(void)
1219
1.25k
{
1220
1.25k
  if (pass == 2) {
1221
600
    free(queue_remove(id_queue));
1222
600
    return 0;
1223
600
  }
1224
1225
657
  if (declare_type(TRUE, TRUE) == NULL) {
1226
1
    return -1;
1227
1
  }
1228
656
  return 0;
1229
657
}
1230
1231
int expand_attrib(void)
1232
1.14k
{
1233
1.14k
  char *id;
1234
1.14k
  ebitmap_t attrs;
1235
1.14k
  type_datum_t *attr;
1236
1.14k
  ebitmap_node_t *node;
1237
1.14k
  const char *name;
1238
1.14k
  uint32_t i;
1239
1.14k
  int rc = -1;
1240
1.14k
  int flags = 0;
1241
1242
1.14k
  if (pass == 1) {
1243
3.43k
    for (i = 0; i < 2; i++) {
1244
5.14k
      while ((id = queue_remove(id_queue))) {
1245
2.85k
        free(id);
1246
2.85k
      }
1247
2.28k
    }
1248
1.14k
    return 0;
1249
1.14k
  }
1250
1251
1
  ebitmap_init(&attrs);
1252
1
  while ((id = queue_remove(id_queue))) {
1253
1
    if (!is_id_in_scope(SYM_TYPES, id)) {
1254
0
      yyerror2("attribute %s is not within scope", id);
1255
0
      goto exit;
1256
0
    }
1257
1258
1
    attr = hashtab_search(policydbp->p_types.table, id);
1259
1
    if (!attr) {
1260
1
      yyerror2("attribute %s is not declared", id);
1261
1
      goto exit;
1262
1
    }
1263
1264
0
    if (attr->flavor != TYPE_ATTRIB) {
1265
0
      yyerror2("%s is a type, not an attribute", id);
1266
0
      goto exit;
1267
0
    }
1268
1269
0
    if (ebitmap_set_bit(&attrs, attr->s.value - 1, TRUE)) {
1270
0
      yyerror("Out of memory!");
1271
0
      goto exit;
1272
0
    }
1273
1274
0
    free(id);
1275
0
  }
1276
1277
0
  id = (char *)queue_remove(id_queue);
1278
0
  if (!id) {
1279
0
    yyerror("No option specified for attribute expansion.");
1280
0
    goto exit;
1281
0
  }
1282
1283
0
  if (!strcmp(id, "T")) {
1284
0
    flags = TYPE_FLAGS_EXPAND_ATTR_TRUE;
1285
0
  } else {
1286
0
    flags = TYPE_FLAGS_EXPAND_ATTR_FALSE;
1287
0
  }
1288
1289
0
  ebitmap_for_each_positive_bit(&attrs, node, i) {
1290
0
    name = policydbp->sym_val_to_name[SYM_TYPES][i];
1291
0
    attr = hashtab_search(policydbp->p_types.table, name);
1292
0
    attr->flags |= flags;
1293
0
    if ((attr->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE) &&
1294
0
        (attr->flags & TYPE_FLAGS_EXPAND_ATTR_FALSE)) {
1295
0
      yywarn2("Expandattribute option of attribute %s was set to both true and false; "
1296
0
        "Resolving to false.",
1297
0
        name);
1298
0
      attr->flags &= ~TYPE_FLAGS_EXPAND_ATTR_TRUE;
1299
0
    }
1300
0
  }
1301
1302
0
  rc = 0;
1303
1
exit:
1304
1
  ebitmap_destroy(&attrs);
1305
1
  free(id);
1306
1
  return rc;
1307
0
}
1308
1309
static int add_aliases_to_type(type_datum_t *type)
1310
178
{
1311
178
  char *id;
1312
178
  type_datum_t *aliasdatum = NULL;
1313
178
  int ret;
1314
849
  while ((id = queue_remove(id_queue))) {
1315
678
    if (id_has_dot(id)) {
1316
2
      yyerror2(
1317
2
        "type alias identifier %s may not contain periods",
1318
2
        id);
1319
2
      free(id);
1320
2
      return -1;
1321
2
    }
1322
676
    aliasdatum = calloc(1, sizeof(type_datum_t));
1323
676
    if (!aliasdatum) {
1324
0
      free(id);
1325
0
      yyerror("Out of memory!");
1326
0
      return -1;
1327
0
    }
1328
676
    aliasdatum->s.value = type->s.value;
1329
1330
676
    ret = declare_symbol(SYM_TYPES, id, aliasdatum, NULL,
1331
676
             &aliasdatum->s.value);
1332
676
    switch (ret) {
1333
0
    case -3: {
1334
0
      yyerror("Out of memory!");
1335
0
      goto cleanup;
1336
0
    }
1337
4
    case -2: {
1338
4
      yyerror2("duplicate declaration of alias %s", id);
1339
4
      goto cleanup;
1340
0
    }
1341
1
    case -1: {
1342
1
      yyerror2("could not declare alias %s here", id);
1343
1
      goto cleanup;
1344
0
    }
1345
661
    case 0:
1346
661
      break;
1347
10
    case 1: {
1348
      /* ret == 1 means the alias was required and therefore already
1349
         * has a value. Set it up as an alias with a different primary. */
1350
10
      type_datum_destroy(aliasdatum);
1351
10
      free(aliasdatum);
1352
1353
10
      aliasdatum = hashtab_search(
1354
10
        policydbp->symtab[SYM_TYPES].table, id);
1355
10
      assert(aliasdatum);
1356
1357
10
      aliasdatum->primary = type->s.value;
1358
10
      aliasdatum->flavor = TYPE_ALIAS;
1359
1360
10
      free(id);
1361
10
      break;
1362
10
    }
1363
0
    default: {
1364
0
      assert(0); /* should never get here */
1365
0
    }
1366
676
    }
1367
676
  }
1368
171
  return 0;
1369
5
cleanup:
1370
5
  free(id);
1371
5
  type_datum_destroy(aliasdatum);
1372
5
  free(aliasdatum);
1373
5
  return -1;
1374
178
}
1375
1376
int define_typealias(void)
1377
150
{
1378
150
  char *id;
1379
150
  type_datum_t *t;
1380
1381
150
  if (pass == 2) {
1382
271
    while ((id = queue_remove(id_queue)))
1383
208
      free(id);
1384
63
    return 0;
1385
63
  }
1386
1387
87
  id = (char *)queue_remove(id_queue);
1388
87
  if (!id) {
1389
1
    yyerror("no type name for typealias definition?");
1390
1
    return -1;
1391
1
  }
1392
1393
86
  if (!is_id_in_scope(SYM_TYPES, id)) {
1394
1
    yyerror2("type %s is not within scope", id);
1395
1
    free(id);
1396
1
    return -1;
1397
1
  }
1398
85
  t = hashtab_search(policydbp->p_types.table, id);
1399
85
  if (!t || t->flavor == TYPE_ATTRIB) {
1400
2
    yyerror2("unknown type %s, or it was already declared as an "
1401
2
       "attribute",
1402
2
       id);
1403
2
    free(id);
1404
2
    return -1;
1405
2
  }
1406
83
  free(id);
1407
83
  return add_aliases_to_type(t);
1408
85
}
1409
1410
int define_typeattribute(void)
1411
250
{
1412
250
  char *id;
1413
250
  type_datum_t *t, *attr;
1414
1415
250
  if (pass == 2) {
1416
198
    while ((id = queue_remove(id_queue)))
1417
132
      free(id);
1418
66
    return 0;
1419
66
  }
1420
1421
184
  id = (char *)queue_remove(id_queue);
1422
184
  if (!id) {
1423
1
    yyerror("no type name for typeattribute definition?");
1424
1
    return -1;
1425
1
  }
1426
1427
183
  if (!is_id_in_scope(SYM_TYPES, id)) {
1428
2
    yyerror2("type %s is not within scope", id);
1429
2
    free(id);
1430
2
    return -1;
1431
2
  }
1432
181
  t = hashtab_search(policydbp->p_types.table, id);
1433
181
  if (!t) {
1434
1
    yyerror2("unknown type %s", id);
1435
1
    free(id);
1436
1
    return -1;
1437
180
  } else if (t->flavor == TYPE_ATTRIB) {
1438
109
    if (policydbp->policy_type != POLICY_KERN &&
1439
109
        policydbp->policyvers <
1440
109
          MOD_POLICYDB_VERSION_TYPE_ATTR_ATTRS) {
1441
0
      yyerror2(
1442
0
        "Type attributes cannot be used in a typeattribute definition in policy version %d",
1443
0
        policydbp->policyvers);
1444
0
      free(id);
1445
0
      return -1;
1446
0
    }
1447
109
  }
1448
1449
180
  free(id);
1450
1451
539
  while ((id = queue_remove(id_queue))) {
1452
367
    if (!is_id_in_scope(SYM_TYPES, id)) {
1453
2
      yyerror2("attribute %s is not within scope", id);
1454
2
      free(id);
1455
2
      return -1;
1456
2
    }
1457
365
    attr = hashtab_search(policydbp->p_types.table, id);
1458
365
    if (!attr) {
1459
      /* treat it as a fatal error */
1460
5
      yyerror2("attribute %s is not declared", id);
1461
5
      free(id);
1462
5
      return -1;
1463
5
    }
1464
1465
360
    if (attr->flavor != TYPE_ATTRIB) {
1466
1
      yyerror2("%s is a type, not an attribute", id);
1467
1
      free(id);
1468
1
      return -1;
1469
1
    }
1470
1471
359
    if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1472
0
      yyerror("Out of memory!");
1473
0
      return -1;
1474
0
    }
1475
1476
359
    if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1477
0
      yyerror("out of memory");
1478
0
      return -1;
1479
0
    }
1480
359
  }
1481
1482
172
  return 0;
1483
180
}
1484
1485
static int define_typebounds_helper(const char *bounds_id, const char *type_id)
1486
2.44k
{
1487
2.44k
  type_datum_t *bounds, *type;
1488
2.44k
  char *id;
1489
2.44k
  uint32_t value;
1490
1491
2.44k
  if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
1492
5
    yyerror2("type %s is not within scope", bounds_id);
1493
5
    return -1;
1494
5
  }
1495
1496
2.43k
  bounds = hashtab_search(policydbp->p_types.table, bounds_id);
1497
2.43k
  if (!bounds || bounds->flavor == TYPE_ATTRIB) {
1498
4
    yyerror2("type %s is not declared", bounds_id);
1499
4
    return -1;
1500
4
  }
1501
1502
2.43k
  if (!is_id_in_scope(SYM_TYPES, type_id)) {
1503
3
    yyerror2("type %s is not within scope", type_id);
1504
3
    return -1;
1505
3
  }
1506
1507
2.42k
  type = hashtab_search(policydbp->p_types.table, type_id);
1508
2.42k
  if (!type || type->flavor == TYPE_ATTRIB) {
1509
8
    yyerror2("type %s is not declared", type_id);
1510
8
    return -1;
1511
8
  }
1512
1513
2.42k
  id = strdup(type_id);
1514
2.42k
  if (!id) {
1515
0
    yyerror("Out of memory!");
1516
0
    return -1;
1517
0
  }
1518
2.42k
  value = (type->flavor != TYPE_ALIAS) ? type->s.value : type->primary;
1519
2.42k
  type = get_local_type(id, value, 0);
1520
2.42k
  if (!type) {
1521
0
    yyerror("Out of memory!");
1522
0
    return -1;
1523
0
  }
1524
1525
2.42k
  if (!type->bounds)
1526
2.15k
    type->bounds = bounds->s.value;
1527
264
  else if (type->bounds != bounds->s.value) {
1528
0
    yyerror2("type %s has inconsistent bounds %s/%s", type_id,
1529
0
       policydbp->p_type_val_to_name[type->bounds - 1],
1530
0
       policydbp->p_type_val_to_name[bounds->s.value - 1]);
1531
0
    return -1;
1532
0
  }
1533
1534
2.42k
  return 0;
1535
2.42k
}
1536
1537
int define_typebounds(void)
1538
1.01k
{
1539
1.01k
  char *bounds, *id;
1540
1541
1.01k
  if (pass == 1) {
1542
5.15k
    while ((id = queue_remove(id_queue)))
1543
4.37k
      free(id);
1544
777
    return 0;
1545
777
  }
1546
1547
238
  bounds = (char *)queue_remove(id_queue);
1548
238
  if (!bounds) {
1549
0
    yyerror("no type name for typebounds definition?");
1550
0
    return -1;
1551
0
  }
1552
1553
2.54k
  while ((id = queue_remove(id_queue))) {
1554
2.32k
    if (define_typebounds_helper(bounds, id)) {
1555
18
      free(bounds);
1556
18
      free(id);
1557
18
      return -1;
1558
18
    }
1559
1560
2.30k
    free(id);
1561
2.30k
  }
1562
220
  free(bounds);
1563
1564
220
  return 0;
1565
238
}
1566
1567
int define_type(int alias)
1568
10.5k
{
1569
10.5k
  char *id;
1570
10.5k
  type_datum_t *datum, *attr;
1571
1572
10.5k
  if (pass == 2) {
1573
    /*
1574
     * If type name contains ".", we have to define boundary
1575
     * relationship implicitly to keep compatibility with
1576
     * old name based hierarchy.
1577
     */
1578
5.06k
    if ((id = queue_remove(id_queue))) {
1579
5.06k
      const char *delim;
1580
1581
5.06k
      if ((delim = strrchr(id, '.'))) {
1582
118
        int ret;
1583
118
        char *bounds = strdup(id);
1584
118
        if (!bounds) {
1585
0
          yyerror("out of memory");
1586
0
          free(id);
1587
0
          return -1;
1588
0
        }
1589
1590
118
        bounds[(size_t)(delim - id)] = '\0';
1591
1592
118
        ret = define_typebounds_helper(bounds, id);
1593
118
        free(bounds);
1594
118
        if (ret) {
1595
2
          free(id);
1596
2
          return -1;
1597
2
        }
1598
118
      }
1599
5.06k
      free(id);
1600
5.06k
    }
1601
1602
5.06k
    if (alias) {
1603
392
      while ((id = queue_remove(id_queue)))
1604
327
        free(id);
1605
65
    }
1606
1607
5.38k
    while ((id = queue_remove(id_queue)))
1608
324
      free(id);
1609
5.06k
    return 0;
1610
5.06k
  }
1611
1612
5.48k
  if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1613
2
    return -1;
1614
2
  }
1615
1616
5.48k
  if (alias) {
1617
95
    if (add_aliases_to_type(datum) == -1) {
1618
5
      return -1;
1619
5
    }
1620
95
  }
1621
1622
6.26k
  while ((id = queue_remove(id_queue))) {
1623
793
    if (!is_id_in_scope(SYM_TYPES, id)) {
1624
1
      yyerror2("attribute %s is not within scope", id);
1625
1
      free(id);
1626
1
      return -1;
1627
1
    }
1628
792
    attr = hashtab_search(policydbp->p_types.table, id);
1629
792
    if (!attr) {
1630
      /* treat it as a fatal error */
1631
6
      yyerror2("attribute %s is not declared", id);
1632
6
      free(id);
1633
6
      return -1;
1634
6
    }
1635
1636
786
    if (attr->flavor != TYPE_ATTRIB) {
1637
2
      yyerror2("%s is a type, not an attribute", id);
1638
2
      free(id);
1639
2
      return -1;
1640
2
    }
1641
1642
784
    if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1643
0
      yyerror("Out of memory!");
1644
0
      return -1;
1645
0
    }
1646
1647
784
    if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1648
0
      yyerror("Out of memory");
1649
0
      return -1;
1650
0
    }
1651
784
  }
1652
1653
5.46k
  return 0;
1654
5.47k
}
1655
1656
struct val_to_name {
1657
  unsigned int val;
1658
  char *name;
1659
};
1660
1661
/* Adds a type, given by its textual name, to a typeset.  If *add is
1662
   0, then add the type to the negative set; otherwise if *add is 1
1663
   then add it to the positive side.
1664
   The identifier `id` is always consumed. */
1665
static int set_types(type_set_t *set, char *id, int *add, char starallowed)
1666
96.1k
{
1667
96.1k
  type_datum_t *t;
1668
1669
96.1k
  if (strcmp(id, "*") == 0) {
1670
3.56k
    free(id);
1671
3.56k
    if (!starallowed) {
1672
1
      yyerror("* not allowed in this type of rule");
1673
1
      return -1;
1674
1
    }
1675
    /* set TYPE_STAR flag */
1676
3.56k
    set->flags = TYPE_STAR;
1677
3.56k
    *add = 1;
1678
3.56k
    return 0;
1679
3.56k
  }
1680
1681
92.5k
  if (strcmp(id, "~") == 0) {
1682
3.81k
    free(id);
1683
3.81k
    if (!starallowed) {
1684
5
      yyerror("~ not allowed in this type of rule");
1685
5
      return -1;
1686
5
    }
1687
    /* complement the set */
1688
3.81k
    set->flags = TYPE_COMP;
1689
3.81k
    *add = 1;
1690
3.81k
    return 0;
1691
3.81k
  }
1692
1693
88.7k
  if (strcmp(id, "-") == 0) {
1694
12.1k
    *add = 0;
1695
12.1k
    free(id);
1696
12.1k
    return 0;
1697
12.1k
  }
1698
1699
76.5k
  if (!is_id_in_scope(SYM_TYPES, id)) {
1700
16
    yyerror2("type %s is not within scope", id);
1701
16
    free(id);
1702
16
    return -1;
1703
16
  }
1704
76.5k
  t = hashtab_search(policydbp->p_types.table, id);
1705
76.5k
  if (!t) {
1706
335
    yyerror2("unknown type %s", id);
1707
335
    free(id);
1708
335
    return -1;
1709
335
  }
1710
1711
76.2k
  if (*add == 0) {
1712
12.1k
    if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
1713
0
      goto oom;
1714
64.0k
  } else {
1715
64.0k
    if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
1716
0
      goto oom;
1717
64.0k
  }
1718
76.2k
  free(id);
1719
76.2k
  *add = 1;
1720
76.2k
  return 0;
1721
0
oom:
1722
0
  yyerror("Out of memory");
1723
0
  free(id);
1724
0
  return -1;
1725
76.2k
}
1726
1727
static int define_compute_type_helper(int which, avrule_t **rule)
1728
1.55k
{
1729
1.55k
  char *id;
1730
1.55k
  type_datum_t *datum;
1731
1.55k
  ebitmap_t tclasses;
1732
1.55k
  ebitmap_node_t *node;
1733
1.55k
  avrule_t *avrule;
1734
1.55k
  class_perm_node_t *perm;
1735
1.55k
  uint32_t i;
1736
1.55k
  int add = 1;
1737
1738
1.55k
  avrule = malloc(sizeof(avrule_t));
1739
1.55k
  if (!avrule) {
1740
0
    yyerror("out of memory");
1741
0
    return -1;
1742
0
  }
1743
1.55k
  avrule_init(avrule);
1744
1.55k
  avrule->specified = which;
1745
1.55k
  avrule->line = policydb_lineno;
1746
1.55k
  avrule->source_line = source_lineno;
1747
1.55k
  avrule->source_filename = strdup(source_file);
1748
1.55k
  if (!avrule->source_filename) {
1749
0
    yyerror("out of memory");
1750
0
    return -1;
1751
0
  }
1752
1753
1.55k
  ebitmap_init(&tclasses);
1754
1755
3.08k
  while ((id = queue_remove(id_queue))) {
1756
1.55k
    if (set_types(&avrule->stypes, id, &add, 0))
1757
17
      goto bad;
1758
1.55k
  }
1759
1.53k
  add = 1;
1760
4.69k
  while ((id = queue_remove(id_queue))) {
1761
3.20k
    if (strcmp(id, "self") == 0) {
1762
101
      free(id);
1763
101
      if (add == 0) {
1764
1
        yyerror("-self is not supported");
1765
1
        goto bad;
1766
1
      }
1767
100
      avrule->flags |= RULE_SELF;
1768
100
      continue;
1769
101
    }
1770
3.10k
    if (set_types(&avrule->ttypes, id, &add, 0))
1771
44
      goto bad;
1772
3.10k
  }
1773
1774
1.48k
  if (read_classes(&tclasses))
1775
6
    goto bad;
1776
1777
1.48k
  id = (char *)queue_remove(id_queue);
1778
1.48k
  if (!id) {
1779
0
    yyerror("no newtype?");
1780
0
    goto bad;
1781
0
  }
1782
1.48k
  if (!is_id_in_scope(SYM_TYPES, id)) {
1783
1
    yyerror2("type %s is not within scope", id);
1784
1
    free(id);
1785
1
    goto bad;
1786
1
  }
1787
1.48k
  datum = (type_datum_t *)hashtab_search(policydbp->p_types.table,
1788
1.48k
                 (hashtab_key_t)id);
1789
1.48k
  if (!datum || datum->flavor == TYPE_ATTRIB) {
1790
17
    yyerror2("unknown type %s", id);
1791
17
    free(id);
1792
17
    goto bad;
1793
17
  }
1794
1.46k
  free(id);
1795
1796
93.6k
  ebitmap_for_each_positive_bit(&tclasses, node, i) {
1797
1.46k
    perm = malloc(sizeof(class_perm_node_t));
1798
1.46k
    if (!perm) {
1799
0
      yyerror("out of memory");
1800
0
      goto bad;
1801
0
    }
1802
1.46k
    class_perm_node_init(perm);
1803
1.46k
    perm->tclass = i + 1;
1804
1.46k
    perm->data = datum->s.value;
1805
1.46k
    perm->next = avrule->perms;
1806
1.46k
    avrule->perms = perm;
1807
1.46k
  }
1808
1.46k
  ebitmap_destroy(&tclasses);
1809
1810
1.46k
  *rule = avrule;
1811
1.46k
  return 0;
1812
1813
86
bad:
1814
86
  ebitmap_destroy(&tclasses);
1815
86
  avrule_destroy(avrule);
1816
86
  free(avrule);
1817
86
  return -1;
1818
1.46k
}
1819
1820
int define_compute_type(int which)
1821
6.35k
{
1822
6.35k
  char *id;
1823
6.35k
  avrule_t *avrule;
1824
1825
6.35k
  if (pass == 1) {
1826
9.70k
    while ((id = queue_remove(id_queue)))
1827
4.90k
      free(id);
1828
12.4k
    while ((id = queue_remove(id_queue)))
1829
7.66k
      free(id);
1830
10.9k
    while ((id = queue_remove(id_queue)))
1831
6.18k
      free(id);
1832
4.80k
    id = queue_remove(id_queue);
1833
4.80k
    free(id);
1834
4.80k
    return 0;
1835
4.80k
  }
1836
1837
1.54k
  if (define_compute_type_helper(which, &avrule))
1838
84
    return -1;
1839
1840
1.46k
  append_avrule(avrule);
1841
1.46k
  return 0;
1842
1.54k
}
1843
1844
avrule_t *define_cond_compute_type(int which)
1845
2.99k
{
1846
2.99k
  char *id;
1847
2.99k
  avrule_t *avrule;
1848
1849
2.99k
  if (pass == 1) {
1850
5.70k
    while ((id = queue_remove(id_queue)))
1851
2.71k
      free(id);
1852
7.44k
    while ((id = queue_remove(id_queue)))
1853
4.45k
      free(id);
1854
7.14k
    while ((id = queue_remove(id_queue)))
1855
4.15k
      free(id);
1856
2.98k
    id = queue_remove(id_queue);
1857
2.98k
    free(id);
1858
2.98k
    return (avrule_t *)1;
1859
2.98k
  }
1860
1861
2
  if (define_compute_type_helper(which, &avrule))
1862
2
    return COND_ERR;
1863
1864
0
  return avrule;
1865
2
}
1866
1867
int define_bool_tunable(int is_tunable)
1868
96
{
1869
96
  char *id, *bool_value;
1870
96
  cond_bool_datum_t *datum;
1871
96
  int ret;
1872
96
  uint32_t value;
1873
1874
96
  if (pass == 2) {
1875
93
    while ((id = queue_remove(id_queue)))
1876
62
      free(id);
1877
31
    return 0;
1878
31
  }
1879
1880
65
  id = (char *)queue_remove(id_queue);
1881
65
  if (!id) {
1882
2
    yyerror("no identifier for bool definition?");
1883
2
    return -1;
1884
2
  }
1885
63
  if (id_has_dot(id)) {
1886
1
    yyerror2("boolean identifier %s may not contain periods", id);
1887
1
    free(id);
1888
1
    return -1;
1889
1
  }
1890
62
  datum = calloc(1, sizeof(cond_bool_datum_t));
1891
62
  if (!datum) {
1892
0
    yyerror("out of memory");
1893
0
    free(id);
1894
0
    return -1;
1895
0
  }
1896
62
  if (is_tunable)
1897
21
    datum->flags |= COND_BOOL_FLAGS_TUNABLE;
1898
62
  ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1899
62
  switch (ret) {
1900
0
  case -3: {
1901
0
    yyerror("Out of memory!");
1902
0
    goto cleanup;
1903
0
  }
1904
1
  case -2: {
1905
1
    yyerror2("duplicate declaration of boolean %s", id);
1906
1
    goto cleanup;
1907
0
  }
1908
1
  case -1: {
1909
1
    yyerror2("could not declare boolean %s here", id);
1910
1
    goto cleanup;
1911
0
  }
1912
57
  case 0: {
1913
57
    break;
1914
0
  }
1915
3
  case 1: {
1916
3
    goto cleanup;
1917
0
  }
1918
0
  default: {
1919
0
    assert(0); /* should never get here */
1920
0
  }
1921
62
  }
1922
57
  datum->s.value = value;
1923
1924
57
  bool_value = (char *)queue_remove(id_queue);
1925
57
  if (!bool_value) {
1926
1
    yyerror("no default value for bool definition?");
1927
1
    return -1;
1928
1
  }
1929
1930
56
  datum->state = (bool_value[0] == 'T') ? 1 : 0;
1931
56
  free(bool_value);
1932
56
  return 0;
1933
5
cleanup:
1934
5
  cond_destroy_bool(id, datum, NULL);
1935
5
  return ret == 1 ? 0 : -1;
1936
57
}
1937
1938
avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *sl)
1939
26.2k
{
1940
26.2k
  avrule_t *last;
1941
1942
26.2k
  if (pass == 1) {
1943
    /* return something so we get through pass 1 */
1944
17.4k
    return (avrule_t *)1;
1945
17.4k
  }
1946
1947
8.84k
  if (sl == NULL) {
1948
    /* This is a require block, return previous list */
1949
719
    return avlist;
1950
719
  }
1951
1952
  /* Prepend the new avlist to the pre-existing one.
1953
   * An extended permission statement might consist of multiple av
1954
   * rules. */
1955
10.6k
  for (last = sl; last->next; last = last->next)
1956
2.54k
    ;
1957
8.13k
  last->next = avlist;
1958
8.13k
  return sl;
1959
8.84k
}
1960
1961
typedef struct av_xperm_range {
1962
  uint16_t low;
1963
  uint16_t high;
1964
} av_xperm_range_t;
1965
1966
struct av_xperm_range_list {
1967
  uint8_t omit;
1968
  av_xperm_range_t range;
1969
  struct av_xperm_range_list *next;
1970
};
1971
1972
static int avrule_sort_xperms(struct av_xperm_range_list **rangehead)
1973
8.69k
{
1974
8.69k
  struct av_xperm_range_list *r, *r2, *sorted, *sortedhead = NULL;
1975
1976
  /* order list by range.low */
1977
17.3k
  for (r = *rangehead; r != NULL; r = r->next) {
1978
8.69k
    sorted = malloc(sizeof(struct av_xperm_range_list));
1979
8.69k
    if (sorted == NULL)
1980
0
      goto error;
1981
8.69k
    memcpy(sorted, r, sizeof(struct av_xperm_range_list));
1982
8.69k
    sorted->next = NULL;
1983
8.69k
    if (sortedhead == NULL) {
1984
8.69k
      sortedhead = sorted;
1985
8.69k
      continue;
1986
8.69k
    }
1987
0
    for (r2 = sortedhead; r2 != NULL; r2 = r2->next) {
1988
0
      if (sorted->range.low < r2->range.low) {
1989
        /* range is the new head */
1990
0
        sorted->next = r2;
1991
0
        sortedhead = sorted;
1992
0
        break;
1993
0
      } else if ((r2->next != NULL) &&
1994
0
           (r->range.low < r2->next->range.low)) {
1995
        /* insert range between elements */
1996
0
        sorted->next = r2->next;
1997
0
        r2->next = sorted;
1998
0
        break;
1999
0
      } else if (r2->next == NULL) {
2000
        /* range is the new tail*/
2001
0
        r2->next = sorted;
2002
0
        break;
2003
0
      }
2004
0
    }
2005
0
  }
2006
2007
8.69k
  r = *rangehead;
2008
17.3k
  while (r != NULL) {
2009
8.69k
    r2 = r;
2010
8.69k
    r = r->next;
2011
8.69k
    free(r2);
2012
8.69k
  }
2013
8.69k
  *rangehead = sortedhead;
2014
8.69k
  return 0;
2015
0
error:
2016
0
  yyerror("out of memory");
2017
0
  return -1;
2018
8.69k
}
2019
2020
static void avrule_merge_xperms(struct av_xperm_range_list **rangehead)
2021
8.69k
{
2022
8.69k
  struct av_xperm_range_list *r, *tmp;
2023
8.69k
  r = *rangehead;
2024
8.69k
  while (r != NULL && r->next != NULL) {
2025
    /* merge */
2026
0
    if ((r->range.high + 1) >= r->next->range.low) {
2027
      /* keep the higher of the two */
2028
0
      if (r->range.high < r->next->range.high)
2029
0
        r->range.high = r->next->range.high;
2030
0
      tmp = r->next;
2031
0
      r->next = r->next->next;
2032
0
      free(tmp);
2033
0
      continue;
2034
0
    }
2035
0
    r = r->next;
2036
0
  }
2037
8.69k
}
2038
2039
static int avrule_read_xperm_value(const char *id, uint16_t *value)
2040
8.71k
{
2041
8.71k
  unsigned long val = strtoul(id, NULL, 0);
2042
2043
8.71k
  if (val > UINT16_MAX) {
2044
20
    yyerror2(
2045
20
      "extended permission value 0x%lx exceeds the maximum of 0x%x",
2046
20
      val, UINT16_MAX);
2047
20
    return -1;
2048
20
  }
2049
8.69k
  *value = (uint16_t)val;
2050
8.69k
  return 0;
2051
8.71k
}
2052
2053
static int avrule_read_xperm_ranges(struct av_xperm_range_list **rangehead)
2054
8.71k
{
2055
8.71k
  char *id;
2056
8.71k
  struct av_xperm_range_list *rnew, *r = NULL;
2057
8.71k
  uint8_t omit = 0;
2058
2059
8.71k
  *rangehead = NULL;
2060
2061
  /* read in all the ioctl/netlink commands */
2062
21.2k
  while ((id = queue_remove(id_queue))) {
2063
12.5k
    if (strcmp(id, "~") == 0) {
2064
      /* these are values to be omitted */
2065
3.80k
      free(id);
2066
3.80k
      omit = 1;
2067
8.71k
    } else if (strcmp(id, "-") == 0) {
2068
      /* high value of range */
2069
0
      free(id);
2070
0
      id = queue_remove(id_queue);
2071
0
      if (avrule_read_xperm_value(id, &r->range.high)) {
2072
0
        free(id);
2073
0
        return -1;
2074
0
      }
2075
0
      if (r->range.high < r->range.low) {
2076
0
        yyerror2(
2077
0
          "extended permission range %#x-%#x must be in ascending order.",
2078
0
          r->range.low, r->range.high);
2079
0
        return -1;
2080
0
      }
2081
0
      free(id);
2082
8.71k
    } else {
2083
      /* read in new low value */
2084
8.71k
      rnew = malloc(sizeof(struct av_xperm_range_list));
2085
8.71k
      if (rnew == NULL)
2086
0
        goto error;
2087
8.71k
      rnew->next = NULL;
2088
8.71k
      if (*rangehead == NULL) {
2089
8.71k
        *rangehead = rnew;
2090
8.71k
        r = *rangehead;
2091
8.71k
      } else {
2092
0
        r->next = rnew;
2093
0
        r = r->next;
2094
0
      }
2095
8.71k
      if (avrule_read_xperm_value(id, &rnew->range.low)) {
2096
20
        free(id);
2097
20
        return -1;
2098
20
      }
2099
8.69k
      rnew->range.high = rnew->range.low;
2100
8.69k
      free(id);
2101
8.69k
    }
2102
12.5k
  }
2103
8.69k
  r = *rangehead;
2104
8.69k
  if (r) {
2105
8.69k
    r->omit = omit;
2106
8.69k
  }
2107
8.69k
  return 0;
2108
0
error:
2109
0
  yyerror("out of memory");
2110
0
  return -1;
2111
8.71k
}
2112
2113
/* flip to included ranges */
2114
static int avrule_omit_xperms(struct av_xperm_range_list **rangehead)
2115
3.80k
{
2116
3.80k
  struct av_xperm_range_list *rnew, *r, *newhead = NULL, *tail = NULL;
2117
3.80k
  uint32_t next_low = 0;
2118
2119
  /*
2120
   * The input ranges are sorted and merged. Emit the gaps between them
2121
   * as the complement. next_low is the first value not yet covered by an
2122
   * emitted (allowed) range; promote it to uint32_t so that high + 1 does
2123
   * not wrap when a range ends at 0xffff.
2124
   */
2125
7.61k
  for (r = *rangehead; r != NULL; r = r->next) {
2126
3.80k
    if (r->range.low > next_low) {
2127
3.32k
      rnew = calloc(1, sizeof(struct av_xperm_range_list));
2128
3.32k
      if (!rnew)
2129
0
        goto error;
2130
3.32k
      rnew->range.low = next_low;
2131
3.32k
      rnew->range.high = r->range.low - 1;
2132
3.32k
      if (tail)
2133
0
        tail->next = rnew;
2134
3.32k
      else
2135
3.32k
        newhead = rnew;
2136
3.32k
      tail = rnew;
2137
3.32k
    }
2138
3.80k
    next_low = (uint32_t)r->range.high + 1;
2139
3.80k
  }
2140
2141
3.80k
  if (next_low <= UINT16_MAX) {
2142
3.56k
    rnew = calloc(1, sizeof(struct av_xperm_range_list));
2143
3.56k
    if (!rnew)
2144
0
      goto error;
2145
3.56k
    rnew->range.low = next_low;
2146
3.56k
    rnew->range.high = UINT16_MAX;
2147
3.56k
    if (tail)
2148
3.07k
      tail->next = rnew;
2149
487
    else
2150
487
      newhead = rnew;
2151
3.56k
    tail = rnew;
2152
3.56k
  }
2153
2154
3.80k
  r = *rangehead;
2155
7.61k
  while (r != NULL) {
2156
3.80k
    rnew = r;
2157
3.80k
    r = r->next;
2158
3.80k
    free(rnew);
2159
3.80k
  }
2160
3.80k
  *rangehead = newhead;
2161
3.80k
  return 0;
2162
2163
0
error:
2164
0
  while (newhead != NULL) {
2165
0
    rnew = newhead;
2166
0
    newhead = newhead->next;
2167
0
    free(rnew);
2168
0
  }
2169
0
  yyerror("out of memory");
2170
0
  return -1;
2171
3.80k
}
2172
2173
static int avrule_xperm_ranges(struct av_xperm_range_list **rangelist)
2174
8.71k
{
2175
8.71k
  struct av_xperm_range_list *rangehead;
2176
8.71k
  uint8_t omit;
2177
2178
  /* read in ranges to include and omit */
2179
8.71k
  if (avrule_read_xperm_ranges(&rangehead))
2180
20
    return -1;
2181
8.69k
  if (rangehead == NULL) {
2182
0
    yyerror("error processing ioctl/netlink commands");
2183
0
    return -1;
2184
0
  }
2185
8.69k
  omit = rangehead->omit;
2186
  /* sort and merge the input ranges */
2187
8.69k
  if (avrule_sort_xperms(&rangehead))
2188
0
    return -1;
2189
8.69k
  avrule_merge_xperms(&rangehead);
2190
  /* flip ranges if these are omitted */
2191
8.69k
  if (omit) {
2192
3.80k
    if (avrule_omit_xperms(&rangehead))
2193
0
      return -1;
2194
3.80k
  }
2195
2196
8.69k
  *rangelist = rangehead;
2197
8.69k
  return 0;
2198
8.69k
}
2199
2200
static int define_te_avtab_xperms_helper(int which, avrule_t **rule)
2201
8.98k
{
2202
8.98k
  char *id;
2203
8.98k
  class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2204
8.98k
  const class_datum_t *cladatum;
2205
8.98k
  const perm_datum_t *perdatum;
2206
8.98k
  ebitmap_t tclasses;
2207
8.98k
  ebitmap_node_t *node;
2208
8.98k
  avrule_t *avrule;
2209
8.98k
  unsigned int i;
2210
8.98k
  int add = 1, ret;
2211
2212
8.98k
  avrule = malloc(sizeof(avrule_t));
2213
8.98k
  if (!avrule) {
2214
0
    yyerror("out of memory");
2215
0
    goto out;
2216
0
  }
2217
8.98k
  avrule_init(avrule);
2218
8.98k
  avrule->specified = which;
2219
8.98k
  avrule->line = policydb_lineno;
2220
8.98k
  avrule->source_line = source_lineno;
2221
8.98k
  avrule->source_filename = strdup(source_file);
2222
8.98k
  avrule->xperms = NULL;
2223
8.98k
  if (!avrule->source_filename) {
2224
0
    yyerror("out of memory");
2225
0
    goto out;
2226
0
  }
2227
2228
17.9k
  while ((id = queue_remove(id_queue))) {
2229
8.99k
    if (set_types(&avrule->stypes, id, &add,
2230
8.99k
            which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
2231
28
      goto out;
2232
28
    }
2233
8.99k
  }
2234
8.95k
  add = 1;
2235
17.8k
  while ((id = queue_remove(id_queue))) {
2236
8.95k
    if (strcmp(id, "self") == 0) {
2237
2.11k
      free(id);
2238
2.11k
      if (add == 0 && which != AVRULE_XPERMS_NEVERALLOW) {
2239
0
        yyerror("-self is only supported in neverallow and neverallowxperm rules");
2240
0
        goto out;
2241
0
      }
2242
2.11k
      avrule->flags |= (add ? RULE_SELF : RULE_NOTSELF);
2243
2.11k
      if ((avrule->flags & RULE_SELF) &&
2244
2.11k
          (avrule->flags & RULE_NOTSELF)) {
2245
0
        yyerror("self and -self are mutual exclusive");
2246
0
        goto out;
2247
0
      }
2248
2.11k
      continue;
2249
2.11k
    }
2250
6.84k
    if (set_types(&avrule->ttypes, id, &add,
2251
6.84k
            which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
2252
34
      goto out;
2253
34
    }
2254
6.84k
  }
2255
2256
8.91k
  if ((avrule->ttypes.flags & TYPE_COMP)) {
2257
0
    if (avrule->flags & RULE_NOTSELF) {
2258
0
      yyerror("-self is not supported in complements");
2259
0
      goto out;
2260
0
    }
2261
0
    if (avrule->flags & RULE_SELF) {
2262
0
      avrule->flags &= ~RULE_SELF;
2263
0
      avrule->flags |= RULE_NOTSELF;
2264
0
    }
2265
0
  }
2266
2267
8.91k
  ebitmap_init(&tclasses);
2268
8.91k
  ret = read_classes(&tclasses);
2269
8.91k
  if (ret)
2270
11
    goto out2;
2271
2272
8.90k
  perms = NULL;
2273
8.90k
  id = queue_head(id_queue);
2274
570k
  ebitmap_for_each_positive_bit(&tclasses, node, i) {
2275
8.90k
    cur_perms = malloc(sizeof(class_perm_node_t));
2276
8.90k
    if (!cur_perms) {
2277
0
      yyerror("out of memory");
2278
0
      goto out2;
2279
0
    }
2280
8.90k
    class_perm_node_init(cur_perms);
2281
8.90k
    cur_perms->tclass = i + 1;
2282
8.90k
    if (!perms)
2283
8.90k
      perms = cur_perms;
2284
8.90k
    if (tail)
2285
0
      tail->next = cur_perms;
2286
8.90k
    tail = cur_perms;
2287
2288
8.90k
    cladatum = policydbp->class_val_to_struct[i];
2289
8.90k
    perdatum = hashtab_search(cladatum->permissions.table, id);
2290
8.90k
    if (!perdatum) {
2291
7.65k
      if (cladatum->comdatum) {
2292
0
        perdatum = hashtab_search(
2293
0
          cladatum->comdatum->permissions.table,
2294
0
          id);
2295
0
      }
2296
7.65k
    }
2297
8.90k
    if (!perdatum) {
2298
7.65k
      yyerror2("permission %s is not defined"
2299
7.65k
         " for class %s",
2300
7.65k
         id, policydbp->p_class_val_to_name[i]);
2301
7.65k
      continue;
2302
7.65k
    } else if (!is_perm_in_scope(
2303
1.25k
           id, policydbp->p_class_val_to_name[i])) {
2304
0
      yyerror2("permission %s of class %s is"
2305
0
         " not within scope",
2306
0
         id, policydbp->p_class_val_to_name[i]);
2307
0
      continue;
2308
1.25k
    } else {
2309
1.25k
      cur_perms->data |= UINT32_C(1)
2310
1.25k
             << (perdatum->s.value - 1);
2311
1.25k
    }
2312
8.90k
  }
2313
2314
8.90k
  ebitmap_destroy(&tclasses);
2315
2316
8.90k
  avrule->perms = perms;
2317
8.90k
  *rule = avrule;
2318
8.90k
  return 0;
2319
2320
11
out2:
2321
11
  ebitmap_destroy(&tclasses);
2322
73
out:
2323
73
  avrule_destroy(avrule);
2324
73
  free(avrule);
2325
73
  return -1;
2326
11
}
2327
2328
/* index of the u32 containing the permission */
2329
108k
#define XPERM_IDX(x) ((x) >> 5)
2330
/* set bits 0 through x-1 within the u32 */
2331
16.9k
#define XPERM_SETBITS(x) ((UINT32_C(1) << ((x) & 0x1f)) - 1)
2332
/* low value for this u32 */
2333
101k
#define XPERM_LOW(x) ((x) << 5)
2334
/* high value for this u32 */
2335
81.9k
#define XPERM_HIGH(x) ((((x) + 1) << 5) - 1)
2336
static void avrule_xperm_setrangebits(uint16_t low, uint16_t high,
2337
              av_extended_perms_t *xperms)
2338
16.9k
{
2339
16.9k
  unsigned int i;
2340
16.9k
  uint16_t h = high + 1;
2341
  /* for each u32 that this low-high range touches, set driver permissions */
2342
91.7k
  for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
2343
    /* set all bits in u32 */
2344
74.8k
    if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
2345
60.4k
      xperms->perms[i] |= ~0U;
2346
    /* set low bits */
2347
14.3k
    else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
2348
4.49k
      xperms->perms[i] |= XPERM_SETBITS(h);
2349
    /* set high bits */
2350
9.88k
    else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
2351
7.27k
      xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
2352
    /* set middle bits */
2353
2.61k
    else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
2354
2.61k
      xperms->perms[i] |=
2355
2.61k
        XPERM_SETBITS(h) - XPERM_SETBITS(low);
2356
74.8k
  }
2357
16.9k
}
2358
2359
static int avrule_xperms_used(const av_extended_perms_t *xperms)
2360
33.0k
{
2361
33.0k
  unsigned int i;
2362
2363
91.3k
  for (i = 0; i < sizeof(xperms->perms) / sizeof(xperms->perms[0]); i++) {
2364
88.9k
    if (xperms->perms[i])
2365
30.6k
      return 1;
2366
88.9k
  }
2367
2.40k
  return 0;
2368
33.0k
}
2369
2370
/*
2371
 * using definitions found in kernel document ioctl-number.txt
2372
 * The kernel components of an ioctl command are:
2373
 * dir, size, driver, and function. Only the driver and function fields
2374
 * are considered here
2375
 */
2376
71.8k
#define IOC_DRIV(x) ((x) >> 8)
2377
34.1k
#define IOC_FUNC(x) ((x) & 0xff)
2378
20.5k
#define IOC_CMD(driver, func) (((driver) << 8) + (func))
2379
static int avrule_xperm_partialdriver(struct av_xperm_range_list *rangelist,
2380
              av_extended_perms_t *complete_driver,
2381
              av_extended_perms_t **extended_perms)
2382
8.69k
{
2383
8.69k
  struct av_xperm_range_list *r;
2384
8.69k
  av_extended_perms_t *xperms;
2385
8.69k
  uint8_t low, high;
2386
2387
8.69k
  xperms = calloc(1, sizeof(av_extended_perms_t));
2388
8.69k
  if (!xperms) {
2389
0
    yyerror("out of memory");
2390
0
    return -1;
2391
0
  }
2392
2393
8.69k
  r = rangelist;
2394
20.4k
  while (r) {
2395
11.7k
    low = IOC_DRIV(r->range.low);
2396
11.7k
    high = IOC_DRIV(r->range.high);
2397
11.7k
    if (complete_driver) {
2398
4.77k
      if (!xperm_test(low, complete_driver->perms))
2399
3.23k
        xperm_set(low, xperms->perms);
2400
4.77k
      if (!xperm_test(high, complete_driver->perms))
2401
2.66k
        xperm_set(high, xperms->perms);
2402
6.99k
    } else {
2403
6.99k
      xperm_set(low, xperms->perms);
2404
6.99k
      xperm_set(high, xperms->perms);
2405
6.99k
    }
2406
11.7k
    r = r->next;
2407
11.7k
  }
2408
8.69k
  if (avrule_xperms_used(xperms)) {
2409
8.69k
    *extended_perms = xperms;
2410
8.69k
  } else {
2411
0
    free(xperms);
2412
0
    *extended_perms = NULL;
2413
0
  }
2414
8.69k
  return 0;
2415
8.69k
}
2416
2417
static int avrule_ioctl_completedriver(struct av_xperm_range_list *rangelist,
2418
               av_extended_perms_t **extended_perms)
2419
4.97k
{
2420
4.97k
  struct av_xperm_range_list *r;
2421
4.97k
  av_extended_perms_t *xperms;
2422
4.97k
  uint16_t low, high;
2423
4.97k
  xperms = calloc(1, sizeof(av_extended_perms_t));
2424
4.97k
  if (!xperms) {
2425
0
    yyerror("out of memory");
2426
0
    return -1;
2427
0
  }
2428
2429
4.97k
  r = rangelist;
2430
12.1k
  while (r) {
2431
    /*
2432
     * Any driver code that has sequence 0x00 - 0xff is a complete code,
2433
     *
2434
     * if command number = 0xff, then round high up to next code,
2435
     * else 0x00 - 0xfe keep current code
2436
     * of this range. temporarily u32 for the + 1
2437
     * to account for possible rollover before right shift
2438
     */
2439
7.17k
    high = IOC_DRIV((uint32_t)(r->range.high + 1));
2440
    /* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/
2441
7.17k
    low = IOC_DRIV(r->range.low);
2442
7.17k
    if (IOC_FUNC(r->range.low))
2443
4.65k
      low++;
2444
7.17k
    if (high > low)
2445
3.48k
      avrule_xperm_setrangebits(low, high - 1, xperms);
2446
7.17k
    r = r->next;
2447
7.17k
  }
2448
4.97k
  if (avrule_xperms_used(xperms)) {
2449
2.56k
    xperms->driver = 0x00;
2450
2.56k
    xperms->specified = AVRULE_XPERMS_IOCTLDRIVER;
2451
2.56k
    *extended_perms = xperms;
2452
2.56k
  } else {
2453
2.40k
    free(xperms);
2454
2.40k
    *extended_perms = NULL;
2455
2.40k
  }
2456
4.97k
  return 0;
2457
4.97k
}
2458
2459
static int avrule_xperm_func(struct av_xperm_range_list *rangelist,
2460
           av_extended_perms_t **extended_perms,
2461
           unsigned int driver, uint8_t specified)
2462
10.6k
{
2463
10.6k
  struct av_xperm_range_list *r;
2464
10.6k
  av_extended_perms_t *xperms;
2465
10.6k
  uint16_t low, high;
2466
2467
10.6k
  *extended_perms = NULL;
2468
10.6k
  xperms = calloc(1, sizeof(av_extended_perms_t));
2469
10.6k
  if (!xperms) {
2470
0
    yyerror("out of memory");
2471
0
    return -1;
2472
0
  }
2473
2474
10.6k
  r = rangelist;
2475
  /* for the passed in driver code, find the ranges that apply */
2476
26.0k
  while (r) {
2477
15.3k
    low = r->range.low;
2478
15.3k
    high = r->range.high;
2479
15.3k
    if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) {
2480
1.87k
      r = r->next;
2481
1.87k
      continue;
2482
1.87k
    }
2483
2484
13.4k
    if (driver == IOC_DRIV(low)) {
2485
10.2k
      if (high > IOC_CMD(driver, 0xff))
2486
3.81k
        high = IOC_CMD(driver, 0xff);
2487
2488
10.2k
    } else {
2489
3.24k
      if (low < IOC_CMD(driver, 0))
2490
3.24k
        low = IOC_CMD(driver, 0);
2491
3.24k
    }
2492
2493
13.4k
    low = IOC_FUNC(low);
2494
13.4k
    high = IOC_FUNC(high);
2495
13.4k
    avrule_xperm_setrangebits(low, high, xperms);
2496
13.4k
    xperms->driver = driver;
2497
13.4k
    xperms->specified = specified;
2498
13.4k
    r = r->next;
2499
13.4k
  }
2500
2501
10.6k
  if (avrule_xperms_used(xperms)) {
2502
10.6k
    *extended_perms = xperms;
2503
10.6k
  } else {
2504
0
    free(xperms);
2505
0
    *extended_perms = NULL;
2506
0
  }
2507
10.6k
  return 0;
2508
10.6k
}
2509
2510
static unsigned int xperms_for_each_bit(unsigned int *bit,
2511
          av_extended_perms_t *xperms)
2512
19.3k
{
2513
19.3k
  unsigned int i;
2514
2.24M
  for (i = *bit; i < sizeof(xperms->perms) * 8; i++) {
2515
2.23M
    if (xperm_test(i, xperms->perms)) {
2516
10.6k
      xperm_clear(i, xperms->perms);
2517
10.6k
      *bit = i;
2518
10.6k
      return 1;
2519
10.6k
    }
2520
2.23M
  }
2521
8.69k
  return 0;
2522
19.3k
}
2523
2524
static int avrule_cpy(avrule_t *dest, const avrule_t *src)
2525
13.2k
{
2526
13.2k
  class_perm_node_t *src_perms;
2527
13.2k
  class_perm_node_t *dest_perms, *dest_tail;
2528
13.2k
  dest_tail = NULL;
2529
2530
13.2k
  avrule_init(dest);
2531
13.2k
  dest->specified = src->specified;
2532
13.2k
  dest->flags = src->flags;
2533
13.2k
  if (type_set_cpy(&dest->stypes, &src->stypes)) {
2534
0
    yyerror("out of memory");
2535
0
    return -1;
2536
0
  }
2537
13.2k
  if (type_set_cpy(&dest->ttypes, &src->ttypes)) {
2538
0
    yyerror("out of memory");
2539
0
    return -1;
2540
0
  }
2541
13.2k
  dest->line = src->line;
2542
13.2k
  dest->source_filename = strdup(source_file);
2543
13.2k
  if (!dest->source_filename) {
2544
0
    yyerror("out of memory");
2545
0
    return -1;
2546
0
  }
2547
13.2k
  dest->source_line = src->source_line;
2548
2549
  /* increment through the class perms and copy over */
2550
13.2k
  src_perms = src->perms;
2551
26.4k
  while (src_perms) {
2552
13.2k
    dest_perms = calloc(1, sizeof(class_perm_node_t));
2553
13.2k
    if (!dest_perms) {
2554
0
      yyerror("out of memory");
2555
0
      return -1;
2556
0
    }
2557
13.2k
    class_perm_node_init(dest_perms);
2558
2559
13.2k
    if (!dest->perms)
2560
13.2k
      dest->perms = dest_perms;
2561
0
    else
2562
0
      dest_tail->next = dest_perms;
2563
2564
13.2k
    dest_perms->tclass = src_perms->tclass;
2565
13.2k
    dest_perms->data = src_perms->data;
2566
13.2k
    dest_perms->next = NULL;
2567
13.2k
    dest_tail = dest_perms;
2568
13.2k
    src_perms = src_perms->next;
2569
13.2k
  }
2570
13.2k
  return 0;
2571
13.2k
}
2572
2573
static int define_te_avtab_ioctl(const avrule_t *avrule_template,
2574
         avrule_t **ret_avrules)
2575
4.98k
{
2576
4.98k
  avrule_t *avrule, *ret = NULL, **last = &ret;
2577
4.98k
  struct av_xperm_range_list *rangelist, *r;
2578
4.98k
  av_extended_perms_t *complete_driver, *partial_driver, *xperms;
2579
4.98k
  unsigned int i;
2580
2581
  /* organize ioctl ranges */
2582
4.98k
  if (avrule_xperm_ranges(&rangelist))
2583
14
    return -1;
2584
2585
  /* create rule for ioctl driver types that are entirely enabled */
2586
4.97k
  if (avrule_ioctl_completedriver(rangelist, &complete_driver))
2587
0
    return -1;
2588
4.97k
  if (complete_driver) {
2589
2.56k
    avrule = calloc(1, sizeof(avrule_t));
2590
2.56k
    if (!avrule) {
2591
0
      yyerror("out of memory");
2592
0
      return -1;
2593
0
    }
2594
2.56k
    if (avrule_cpy(avrule, avrule_template))
2595
0
      return -1;
2596
2.56k
    avrule->xperms = complete_driver;
2597
2598
2.56k
    if (ret_avrules) {
2599
2.18k
      *last = avrule;
2600
2.18k
      last = &(avrule->next);
2601
2.18k
    } else {
2602
382
      append_avrule(avrule);
2603
382
    }
2604
2.56k
  }
2605
2606
  /* flag ioctl driver codes that are partially enabled */
2607
4.97k
  if (avrule_xperm_partialdriver(rangelist, complete_driver,
2608
4.97k
               &partial_driver))
2609
0
    return -1;
2610
2611
4.97k
  if (!partial_driver || !avrule_xperms_used(partial_driver))
2612
0
    goto done;
2613
2614
  /*
2615
   * create rule for each partially used driver codes
2616
   * "partially used" meaning that the code number e.g. socket 0x89
2617
   * has some permission bits set and others not set.
2618
   */
2619
4.97k
  i = 0;
2620
9.94k
  while (xperms_for_each_bit(&i, partial_driver)) {
2621
4.97k
    if (avrule_xperm_func(rangelist, &xperms, i,
2622
4.97k
              AVRULE_XPERMS_IOCTLFUNCTION))
2623
0
      return -1;
2624
2625
4.97k
    if (xperms) {
2626
4.97k
      avrule = calloc(1, sizeof(avrule_t));
2627
4.97k
      if (!avrule) {
2628
0
        yyerror("out of memory");
2629
0
        return -1;
2630
0
      }
2631
4.97k
      if (avrule_cpy(avrule, avrule_template))
2632
0
        return -1;
2633
4.97k
      avrule->xperms = xperms;
2634
2635
4.97k
      if (ret_avrules) {
2636
2.22k
        *last = avrule;
2637
2.22k
        last = &(avrule->next);
2638
2.74k
      } else {
2639
2.74k
        append_avrule(avrule);
2640
2.74k
      }
2641
4.97k
    }
2642
4.97k
  }
2643
2644
4.97k
done:
2645
4.97k
  if (partial_driver)
2646
4.97k
    free(partial_driver);
2647
2648
12.1k
  while (rangelist != NULL) {
2649
7.17k
    r = rangelist;
2650
7.17k
    rangelist = rangelist->next;
2651
7.17k
    free(r);
2652
7.17k
  }
2653
2654
4.97k
  if (ret_avrules)
2655
2.22k
    *ret_avrules = ret;
2656
2657
4.97k
  return 0;
2658
4.97k
}
2659
2660
static int define_te_avtab_netlink(const avrule_t *avrule_template,
2661
           avrule_t **ret_avrules)
2662
3.72k
{
2663
3.72k
  avrule_t *avrule, *ret = NULL, **last = &ret;
2664
3.72k
  struct av_xperm_range_list *rangelist, *r;
2665
3.72k
  av_extended_perms_t *partial_driver, *xperms;
2666
3.72k
  unsigned int i;
2667
2668
  /* organize ranges */
2669
3.72k
  if (avrule_xperm_ranges(&rangelist))
2670
6
    return -1;
2671
2672
  /* flag driver codes that are partially enabled */
2673
3.72k
  if (avrule_xperm_partialdriver(rangelist, NULL, &partial_driver))
2674
0
    return -1;
2675
2676
3.72k
  if (!partial_driver || !avrule_xperms_used(partial_driver))
2677
0
    goto done;
2678
2679
  /*
2680
   * create rule for each partially used driver codes
2681
   * "partially used" meaning that the code number e.g. socket 0x89
2682
   * has some permission bits set and others not set.
2683
   */
2684
3.72k
  i = 0;
2685
9.41k
  while (xperms_for_each_bit(&i, partial_driver)) {
2686
5.69k
    if (avrule_xperm_func(rangelist, &xperms, i,
2687
5.69k
              AVRULE_XPERMS_NLMSG))
2688
0
      return -1;
2689
2690
5.69k
    if (xperms) {
2691
5.69k
      avrule = calloc(1, sizeof(avrule_t));
2692
5.69k
      if (!avrule) {
2693
0
        yyerror("out of memory");
2694
0
        return -1;
2695
0
      }
2696
5.69k
      if (avrule_cpy(avrule, avrule_template))
2697
0
        return -1;
2698
5.69k
      avrule->xperms = xperms;
2699
2700
5.69k
      if (ret_avrules) {
2701
758
        *last = avrule;
2702
758
        last = &(avrule->next);
2703
4.93k
      } else {
2704
4.93k
        append_avrule(avrule);
2705
4.93k
      }
2706
5.69k
    }
2707
5.69k
  }
2708
2709
3.72k
done:
2710
3.72k
  if (partial_driver)
2711
3.72k
    free(partial_driver);
2712
2713
8.31k
  while (rangelist != NULL) {
2714
4.59k
    r = rangelist;
2715
4.59k
    rangelist = rangelist->next;
2716
4.59k
    free(r);
2717
4.59k
  }
2718
2719
3.72k
  if (ret_avrules)
2720
403
    *ret_avrules = ret;
2721
2722
3.72k
  return 0;
2723
3.72k
}
2724
2725
avrule_t *define_cond_te_avtab_extended_perms(int which)
2726
7.22k
{
2727
7.22k
  char *id;
2728
7.22k
  unsigned int i;
2729
7.22k
  avrule_t *avrule_template, *rules = NULL;
2730
7.22k
  int rc = 0;
2731
2732
7.22k
  if (policydbp->policy_type == POLICY_KERN &&
2733
0
      policydbp->policyvers < POLICYDB_VERSION_COND_XPERMS) {
2734
0
    yyerror2(
2735
0
      "extended permissions in conditional policies are only supported since policy version %d, found policy version %d",
2736
0
      POLICYDB_VERSION_COND_XPERMS, policydbp->policyvers);
2737
0
    return COND_ERR;
2738
0
  }
2739
7.22k
  if (policydbp->policy_type != POLICY_KERN &&
2740
7.22k
      policydbp->policyvers < MOD_POLICYDB_VERSION_COND_XPERMS) {
2741
0
    yyerror2(
2742
0
      "extended permissions in conditional policies are only supported since module policy version %d, found module policy version %d",
2743
0
      MOD_POLICYDB_VERSION_COND_XPERMS,
2744
0
      policydbp->policyvers);
2745
0
    return COND_ERR;
2746
0
  }
2747
2748
7.22k
  if (pass == 1) {
2749
22.0k
    for (i = 0; i < 4; i++) {
2750
43.8k
      while ((id = queue_remove(id_queue)))
2751
26.1k
        free(id);
2752
17.6k
    }
2753
4.41k
    return (avrule_t *)1; /* any non-NULL value */
2754
4.41k
  }
2755
2756
  /* populate avrule template with source/target/tclass */
2757
2.81k
  if (define_te_avtab_xperms_helper(which, &avrule_template))
2758
56
    return COND_ERR;
2759
2760
2.75k
  id = queue_remove(id_queue);
2761
2.75k
  if (strcmp(id, "ioctl") == 0) {
2762
2.23k
    rc = define_te_avtab_ioctl(avrule_template, &rules);
2763
2.23k
  } else if (strcmp(id, "nlmsg") == 0) {
2764
409
    rc = define_te_avtab_netlink(avrule_template, &rules);
2765
409
  } else {
2766
114
    yyerror2(
2767
114
      "only ioctl and nlmsg extended permissions are supported, found %s",
2768
114
      id);
2769
114
    rc = -1;
2770
114
  }
2771
2772
2.75k
  free(id);
2773
2.75k
  avrule_destroy(avrule_template);
2774
2.75k
  free(avrule_template);
2775
2776
2.75k
  if (rc) {
2777
133
    avrule_destroy(rules);
2778
133
    return NULL;
2779
133
  }
2780
2781
2.62k
  return rules;
2782
2.75k
}
2783
2784
int define_te_avtab_extended_perms(int which)
2785
13.9k
{
2786
13.9k
  char *id;
2787
13.9k
  unsigned int i;
2788
13.9k
  avrule_t *avrule_template;
2789
13.9k
  int rc = 0;
2790
2791
13.9k
  if (pass == 1) {
2792
39.0k
    for (i = 0; i < 4; i++) {
2793
72.5k
      while ((id = queue_remove(id_queue)))
2794
41.3k
        free(id);
2795
31.2k
    }
2796
7.80k
    return 0;
2797
7.80k
  }
2798
2799
  /* populate avrule template with source/target/tclass */
2800
6.16k
  if (define_te_avtab_xperms_helper(which, &avrule_template))
2801
17
    return -1;
2802
2803
6.14k
  id = queue_remove(id_queue);
2804
6.14k
  if (strcmp(id, "ioctl") == 0) {
2805
2.75k
    rc = define_te_avtab_ioctl(avrule_template, NULL);
2806
3.39k
  } else if (strcmp(id, "nlmsg") == 0) {
2807
3.31k
    rc = define_te_avtab_netlink(avrule_template, NULL);
2808
3.31k
  } else {
2809
82
    yyerror2(
2810
82
      "only ioctl and nlmsg extended permissions are supported, found %s",
2811
82
      id);
2812
82
    rc = -1;
2813
82
  }
2814
2815
6.14k
  free(id);
2816
6.14k
  avrule_destroy(avrule_template);
2817
6.14k
  free(avrule_template);
2818
2819
6.14k
  return rc;
2820
6.16k
}
2821
2822
#define PERMISSION_MASK(nprim)                          \
2823
21.3k
  ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : \
2824
21.3k
               ((UINT32_C(1) << (nprim)) - 1))
2825
2826
static int define_te_avtab_helper(int which, avrule_t **rule)
2827
24.3k
{
2828
24.3k
  char *id;
2829
24.3k
  class_datum_t *cladatum;
2830
24.3k
  perm_datum_t *perdatum = NULL;
2831
24.3k
  class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2832
24.3k
  ebitmap_t tclasses;
2833
24.3k
  ebitmap_node_t *node;
2834
24.3k
  avrule_t *avrule;
2835
24.3k
  unsigned int i;
2836
24.3k
  int add = 1, ret = 0;
2837
24.3k
  int suppress = 0;
2838
2839
24.3k
  ebitmap_init(&tclasses);
2840
2841
24.3k
  avrule = malloc(sizeof(avrule_t));
2842
24.3k
  if (!avrule) {
2843
0
    yyerror("memory error");
2844
0
    ret = -1;
2845
0
    goto out;
2846
0
  }
2847
24.3k
  avrule_init(avrule);
2848
24.3k
  avrule->specified = which;
2849
24.3k
  avrule->line = policydb_lineno;
2850
24.3k
  avrule->source_line = source_lineno;
2851
24.3k
  avrule->source_filename = strdup(source_file);
2852
24.3k
  avrule->xperms = NULL;
2853
24.3k
  if (!avrule->source_filename) {
2854
0
    yyerror("out of memory");
2855
0
    return -1;
2856
0
  }
2857
2858
49.0k
  while ((id = queue_remove(id_queue))) {
2859
24.6k
    if (set_types(&avrule->stypes, id, &add,
2860
24.6k
            which == AVRULE_NEVERALLOW ? 1 : 0)) {
2861
18
      ret = -1;
2862
18
      goto out;
2863
18
    }
2864
24.6k
  }
2865
24.3k
  add = 1;
2866
52.3k
  while ((id = queue_remove(id_queue))) {
2867
27.9k
    if (strcmp(id, "self") == 0) {
2868
14.4k
      free(id);
2869
14.4k
      if (add == 0 && which != AVRULE_NEVERALLOW) {
2870
2
        yyerror("-self is only supported in neverallow and neverallowxperm rules");
2871
2
        ret = -1;
2872
2
        goto out;
2873
2
      }
2874
14.4k
      avrule->flags |= (add ? RULE_SELF : RULE_NOTSELF);
2875
14.4k
      if ((avrule->flags & RULE_SELF) &&
2876
14.4k
          (avrule->flags & RULE_NOTSELF)) {
2877
0
        yyerror("self and -self are mutual exclusive");
2878
0
        ret = -1;
2879
0
        goto out;
2880
0
      }
2881
14.4k
      continue;
2882
14.4k
    }
2883
13.4k
    if (set_types(&avrule->ttypes, id, &add,
2884
13.4k
            which == AVRULE_NEVERALLOW ? 1 : 0)) {
2885
31
      ret = -1;
2886
31
      goto out;
2887
31
    }
2888
13.4k
  }
2889
2890
24.3k
  if ((avrule->ttypes.flags & TYPE_COMP)) {
2891
3.55k
    if (avrule->flags & RULE_NOTSELF) {
2892
0
      yyerror("-self is not supported in complements");
2893
0
      ret = -1;
2894
0
      goto out;
2895
0
    }
2896
3.55k
    if (avrule->flags & RULE_SELF) {
2897
2.80k
      avrule->flags &= ~RULE_SELF;
2898
2.80k
      avrule->flags |= RULE_NOTSELF;
2899
2.80k
    }
2900
3.55k
  }
2901
2902
24.3k
  ret = read_classes(&tclasses);
2903
24.3k
  if (ret)
2904
9
    goto out;
2905
2906
24.3k
  perms = NULL;
2907
1.55M
  ebitmap_for_each_positive_bit(&tclasses, node, i) {
2908
24.3k
    cur_perms = malloc(sizeof(class_perm_node_t));
2909
24.3k
    if (!cur_perms) {
2910
0
      yyerror("out of memory");
2911
0
      ret = -1;
2912
0
      goto out;
2913
0
    }
2914
24.3k
    class_perm_node_init(cur_perms);
2915
24.3k
    cur_perms->tclass = i + 1;
2916
24.3k
    if (!perms)
2917
24.3k
      perms = cur_perms;
2918
24.3k
    if (tail)
2919
0
      tail->next = cur_perms;
2920
24.3k
    tail = cur_perms;
2921
24.3k
  }
2922
2923
71.6k
  while ((id = queue_remove(id_queue))) {
2924
47.3k
    cur_perms = perms;
2925
3.02M
    ebitmap_for_each_positive_bit(&tclasses, node, i) {
2926
47.3k
      cladatum = policydbp->class_val_to_struct[i];
2927
2928
47.3k
      if (strcmp(id, "*") == 0) {
2929
        /* set all declared permissions in the class */
2930
0
        cur_perms->data = PERMISSION_MASK(
2931
0
          cladatum->permissions.nprim);
2932
0
        goto next;
2933
0
      }
2934
2935
47.3k
      if (strcmp(id, "~") == 0) {
2936
        /* complement the set */
2937
20.2k
        if (which == AVRULE_DONTAUDIT)
2938
857
          yywarn("dontaudit rule with a ~?");
2939
20.2k
        cur_perms->data =
2940
20.2k
          ~cur_perms->data &
2941
20.2k
          PERMISSION_MASK(
2942
20.2k
            cladatum->permissions.nprim);
2943
20.2k
        if (cur_perms->data == 0) {
2944
2.03k
          class_perm_node_t *tmp = cur_perms;
2945
2.03k
          yywarn("omitting avrule with no permission set");
2946
2.03k
          if (perms == cur_perms)
2947
2.03k
            perms = cur_perms->next;
2948
2.03k
          cur_perms = cur_perms->next;
2949
2.03k
          free(tmp);
2950
2.03k
          continue;
2951
2.03k
        }
2952
18.2k
        goto next;
2953
20.2k
      }
2954
2955
27.0k
      perdatum =
2956
27.0k
        hashtab_search(cladatum->permissions.table, id);
2957
27.0k
      if (!perdatum) {
2958
10.4k
        if (cladatum->comdatum) {
2959
0
          perdatum = hashtab_search(
2960
0
            cladatum->comdatum->permissions
2961
0
              .table,
2962
0
            id);
2963
0
        }
2964
10.4k
      }
2965
27.0k
      if (!perdatum) {
2966
10.4k
        if (!suppress)
2967
10.4k
          yyerror2("permission %s is not defined"
2968
10.4k
             " for class %s",
2969
10.4k
             id,
2970
10.4k
             policydbp->p_class_val_to_name
2971
10.4k
               [i]);
2972
10.4k
        continue;
2973
16.6k
      } else if (!is_perm_in_scope(
2974
16.6k
             id,
2975
16.6k
             policydbp->p_class_val_to_name[i])) {
2976
0
        if (!suppress) {
2977
0
          yyerror2("permission %s of class %s is"
2978
0
             " not within scope",
2979
0
             id,
2980
0
             policydbp->p_class_val_to_name
2981
0
               [i]);
2982
0
        }
2983
0
        continue;
2984
16.6k
      } else {
2985
16.6k
        cur_perms->data |= UINT32_C(1)
2986
16.6k
               << (perdatum->s.value - 1);
2987
16.6k
      }
2988
34.8k
next:
2989
34.8k
      cur_perms = cur_perms->next;
2990
34.8k
    }
2991
2992
47.3k
    free(id);
2993
47.3k
  }
2994
2995
24.3k
  avrule->perms = perms;
2996
24.3k
  *rule = avrule;
2997
2998
24.3k
out:
2999
24.3k
  if (ret) {
3000
60
    avrule_destroy(avrule);
3001
60
    free(avrule);
3002
60
  }
3003
3004
24.3k
  ebitmap_destroy(&tclasses);
3005
3006
24.3k
  return ret;
3007
24.3k
}
3008
3009
avrule_t *define_cond_te_avtab(int which)
3010
14.8k
{
3011
14.8k
  char *id;
3012
14.8k
  avrule_t *avrule;
3013
14.8k
  int i;
3014
3015
14.8k
  if (pass == 1) {
3016
46.8k
    for (i = 0; i < 4; i++) {
3017
84.7k
      while ((id = queue_remove(id_queue)))
3018
47.2k
        free(id);
3019
37.4k
    }
3020
9.36k
    return (avrule_t *)1; /* any non-NULL value */
3021
9.36k
  }
3022
3023
5.53k
  if (define_te_avtab_helper(which, &avrule))
3024
26
    return COND_ERR;
3025
3026
5.50k
  return avrule;
3027
5.53k
}
3028
3029
int define_te_avtab(int which)
3030
42.4k
{
3031
42.4k
  char *id;
3032
42.4k
  avrule_t *avrule;
3033
42.4k
  int i;
3034
3035
42.4k
  if (pass == 1) {
3036
117k
    for (i = 0; i < 4; i++) {
3037
215k
      while ((id = queue_remove(id_queue)))
3038
120k
        free(id);
3039
94.2k
    }
3040
23.5k
    return 0;
3041
23.5k
  }
3042
3043
18.8k
  if (define_te_avtab_helper(which, &avrule))
3044
34
    return -1;
3045
3046
  /* append this avrule to the end of the current rules list */
3047
18.8k
  append_avrule(avrule);
3048
18.8k
  return 0;
3049
18.8k
}
3050
3051
/* The role-types rule is no longer used to declare regular role or
3052
 * role attribute, but solely aimed for declaring role-types associations.
3053
 */
3054
int define_role_types(void)
3055
12.0k
{
3056
12.0k
  role_datum_t *role;
3057
12.0k
  char *id;
3058
12.0k
  int add = 1;
3059
3060
12.0k
  if (pass == 1) {
3061
20.9k
    while ((id = queue_remove(id_queue)))
3062
14.0k
      free(id);
3063
6.88k
    return 0;
3064
6.88k
  }
3065
3066
5.12k
  id = (char *)queue_remove(id_queue);
3067
5.12k
  if (!id) {
3068
0
    yyerror("no role name for role-types rule?");
3069
0
    return -1;
3070
0
  }
3071
3072
5.12k
  if (!is_id_in_scope(SYM_ROLES, id)) {
3073
3
    yyerror2("role %s is not within scope", id);
3074
3
    free(id);
3075
3
    return -1;
3076
3
  }
3077
3078
5.11k
  role = hashtab_search(policydbp->p_roles.table, id);
3079
5.11k
  if (!role) {
3080
38
    yyerror2("unknown role %s", id);
3081
38
    free(id);
3082
38
    return -1;
3083
38
  }
3084
5.08k
  role = get_local_role(id, role->s.value, (role->flavor == ROLE_ATTRIB));
3085
3086
11.2k
  while ((id = queue_remove(id_queue))) {
3087
6.18k
    if (set_types(&role->types, id, &add, 0))
3088
9
      return -1;
3089
6.18k
  }
3090
3091
5.07k
  return 0;
3092
5.08k
}
3093
3094
int define_attrib_role(void)
3095
2.22k
{
3096
2.22k
  if (pass == 2) {
3097
1.06k
    free(queue_remove(id_queue));
3098
1.06k
    return 0;
3099
1.06k
  }
3100
3101
  /* Declare a role attribute */
3102
1.15k
  if (declare_role(TRUE) == NULL)
3103
2
    return -1;
3104
3105
1.15k
  return 0;
3106
1.15k
}
3107
3108
int define_role_attr(void)
3109
244k
{
3110
244k
  char *id;
3111
244k
  role_datum_t *r, *attr;
3112
3113
244k
  if (pass == 2) {
3114
226k
    while ((id = queue_remove(id_queue)))
3115
121k
      free(id);
3116
104k
    return 0;
3117
104k
  }
3118
3119
  /* Declare a regular role */
3120
140k
  if ((r = declare_role(FALSE)) == NULL)
3121
5
    return -1;
3122
3123
162k
  while ((id = queue_remove(id_queue))) {
3124
21.9k
    if (!is_id_in_scope(SYM_ROLES, id)) {
3125
5
      yyerror2("attribute %s is not within scope", id);
3126
5
      free(id);
3127
5
      return -1;
3128
5
    }
3129
21.9k
    attr = hashtab_search(policydbp->p_roles.table, id);
3130
21.9k
    if (!attr) {
3131
      /* treat it as a fatal error */
3132
11
      yyerror2("role attribute %s is not declared", id);
3133
11
      free(id);
3134
11
      return -1;
3135
11
    }
3136
3137
21.9k
    if (attr->flavor != ROLE_ATTRIB) {
3138
3
      yyerror2("%s is a regular role, not an attribute", id);
3139
3
      free(id);
3140
3
      return -1;
3141
3
    }
3142
3143
21.9k
    if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
3144
0
      yyerror("Out of memory!");
3145
0
      return -1;
3146
0
    }
3147
3148
21.9k
    if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
3149
0
      yyerror("out of memory");
3150
0
      return -1;
3151
0
    }
3152
21.9k
  }
3153
3154
140k
  return 0;
3155
140k
}
3156
3157
int define_roleattribute(void)
3158
872
{
3159
872
  char *id;
3160
872
  role_datum_t *r, *attr;
3161
3162
872
  if (pass == 2) {
3163
909
    while ((id = queue_remove(id_queue)))
3164
606
      free(id);
3165
303
    return 0;
3166
303
  }
3167
3168
569
  id = (char *)queue_remove(id_queue);
3169
569
  if (!id) {
3170
1
    yyerror("no role name for roleattribute definition?");
3171
1
    return -1;
3172
1
  }
3173
3174
568
  if (!is_id_in_scope(SYM_ROLES, id)) {
3175
1
    yyerror2("role %s is not within scope", id);
3176
1
    free(id);
3177
1
    return -1;
3178
1
  }
3179
567
  r = hashtab_search(policydbp->p_roles.table, id);
3180
  /* We support adding one role attribute into another */
3181
567
  if (!r) {
3182
1
    yyerror2("unknown role %s", id);
3183
1
    free(id);
3184
1
    return -1;
3185
1
  }
3186
566
  free(id);
3187
3188
1.12k
  while ((id = queue_remove(id_queue))) {
3189
566
    if (!is_id_in_scope(SYM_ROLES, id)) {
3190
1
      yyerror2("attribute %s is not within scope", id);
3191
1
      free(id);
3192
1
      return -1;
3193
1
    }
3194
565
    attr = hashtab_search(policydbp->p_roles.table, id);
3195
565
    if (!attr) {
3196
      /* treat it as a fatal error */
3197
2
      yyerror2("role attribute %s is not declared", id);
3198
2
      free(id);
3199
2
      return -1;
3200
2
    }
3201
3202
563
    if (attr->flavor != ROLE_ATTRIB) {
3203
1
      yyerror2("%s is a regular role, not an attribute", id);
3204
1
      free(id);
3205
1
      return -1;
3206
1
    }
3207
3208
562
    if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
3209
0
      yyerror("Out of memory!");
3210
0
      return -1;
3211
0
    }
3212
3213
562
    if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
3214
0
      yyerror("out of memory");
3215
0
      return -1;
3216
0
    }
3217
562
  }
3218
3219
562
  return 0;
3220
566
}
3221
3222
static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
3223
           void *p)
3224
664
{
3225
664
  struct val_to_name *v = p;
3226
664
  role_datum_t *roldatum;
3227
3228
664
  roldatum = (role_datum_t *)datum;
3229
3230
664
  if (v->val == roldatum->s.value) {
3231
33
    v->name = key;
3232
33
    return 1;
3233
33
  }
3234
3235
631
  return 0;
3236
664
}
3237
3238
static char *role_val_to_name(unsigned int val)
3239
33
{
3240
33
  struct val_to_name v;
3241
33
  int rc;
3242
3243
33
  v.val = val;
3244
33
  rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
3245
33
  if (rc)
3246
33
    return v.name;
3247
0
  return NULL;
3248
33
}
3249
3250
static int set_roles(role_set_t *set, char *id)
3251
16.7k
{
3252
16.7k
  role_datum_t *r;
3253
3254
16.7k
  if (strcmp(id, "*") == 0) {
3255
1
    free(id);
3256
1
    yyerror("* is not allowed for role sets");
3257
1
    return -1;
3258
1
  }
3259
3260
16.7k
  if (strcmp(id, "~") == 0) {
3261
1
    free(id);
3262
1
    yyerror("~ is not allowed for role sets");
3263
1
    return -1;
3264
1
  }
3265
16.7k
  if (!is_id_in_scope(SYM_ROLES, id)) {
3266
2
    yyerror2("role %s is not within scope", id);
3267
2
    free(id);
3268
2
    return -1;
3269
2
  }
3270
16.7k
  r = hashtab_search(policydbp->p_roles.table, id);
3271
16.7k
  if (!r) {
3272
31
    yyerror2("unknown role %s", id);
3273
31
    free(id);
3274
31
    return -1;
3275
31
  }
3276
3277
16.7k
  if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
3278
0
    yyerror("out of memory");
3279
0
    free(id);
3280
0
    return -1;
3281
0
  }
3282
16.7k
  free(id);
3283
16.7k
  return 0;
3284
16.7k
}
3285
3286
int define_role_trans(int class_specified)
3287
9.01k
{
3288
9.01k
  char *id;
3289
9.01k
  const role_datum_t *role;
3290
9.01k
  role_set_t roles;
3291
9.01k
  type_set_t types;
3292
9.01k
  const class_datum_t *cladatum;
3293
9.01k
  ebitmap_t e_types, e_roles, e_classes;
3294
9.01k
  ebitmap_node_t *tnode, *rnode, *cnode;
3295
9.01k
  struct role_trans *tr = NULL;
3296
9.01k
  struct role_trans_rule *rule = NULL;
3297
9.01k
  unsigned int i, j, k;
3298
9.01k
  int add = 1;
3299
3300
9.01k
  if (pass == 1) {
3301
17.0k
    while ((id = queue_remove(id_queue)))
3302
9.93k
      free(id);
3303
38.5k
    while ((id = queue_remove(id_queue)))
3304
31.5k
      free(id);
3305
7.07k
    if (class_specified)
3306
17.0k
      while ((id = queue_remove(id_queue)))
3307
10.6k
        free(id);
3308
7.07k
    id = queue_remove(id_queue);
3309
7.07k
    free(id);
3310
7.07k
    return 0;
3311
7.07k
  }
3312
3313
1.93k
  role_set_init(&roles);
3314
1.93k
  ebitmap_init(&e_roles);
3315
1.93k
  type_set_init(&types);
3316
1.93k
  ebitmap_init(&e_types);
3317
1.93k
  ebitmap_init(&e_classes);
3318
3319
3.86k
  while ((id = queue_remove(id_queue))) {
3320
1.93k
    if (set_roles(&roles, id))
3321
9
      goto bad;
3322
1.93k
  }
3323
1.92k
  add = 1;
3324
23.1k
  while ((id = queue_remove(id_queue))) {
3325
21.2k
    if (set_types(&types, id, &add, 0))
3326
12
      goto bad;
3327
21.2k
  }
3328
3329
1.91k
  if (class_specified) {
3330
1.77k
    if (read_classes(&e_classes))
3331
3
      goto bad;
3332
1.77k
  } else {
3333
144
    cladatum =
3334
144
      hashtab_search(policydbp->p_classes.table, "process");
3335
144
    if (!cladatum) {
3336
1
      yyerror2("could not find process class for "
3337
1
         "legacy role_transition statement");
3338
1
      goto bad;
3339
1
    }
3340
3341
143
    if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
3342
0
      yyerror("out of memory");
3343
0
      goto bad;
3344
0
    }
3345
143
  }
3346
3347
1.91k
  id = (char *)queue_remove(id_queue);
3348
1.91k
  if (!id) {
3349
0
    yyerror("no new role in transition definition?");
3350
0
    goto bad;
3351
0
  }
3352
1.91k
  if (!is_id_in_scope(SYM_ROLES, id)) {
3353
2
    yyerror2("role %s is not within scope", id);
3354
2
    free(id);
3355
2
    goto bad;
3356
2
  }
3357
1.90k
  role = hashtab_search(policydbp->p_roles.table, id);
3358
1.90k
  if (!role) {
3359
8
    yyerror2("unknown role %s used in transition definition", id);
3360
8
    free(id);
3361
8
    goto bad;
3362
8
  }
3363
3364
1.90k
  if (role->flavor != ROLE_ROLE) {
3365
0
    yyerror2("the new role %s must be a regular role", id);
3366
0
    free(id);
3367
0
    goto bad;
3368
0
  }
3369
1.90k
  free(id);
3370
3371
  /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
3372
1.90k
  if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
3373
0
    goto bad;
3374
3375
1.90k
  if (type_set_expand(&types, &e_types, policydbp, 1))
3376
0
    goto bad;
3377
3378
120k
  ebitmap_for_each_positive_bit(&e_roles, rnode, i) {
3379
7.07k
    ebitmap_for_each_positive_bit(&e_types, tnode, j) {
3380
6.81k
      ebitmap_for_each_positive_bit(&e_classes, cnode, k) {
3381
297
        for (tr = policydbp->role_tr; tr;
3382
191
             tr = tr->next) {
3383
191
          if (tr->role == (i + 1) &&
3384
71
              tr->type == (j + 1) &&
3385
33
              tr->tclass == (k + 1)) {
3386
33
            yyerror2(
3387
33
              "duplicate role "
3388
33
              "transition for "
3389
33
              "(%s,%s,%s)",
3390
33
              role_val_to_name(i + 1),
3391
33
              policydbp->p_type_val_to_name
3392
33
                [j],
3393
33
              policydbp->p_class_val_to_name
3394
33
                [k]);
3395
33
            goto bad;
3396
33
          }
3397
191
        }
3398
3399
106
        tr = calloc(1, sizeof(struct role_trans));
3400
106
        if (!tr) {
3401
0
          yyerror("out of memory");
3402
0
          goto bad;
3403
0
        }
3404
106
        tr->role = i + 1;
3405
106
        tr->type = j + 1;
3406
106
        tr->tclass = k + 1;
3407
106
        tr->new_role = role->s.value;
3408
106
        tr->next = policydbp->role_tr;
3409
106
        policydbp->role_tr = tr;
3410
106
      }
3411
139
    }
3412
1.90k
  }
3413
  /* Now add the real rule */
3414
1.86k
  rule = calloc(1, sizeof(struct role_trans_rule));
3415
1.86k
  if (!rule) {
3416
0
    yyerror("out of memory");
3417
0
    goto bad;
3418
0
  }
3419
1.86k
  rule->roles = roles;
3420
1.86k
  rule->types = types;
3421
1.86k
  rule->classes = e_classes;
3422
1.86k
  rule->new_role = role->s.value;
3423
3424
1.86k
  append_role_trans(rule);
3425
3426
1.86k
  ebitmap_destroy(&e_roles);
3427
1.86k
  ebitmap_destroy(&e_types);
3428
3429
1.86k
  return 0;
3430
3431
68
bad:
3432
68
  role_set_destroy(&roles);
3433
68
  type_set_destroy(&types);
3434
68
  ebitmap_destroy(&e_roles);
3435
68
  ebitmap_destroy(&e_types);
3436
68
  ebitmap_destroy(&e_classes);
3437
68
  return -1;
3438
1.86k
}
3439
3440
int define_role_allow(void)
3441
19.3k
{
3442
19.3k
  char *id;
3443
19.3k
  struct role_allow_rule *ra = NULL;
3444
3445
19.3k
  if (pass == 1) {
3446
24.8k
    while ((id = queue_remove(id_queue)))
3447
12.9k
      free(id);
3448
25.4k
    while ((id = queue_remove(id_queue)))
3449
13.5k
      free(id);
3450
11.9k
    return 0;
3451
11.9k
  }
3452
3453
7.40k
  ra = malloc(sizeof(role_allow_rule_t));
3454
7.40k
  if (!ra) {
3455
0
    yyerror("out of memory");
3456
0
    return -1;
3457
0
  }
3458
7.40k
  role_allow_rule_init(ra);
3459
3460
14.8k
  while ((id = queue_remove(id_queue))) {
3461
7.40k
    if (set_roles(&ra->roles, id)) {
3462
14
      role_allow_rule_destroy(ra);
3463
14
      free(ra);
3464
14
      return -1;
3465
14
    }
3466
7.40k
  }
3467
3468
14.7k
  while ((id = queue_remove(id_queue))) {
3469
7.39k
    if (set_roles(&ra->new_roles, id)) {
3470
12
      role_allow_rule_destroy(ra);
3471
12
      free(ra);
3472
12
      return -1;
3473
12
    }
3474
7.39k
  }
3475
3476
7.38k
  append_role_allow(ra);
3477
7.38k
  return 0;
3478
7.39k
}
3479
3480
avrule_t *define_cond_filename_trans(void)
3481
1
{
3482
1
  yyerror("type transitions with a filename not allowed inside "
3483
1
    "conditionals");
3484
1
  return COND_ERR;
3485
1
}
3486
3487
int define_filename_trans(void)
3488
5.09k
{
3489
5.09k
  char *id, *name = NULL;
3490
5.09k
  type_set_t stypes, ttypes;
3491
5.09k
  ebitmap_t e_stypes, e_ttypes;
3492
5.09k
  ebitmap_t e_tclasses;
3493
5.09k
  ebitmap_node_t *snode, *tnode, *cnode;
3494
5.09k
  filename_trans_rule_t *ftr;
3495
5.09k
  type_datum_t *typdatum;
3496
5.09k
  uint32_t otype;
3497
5.09k
  unsigned int c, s, t;
3498
5.09k
  int add, self, rc;
3499
3500
5.09k
  if (pass == 1) {
3501
    /* stype */
3502
6.00k
    while ((id = queue_remove(id_queue)))
3503
3.07k
      free(id);
3504
    /* ttype */
3505
9.75k
    while ((id = queue_remove(id_queue)))
3506
6.83k
      free(id);
3507
    /* tclass */
3508
6.06k
    while ((id = queue_remove(id_queue)))
3509
3.13k
      free(id);
3510
    /* otype */
3511
2.92k
    id = queue_remove(id_queue);
3512
2.92k
    free(id);
3513
    /* name */
3514
2.92k
    id = queue_remove(id_queue);
3515
2.92k
    free(id);
3516
2.92k
    return 0;
3517
2.92k
  }
3518
3519
2.17k
  type_set_init(&stypes);
3520
2.17k
  type_set_init(&ttypes);
3521
2.17k
  ebitmap_init(&e_stypes);
3522
2.17k
  ebitmap_init(&e_ttypes);
3523
2.17k
  ebitmap_init(&e_tclasses);
3524
3525
2.17k
  add = 1;
3526
4.34k
  while ((id = queue_remove(id_queue))) {
3527
2.21k
    if (set_types(&stypes, id, &add, 0))
3528
35
      goto bad;
3529
2.21k
  }
3530
3531
2.13k
  self = 0;
3532
2.13k
  add = 1;
3533
7.27k
  while ((id = queue_remove(id_queue))) {
3534
5.22k
    if (strcmp(id, "self") == 0) {
3535
259
      free(id);
3536
259
      if (add == 0) {
3537
1
        yyerror("-self is not supported");
3538
1
        goto bad;
3539
1
      }
3540
258
      self = 1;
3541
258
      continue;
3542
259
    }
3543
4.97k
    if (set_types(&ttypes, id, &add, 0))
3544
93
      goto bad;
3545
4.97k
  }
3546
3547
2.04k
  if (read_classes(&e_tclasses))
3548
11
    goto bad;
3549
3550
2.03k
  id = (char *)queue_remove(id_queue);
3551
2.03k
  if (!id) {
3552
0
    yyerror("no otype in transition definition?");
3553
0
    goto bad;
3554
0
  }
3555
2.03k
  if (!is_id_in_scope(SYM_TYPES, id)) {
3556
1
    yyerror2("type %s is not within scope", id);
3557
1
    free(id);
3558
1
    goto bad;
3559
1
  }
3560
2.02k
  typdatum = hashtab_search(policydbp->p_types.table, id);
3561
2.02k
  if (!typdatum) {
3562
23
    yyerror2("unknown type %s used in transition definition", id);
3563
23
    free(id);
3564
23
    goto bad;
3565
23
  }
3566
2.00k
  free(id);
3567
2.00k
  otype = typdatum->s.value;
3568
3569
2.00k
  name = queue_remove(id_queue);
3570
2.00k
  if (!name) {
3571
0
    yyerror("no pathname specified in filename_trans definition?");
3572
0
    goto bad;
3573
0
  }
3574
3575
  /* We expand the class set into separate rules.  We expand the types
3576
   * just to make sure there are not duplicates.  They will get turned
3577
   * into separate rules later */
3578
2.00k
  if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
3579
0
    goto bad;
3580
3581
2.00k
  if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
3582
0
    goto bad;
3583
3584
126k
  ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) {
3585
48.9k
    ebitmap_for_each_positive_bit(&e_stypes, snode, s) {
3586
45.7k
      ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) {
3587
1.03k
        rc = policydb_filetrans_insert(policydbp, s + 1,
3588
1.03k
                     t + 1, c + 1,
3589
1.03k
                     name, NULL,
3590
1.03k
                     otype, NULL);
3591
1.03k
        if (rc != SEPOL_OK) {
3592
24
          if (rc == SEPOL_EEXIST) {
3593
24
            yyerror2(
3594
24
              "duplicate filename transition for: filename_trans %s %s %s:%s",
3595
24
              name,
3596
24
              policydbp->p_type_val_to_name
3597
24
                [s],
3598
24
              policydbp->p_type_val_to_name
3599
24
                [t],
3600
24
              policydbp->p_class_val_to_name
3601
24
                [c]);
3602
24
            goto bad;
3603
24
          }
3604
0
          yyerror("out of memory");
3605
0
          goto bad;
3606
24
        }
3607
1.03k
      }
3608
787
      if (self) {
3609
12
        rc = policydb_filetrans_insert(policydbp, s + 1,
3610
12
                     s + 1, c + 1,
3611
12
                     name, NULL,
3612
12
                     otype, NULL);
3613
12
        if (rc != SEPOL_OK) {
3614
8
          if (rc == SEPOL_EEXIST) {
3615
8
            yyerror2(
3616
8
              "duplicate filename transition for: filename_trans %s %s %s:%s",
3617
8
              name,
3618
8
              policydbp->p_type_val_to_name
3619
8
                [s],
3620
8
              policydbp->p_type_val_to_name
3621
8
                [s],
3622
8
              policydbp->p_class_val_to_name
3623
8
                [c]);
3624
8
            goto bad;
3625
8
          }
3626
0
          yyerror("out of memory");
3627
0
          goto bad;
3628
8
        }
3629
12
      }
3630
787
    }
3631
3632
    /* Now add the real rule since we didn't find any duplicates */
3633
1.97k
    ftr = malloc(sizeof(*ftr));
3634
1.97k
    if (!ftr) {
3635
0
      yyerror("out of memory");
3636
0
      goto bad;
3637
0
    }
3638
1.97k
    filename_trans_rule_init(ftr);
3639
1.97k
    append_filename_trans(ftr);
3640
3641
1.97k
    ftr->name = strdup(name);
3642
1.97k
    if (!ftr->name) {
3643
0
      yyerror("out of memory");
3644
0
      goto bad;
3645
0
    }
3646
1.97k
    if (type_set_cpy(&ftr->stypes, &stypes)) {
3647
0
      yyerror("out of memory");
3648
0
      goto bad;
3649
0
    }
3650
1.97k
    if (type_set_cpy(&ftr->ttypes, &ttypes)) {
3651
0
      yyerror("out of memory");
3652
0
      goto bad;
3653
0
    }
3654
1.97k
    ftr->tclass = c + 1;
3655
1.97k
    ftr->otype = otype;
3656
1.97k
    ftr->flags = self ? RULE_SELF : 0;
3657
1.97k
  }
3658
3659
1.97k
  free(name);
3660
1.97k
  ebitmap_destroy(&e_stypes);
3661
1.97k
  ebitmap_destroy(&e_ttypes);
3662
1.97k
  ebitmap_destroy(&e_tclasses);
3663
1.97k
  type_set_destroy(&stypes);
3664
1.97k
  type_set_destroy(&ttypes);
3665
3666
1.97k
  return 0;
3667
3668
196
bad:
3669
196
  free(name);
3670
196
  ebitmap_destroy(&e_stypes);
3671
196
  ebitmap_destroy(&e_ttypes);
3672
196
  ebitmap_destroy(&e_tclasses);
3673
196
  type_set_destroy(&stypes);
3674
196
  type_set_destroy(&ttypes);
3675
196
  return -1;
3676
2.00k
}
3677
3678
static constraint_expr_t *constraint_expr_clone(const constraint_expr_t *expr)
3679
0
{
3680
0
  constraint_expr_t *h = NULL, *l = NULL, *newe;
3681
0
  const constraint_expr_t *e;
3682
0
  for (e = expr; e; e = e->next) {
3683
0
    newe = malloc(sizeof(*newe));
3684
0
    if (!newe)
3685
0
      goto oom;
3686
0
    if (constraint_expr_init(newe) == -1) {
3687
0
      free(newe);
3688
0
      goto oom;
3689
0
    }
3690
0
    if (l)
3691
0
      l->next = newe;
3692
0
    else
3693
0
      h = newe;
3694
0
    l = newe;
3695
0
    newe->expr_type = e->expr_type;
3696
0
    newe->attr = e->attr;
3697
0
    newe->op = e->op;
3698
0
    if (newe->expr_type == CEXPR_NAMES) {
3699
0
      if (newe->attr & CEXPR_TYPE) {
3700
0
        if (type_set_cpy(newe->type_names,
3701
0
             e->type_names))
3702
0
          goto oom;
3703
0
      } else {
3704
0
        if (ebitmap_cpy(&newe->names, &e->names))
3705
0
          goto oom;
3706
0
      }
3707
0
    }
3708
0
  }
3709
3710
0
  return h;
3711
0
oom:
3712
0
  constraint_expr_destroy(h);
3713
0
  return NULL;
3714
0
}
3715
3716
int define_constraint(constraint_expr_t *expr)
3717
15.2k
{
3718
15.2k
  struct constraint_node *node;
3719
15.2k
  char *id;
3720
15.2k
  class_datum_t *cladatum;
3721
15.2k
  perm_datum_t *perdatum;
3722
15.2k
  ebitmap_t classmap;
3723
15.2k
  ebitmap_node_t *enode;
3724
15.2k
  constraint_expr_t *e;
3725
15.2k
  unsigned int i;
3726
15.2k
  int depth;
3727
15.2k
  unsigned char useexpr = 1;
3728
3729
15.2k
  if (pass == 1) {
3730
16.6k
    while ((id = queue_remove(id_queue)))
3731
8.53k
      free(id);
3732
17.8k
    while ((id = queue_remove(id_queue)))
3733
9.75k
      free(id);
3734
8.12k
    return 0;
3735
8.12k
  }
3736
3737
7.15k
  ebitmap_init(&classmap);
3738
3739
7.15k
  depth = -1;
3740
1.88M
  for (e = expr; e; e = e->next) {
3741
1.87M
    switch (e->expr_type) {
3742
1.54M
    case CEXPR_NOT:
3743
1.54M
      if (depth < 0) {
3744
0
        yyerror("illegal constraint expression");
3745
0
        goto bad;
3746
0
      }
3747
1.54M
      break;
3748
1.54M
    case CEXPR_AND:
3749
163k
    case CEXPR_OR:
3750
163k
      if (depth < 1) {
3751
0
        yyerror("illegal constraint expression");
3752
0
        goto bad;
3753
0
      }
3754
163k
      depth--;
3755
163k
      break;
3756
154k
    case CEXPR_ATTR:
3757
170k
    case CEXPR_NAMES:
3758
170k
      if (e->attr & CEXPR_XTARGET) {
3759
66
        yyerror("illegal constraint expression");
3760
66
        goto bad; /* only for validatetrans rules */
3761
66
      }
3762
170k
      if (depth == (CEXPR_MAXDEPTH - 1)) {
3763
0
        yyerror("constraint expression is too deep");
3764
0
        goto bad;
3765
0
      }
3766
170k
      depth++;
3767
170k
      break;
3768
0
    default:
3769
0
      yyerror("illegal constraint expression");
3770
0
      goto bad;
3771
1.87M
    }
3772
1.87M
  }
3773
7.08k
  if (depth != 0) {
3774
0
    yyerror("illegal constraint expression");
3775
0
    goto bad;
3776
0
  }
3777
3778
14.0k
  while ((id = queue_remove(id_queue))) {
3779
7.09k
    if (!is_id_in_scope(SYM_CLASSES, id)) {
3780
0
      yyerror2("class %s is not within scope", id);
3781
0
      free(id);
3782
0
      goto bad;
3783
0
    }
3784
7.09k
    cladatum = (class_datum_t *)hashtab_search(
3785
7.09k
      policydbp->p_classes.table, (hashtab_key_t)id);
3786
7.09k
    if (!cladatum) {
3787
87
      yyerror2("class %s is not defined", id);
3788
87
      free(id);
3789
87
      goto bad;
3790
87
    }
3791
7.00k
    if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
3792
0
      yyerror("out of memory");
3793
0
      free(id);
3794
0
      goto bad;
3795
0
    }
3796
7.00k
    node = calloc(1, sizeof(struct constraint_node));
3797
7.00k
    if (!node) {
3798
0
      yyerror("out of memory");
3799
0
      free(node);
3800
0
      goto bad;
3801
0
    }
3802
7.00k
    if (useexpr) {
3803
7.00k
      node->expr = expr;
3804
7.00k
      useexpr = 0;
3805
7.00k
    } else {
3806
0
      node->expr = constraint_expr_clone(expr);
3807
0
    }
3808
7.00k
    if (!node->expr) {
3809
0
      yyerror("out of memory");
3810
0
      free(node);
3811
0
      goto bad;
3812
0
    }
3813
7.00k
    node->permissions = 0;
3814
3815
7.00k
    node->next = cladatum->constraints;
3816
7.00k
    cladatum->constraints = node;
3817
3818
7.00k
    free(id);
3819
7.00k
  }
3820
3821
14.9k
  while ((id = queue_remove(id_queue))) {
3822
510k
    ebitmap_for_each_positive_bit(&classmap, enode, i) {
3823
8.06k
      cladatum = policydbp->class_val_to_struct[i];
3824
8.06k
      node = cladatum->constraints;
3825
3826
8.06k
      if (strcmp(id, "*") == 0) {
3827
11
        node->permissions = PERMISSION_MASK(
3828
11
          cladatum->permissions.nprim);
3829
11
        continue;
3830
11
      }
3831
3832
8.05k
      if (strcmp(id, "~") == 0) {
3833
1.06k
        node->permissions =
3834
1.06k
          ~node->permissions &
3835
1.06k
          PERMISSION_MASK(
3836
1.06k
            cladatum->permissions.nprim);
3837
1.06k
        if (node->permissions == 0) {
3838
37
          yywarn("omitting constraint with no permission set");
3839
37
          cladatum->constraints = node->next;
3840
37
          constraint_expr_destroy(node->expr);
3841
37
          free(node);
3842
37
        }
3843
1.06k
        continue;
3844
1.06k
      }
3845
3846
6.98k
      perdatum = (perm_datum_t *)hashtab_search(
3847
6.98k
        cladatum->permissions.table, (hashtab_key_t)id);
3848
6.98k
      if (!perdatum) {
3849
92
        if (cladatum->comdatum) {
3850
0
          perdatum =
3851
0
            (perm_datum_t *)hashtab_search(
3852
0
              cladatum->comdatum
3853
0
                ->permissions
3854
0
                .table,
3855
0
              (hashtab_key_t)id);
3856
0
        }
3857
92
        if (!perdatum) {
3858
92
          yyerror2("permission %s is not"
3859
92
             " defined for class %s",
3860
92
             id,
3861
92
             policydbp->p_class_val_to_name
3862
92
               [i]);
3863
92
          free(id);
3864
92
          goto bad;
3865
92
        }
3866
92
      }
3867
6.89k
      node->permissions |=
3868
6.89k
        (UINT32_C(1) << (perdatum->s.value - 1));
3869
6.89k
    }
3870
7.97k
    free(id);
3871
7.97k
  }
3872
3873
6.90k
  ebitmap_destroy(&classmap);
3874
3875
6.90k
  return 0;
3876
3877
245
bad:
3878
245
  ebitmap_destroy(&classmap);
3879
245
  if (useexpr)
3880
148
    constraint_expr_destroy(expr);
3881
3882
245
  return -1;
3883
6.99k
}
3884
3885
int define_validatetrans(constraint_expr_t *expr)
3886
1.21k
{
3887
1.21k
  struct constraint_node *node;
3888
1.21k
  char *id;
3889
1.21k
  class_datum_t *cladatum;
3890
1.21k
  ebitmap_t classmap;
3891
1.21k
  constraint_expr_t *e;
3892
1.21k
  int depth;
3893
1.21k
  unsigned char useexpr = 1;
3894
3895
1.21k
  if (pass == 1) {
3896
2.53k
    while ((id = queue_remove(id_queue)))
3897
1.42k
      free(id);
3898
1.10k
    return 0;
3899
1.10k
  }
3900
3901
109
  ebitmap_init(&classmap);
3902
3903
109
  depth = -1;
3904
51.5k
  for (e = expr; e; e = e->next) {
3905
51.4k
    switch (e->expr_type) {
3906
27.5k
    case CEXPR_NOT:
3907
27.5k
      if (depth < 0) {
3908
0
        yyerror("illegal validatetrans expression");
3909
0
        goto bad;
3910
0
      }
3911
27.5k
      break;
3912
27.5k
    case CEXPR_AND:
3913
11.9k
    case CEXPR_OR:
3914
11.9k
      if (depth < 1) {
3915
0
        yyerror("illegal validatetrans expression");
3916
0
        goto bad;
3917
0
      }
3918
11.9k
      depth--;
3919
11.9k
      break;
3920
1.33k
    case CEXPR_ATTR:
3921
12.0k
    case CEXPR_NAMES:
3922
12.0k
      if (depth == (CEXPR_MAXDEPTH - 1)) {
3923
1
        yyerror("validatetrans expression is too deep");
3924
1
        goto bad;
3925
1
      }
3926
12.0k
      depth++;
3927
12.0k
      break;
3928
0
    default:
3929
0
      yyerror("illegal validatetrans expression");
3930
0
      goto bad;
3931
51.4k
    }
3932
51.4k
  }
3933
108
  if (depth != 0) {
3934
0
    yyerror("illegal validatetrans expression");
3935
0
    goto bad;
3936
0
  }
3937
3938
136
  while ((id = queue_remove(id_queue))) {
3939
119
    if (!is_id_in_scope(SYM_CLASSES, id)) {
3940
0
      yyerror2("class %s is not within scope", id);
3941
0
      free(id);
3942
0
      goto bad;
3943
0
    }
3944
119
    cladatum = (class_datum_t *)hashtab_search(
3945
119
      policydbp->p_classes.table, (hashtab_key_t)id);
3946
119
    if (!cladatum) {
3947
91
      yyerror2("class %s is not defined", id);
3948
91
      free(id);
3949
91
      goto bad;
3950
91
    }
3951
28
    if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
3952
0
      yyerror("out of memory");
3953
0
      free(id);
3954
0
      goto bad;
3955
0
    }
3956
3957
28
    node = calloc(1, sizeof(struct constraint_node));
3958
28
    if (!node) {
3959
0
      yyerror("out of memory");
3960
0
      free(id);
3961
0
      goto bad;
3962
0
    }
3963
28
    if (useexpr) {
3964
28
      node->expr = expr;
3965
28
      useexpr = 0;
3966
28
    } else {
3967
0
      node->expr = constraint_expr_clone(expr);
3968
0
    }
3969
28
    node->permissions = 0;
3970
3971
28
    node->next = cladatum->validatetrans;
3972
28
    cladatum->validatetrans = node;
3973
3974
28
    free(id);
3975
28
  }
3976
3977
17
  ebitmap_destroy(&classmap);
3978
3979
17
  return 0;
3980
3981
92
bad:
3982
92
  ebitmap_destroy(&classmap);
3983
92
  if (useexpr)
3984
81
    constraint_expr_destroy(expr);
3985
3986
92
  return -1;
3987
108
}
3988
3989
uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
3990
3.98M
{
3991
3.98M
  struct constraint_expr *expr, *e1 = NULL, *e2;
3992
3.98M
  user_datum_t *user;
3993
3.98M
  role_datum_t *role;
3994
3.98M
  ebitmap_t negset;
3995
3.98M
  char *id;
3996
3.98M
  uint32_t val;
3997
3.98M
  int add = 1;
3998
3999
3.98M
  if (pass == 1) {
4000
2.01M
    if (expr_type == CEXPR_NAMES) {
4001
92.8k
      while ((id = queue_remove(id_queue)))
4002
46.9k
        free(id);
4003
45.8k
    }
4004
2.01M
    return 1; /* any non-NULL value */
4005
2.01M
  }
4006
4007
1.97M
  if ((expr = malloc(sizeof(*expr))) == NULL ||
4008
1.97M
      constraint_expr_init(expr) == -1) {
4009
0
    yyerror("out of memory");
4010
0
    free(expr);
4011
0
    return 0;
4012
0
  }
4013
1.97M
  expr->expr_type = expr_type;
4014
4015
1.97M
  switch (expr_type) {
4016
1.58M
  case CEXPR_NOT:
4017
1.58M
    e1 = NULL;
4018
1.58M
    e2 = (struct constraint_expr *)arg1;
4019
61.9M
    while (e2) {
4020
60.3M
      e1 = e2;
4021
60.3M
      e2 = e2->next;
4022
60.3M
    }
4023
1.58M
    if (!e1 || e1->next) {
4024
0
      yyerror("illegal constraint expression");
4025
0
      constraint_expr_destroy(expr);
4026
0
      return 0;
4027
0
    }
4028
1.58M
    e1->next = expr;
4029
1.58M
    return arg1;
4030
144k
  case CEXPR_AND:
4031
189k
  case CEXPR_OR:
4032
189k
    e1 = NULL;
4033
189k
    e2 = (struct constraint_expr *)arg1;
4034
419M
    while (e2) {
4035
418M
      e1 = e2;
4036
418M
      e2 = e2->next;
4037
418M
    }
4038
189k
    if (!e1 || e1->next) {
4039
0
      yyerror("illegal constraint expression");
4040
0
      constraint_expr_destroy(expr);
4041
0
      return 0;
4042
0
    }
4043
189k
    e1->next = (struct constraint_expr *)arg2;
4044
4045
189k
    e1 = NULL;
4046
189k
    e2 = (struct constraint_expr *)arg2;
4047
2.70M
    while (e2) {
4048
2.52M
      e1 = e2;
4049
2.52M
      e2 = e2->next;
4050
2.52M
    }
4051
189k
    if (!e1 || e1->next) {
4052
0
      yyerror("illegal constraint expression");
4053
0
      constraint_expr_destroy(expr);
4054
0
      return 0;
4055
0
    }
4056
189k
    e1->next = expr;
4057
189k
    return arg1;
4058
157k
  case CEXPR_ATTR:
4059
157k
    if (!mlspol && (arg1 >= CEXPR_L1L2)) {
4060
6
      yyerror("MLS constraint expression "
4061
6
        "in non-MLS configuration");
4062
6
      constraint_expr_destroy(expr);
4063
6
      return 0;
4064
6
    }
4065
157k
    expr->attr = arg1;
4066
157k
    expr->op = arg2;
4067
157k
    return (uintptr_t)expr;
4068
39.8k
  case CEXPR_NAMES:
4069
39.8k
    add = 1;
4070
39.8k
    expr->attr = arg1;
4071
39.8k
    expr->op = arg2;
4072
39.8k
    ebitmap_init(&negset);
4073
79.6k
    while ((id = (char *)queue_remove(id_queue))) {
4074
39.8k
      if (expr->attr & CEXPR_USER) {
4075
19.6k
        if (!is_id_in_scope(SYM_USERS, id)) {
4076
0
          yyerror2("user %s is not within scope",
4077
0
             id);
4078
0
          free(id);
4079
0
          constraint_expr_destroy(expr);
4080
0
          return 0;
4081
0
        }
4082
19.6k
        user = (user_datum_t *)hashtab_search(
4083
19.6k
          policydbp->p_users.table,
4084
19.6k
          (hashtab_key_t)id);
4085
19.6k
        if (!user) {
4086
14
          yyerror2("unknown user %s", id);
4087
14
          free(id);
4088
14
          constraint_expr_destroy(expr);
4089
14
          return 0;
4090
14
        }
4091
19.6k
        val = user->s.value;
4092
20.1k
      } else if (expr->attr & CEXPR_ROLE) {
4093
20.0k
        if (!is_id_in_scope(SYM_ROLES, id)) {
4094
1
          yyerror2("role %s is not within scope",
4095
1
             id);
4096
1
          constraint_expr_destroy(expr);
4097
1
          free(id);
4098
1
          return 0;
4099
1
        }
4100
20.0k
        role = (role_datum_t *)hashtab_search(
4101
20.0k
          policydbp->p_roles.table,
4102
20.0k
          (hashtab_key_t)id);
4103
20.0k
        if (!role) {
4104
22
          yyerror2("unknown role %s", id);
4105
22
          constraint_expr_destroy(expr);
4106
22
          free(id);
4107
22
          return 0;
4108
22
        }
4109
20.0k
        val = role->s.value;
4110
20.0k
      } else if (expr->attr & CEXPR_TYPE) {
4111
113
        if (set_types(expr->type_names, id, &add, 0)) {
4112
33
          constraint_expr_destroy(expr);
4113
33
          return 0;
4114
33
        }
4115
80
        continue;
4116
113
      } else {
4117
0
        yyerror("invalid constraint expression");
4118
0
        constraint_expr_destroy(expr);
4119
0
        free(id);
4120
0
        return 0;
4121
0
      }
4122
39.6k
      if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
4123
0
        yyerror("out of memory");
4124
0
        ebitmap_destroy(&expr->names);
4125
0
        free(id);
4126
0
        constraint_expr_destroy(expr);
4127
0
        return 0;
4128
0
      }
4129
39.6k
      free(id);
4130
39.6k
    }
4131
39.7k
    ebitmap_destroy(&negset);
4132
39.7k
    return (uintptr_t)expr;
4133
0
  default:
4134
0
    break;
4135
1.97M
  }
4136
4137
0
  yyerror("invalid constraint expression");
4138
0
  constraint_expr_destroy(expr);
4139
0
  return 0;
4140
1.97M
}
4141
4142
int define_conditional(cond_expr_t *expr, avrule_t *t_list, avrule_t *f_list)
4143
8.29k
{
4144
8.29k
  cond_expr_t *e;
4145
8.29k
  int depth, booleans, tunables;
4146
8.29k
  cond_node_t cn, *cn_old;
4147
8.29k
  const cond_bool_datum_t *bool_var;
4148
4149
  /* expression cannot be NULL */
4150
8.29k
  if (!expr) {
4151
321
    yyerror("illegal conditional expression");
4152
321
    return -1;
4153
321
  }
4154
7.97k
  if (!t_list) {
4155
3.33k
    if (!f_list) {
4156
      /* empty is fine, destroy expression and return */
4157
2.47k
      cond_expr_destroy(expr);
4158
2.47k
      return 0;
4159
2.47k
    }
4160
    /* Invert */
4161
862
    t_list = f_list;
4162
862
    f_list = NULL;
4163
862
    expr = define_cond_expr(COND_NOT, expr, NULL);
4164
862
    if (!expr) {
4165
0
      yyerror("unable to invert conditional expression");
4166
0
      return -1;
4167
0
    }
4168
862
  }
4169
4170
  /* verify expression */
4171
5.49k
  depth = -1;
4172
5.49k
  booleans = 0;
4173
5.49k
  tunables = 0;
4174
221k
  for (e = expr; e; e = e->next) {
4175
215k
    switch (e->expr_type) {
4176
149k
    case COND_NOT:
4177
149k
      if (depth < 0) {
4178
0
        yyerror("illegal conditional expression; Bad NOT");
4179
0
        return -1;
4180
0
      }
4181
149k
      break;
4182
149k
    case COND_AND:
4183
3.19k
    case COND_OR:
4184
4.92k
    case COND_XOR:
4185
25.4k
    case COND_EQ:
4186
30.3k
    case COND_NEQ:
4187
30.3k
      if (depth < 1) {
4188
0
        yyerror("illegal conditional expression; Bad binary op");
4189
0
        return -1;
4190
0
      }
4191
30.3k
      depth--;
4192
30.3k
      break;
4193
35.8k
    case COND_BOOL:
4194
35.8k
      if (depth == (COND_EXPR_MAXDEPTH - 1)) {
4195
2
        yyerror("conditional expression is like totally too deep");
4196
2
        return -1;
4197
2
      }
4198
35.8k
      depth++;
4199
4200
35.8k
      bool_var =
4201
35.8k
        policydbp->bool_val_to_struct[e->boolean - 1];
4202
35.8k
      if (bool_var->flags & COND_BOOL_FLAGS_TUNABLE) {
4203
339
        tunables = 1;
4204
35.5k
      } else {
4205
35.5k
        booleans = 1;
4206
35.5k
      }
4207
4208
35.8k
      break;
4209
0
    default:
4210
0
      yyerror("illegal conditional expression");
4211
0
      return -1;
4212
215k
    }
4213
215k
  }
4214
5.49k
  if (depth != 0) {
4215
0
    yyerror("illegal conditional expression");
4216
0
    return -1;
4217
0
  }
4218
5.49k
  if (booleans && tunables) {
4219
7
    yyerror("illegal conditional expression; Contains boolean and tunable");
4220
7
    return -1;
4221
7
  }
4222
4223
  /*  use tmp conditional node to partially build new node */
4224
5.48k
  memset(&cn, 0, sizeof(cn));
4225
5.48k
  cn.expr = expr;
4226
5.48k
  cn.avtrue_list = t_list;
4227
5.48k
  cn.avfalse_list = f_list;
4228
4229
  /* normalize/precompute expression */
4230
5.48k
  if (cond_normalize_expr(policydbp, &cn) < 0) {
4231
0
    yyerror("problem normalizing conditional expression");
4232
0
    return -1;
4233
0
  }
4234
4235
  /* get the existing conditional node, or create a new one */
4236
5.48k
  cn_old = get_current_cond_list(&cn);
4237
5.48k
  if (!cn_old) {
4238
0
    return -1;
4239
0
  }
4240
4241
5.48k
  append_cond_list(&cn);
4242
4243
  /* note that there is no check here for duplicate rules, nor
4244
   * check that rule already exists in base -- that will be
4245
   * handled during conditional expansion, in expand.c */
4246
4247
5.48k
  cn.avtrue_list = NULL;
4248
5.48k
  cn.avfalse_list = NULL;
4249
5.48k
  cond_node_destroy(&cn);
4250
4251
5.48k
  return 0;
4252
5.48k
}
4253
4254
cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
4255
454k
{
4256
454k
  struct cond_expr *expr, *e1 = NULL, *e2;
4257
454k
  cond_bool_datum_t *bool_var;
4258
454k
  char *id;
4259
4260
  /* expressions are handled in the second pass */
4261
454k
  if (pass == 1) {
4262
233k
    if (expr_type == COND_BOOL) {
4263
88.8k
      while ((id = queue_remove(id_queue))) {
4264
44.3k
        free(id);
4265
44.3k
      }
4266
44.4k
    }
4267
233k
    return (cond_expr_t *)1; /* any non-NULL value */
4268
233k
  }
4269
4270
  /* create a new expression struct */
4271
220k
  expr = calloc(1, sizeof(struct cond_expr));
4272
220k
  if (!expr) {
4273
0
    yyerror("out of memory");
4274
0
    return NULL;
4275
0
  }
4276
220k
  expr->expr_type = expr_type;
4277
4278
  /* create the type asked for */
4279
220k
  switch (expr_type) {
4280
150k
  case COND_NOT:
4281
150k
    e1 = NULL;
4282
150k
    e2 = (struct cond_expr *)arg1;
4283
6.55M
    while (e2) {
4284
6.40M
      e1 = e2;
4285
6.40M
      e2 = e2->next;
4286
6.40M
    }
4287
150k
    if (!e1 || e1->next) {
4288
15
      yyerror("illegal conditional NOT expression");
4289
15
      free(expr);
4290
15
      return NULL;
4291
15
    }
4292
150k
    e1->next = expr;
4293
150k
    return (struct cond_expr *)arg1;
4294
598
  case COND_AND:
4295
3.27k
  case COND_OR:
4296
5.06k
  case COND_XOR:
4297
25.7k
  case COND_EQ:
4298
30.7k
  case COND_NEQ:
4299
30.7k
    e1 = NULL;
4300
30.7k
    e2 = (struct cond_expr *)arg1;
4301
1.42M
    while (e2) {
4302
1.39M
      e1 = e2;
4303
1.39M
      e2 = e2->next;
4304
1.39M
    }
4305
30.7k
    if (!e1 || e1->next) {
4306
29
      yyerror("illegal left side of conditional binary op expression");
4307
29
      free(expr);
4308
29
      return NULL;
4309
29
    }
4310
30.7k
    e1->next = (struct cond_expr *)arg2;
4311
4312
30.7k
    e1 = NULL;
4313
30.7k
    e2 = (struct cond_expr *)arg2;
4314
478k
    while (e2) {
4315
447k
      e1 = e2;
4316
447k
      e2 = e2->next;
4317
447k
    }
4318
30.7k
    if (!e1 || e1->next) {
4319
44
      yyerror("illegal right side of conditional binary op expression");
4320
44
      cond_expr_destroy(arg1);
4321
44
      free(expr);
4322
44
      return NULL;
4323
44
    }
4324
30.7k
    e1->next = expr;
4325
30.7k
    return (struct cond_expr *)arg1;
4326
39.3k
  case COND_BOOL:
4327
39.3k
    id = (char *)queue_remove(id_queue);
4328
39.3k
    if (!id) {
4329
0
      yyerror("bad conditional; expected boolean id");
4330
0
      free(id);
4331
0
      free(expr);
4332
0
      return NULL;
4333
0
    }
4334
39.3k
    if (!is_id_in_scope(SYM_BOOLS, id)) {
4335
39
      yyerror2("boolean %s is not within scope", id);
4336
39
      free(id);
4337
39
      free(expr);
4338
39
      return NULL;
4339
39
    }
4340
39.2k
    bool_var = (cond_bool_datum_t *)hashtab_search(
4341
39.2k
      policydbp->p_bools.table, (hashtab_key_t)id);
4342
39.2k
    if (!bool_var) {
4343
477
      yyerror2("unknown boolean %s in conditional expression",
4344
477
         id);
4345
477
      free(expr);
4346
477
      free(id);
4347
477
      return NULL;
4348
477
    }
4349
38.8k
    expr->boolean = bool_var->s.value;
4350
38.8k
    free(id);
4351
38.8k
    return expr;
4352
0
  default:
4353
0
    yyerror("illegal conditional expression");
4354
0
    free(expr);
4355
0
    return NULL;
4356
220k
  }
4357
220k
}
4358
4359
static int set_user_roles(role_set_t *set, char *id)
4360
9.18k
{
4361
9.18k
  role_datum_t *r;
4362
4363
9.18k
  if (strcmp(id, "*") == 0) {
4364
4
    free(id);
4365
4
    yyerror("* is not allowed in user declarations");
4366
4
    return -1;
4367
4
  }
4368
4369
9.17k
  if (strcmp(id, "~") == 0) {
4370
1
    free(id);
4371
1
    yyerror("~ is not allowed in user declarations");
4372
1
    return -1;
4373
1
  }
4374
4375
9.17k
  if (!is_id_in_scope(SYM_ROLES, id)) {
4376
4
    yyerror2("role %s is not within scope", id);
4377
4
    free(id);
4378
4
    return -1;
4379
4
  }
4380
9.17k
  r = hashtab_search(policydbp->p_roles.table, id);
4381
9.17k
  if (!r) {
4382
833
    yyerror2("unknown role %s", id);
4383
833
    free(id);
4384
833
    return -1;
4385
833
  }
4386
4387
8.33k
  free(id);
4388
8.33k
  if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE))
4389
0
    goto oom;
4390
8.33k
  return 0;
4391
0
oom:
4392
0
  yyerror("out of memory");
4393
0
  return -1;
4394
8.33k
}
4395
4396
static int parse_categories(char *id, level_datum_t *levdatum, ebitmap_t *cats)
4397
1.22k
{
4398
1.22k
  cat_datum_t *cdatum;
4399
1.22k
  uint32_t range_start, range_end, i;
4400
4401
1.22k
  if (id_has_dot(id)) {
4402
442
    char *id_start = id;
4403
442
    char *id_end = strchr(id, '.');
4404
4405
442
    *(id_end++) = '\0';
4406
4407
442
    cdatum = (cat_datum_t *)hashtab_search(policydbp->p_cats.table,
4408
442
                   (hashtab_key_t)id_start);
4409
442
    if (!cdatum) {
4410
2
      yyerror2("unknown category %s", id_start);
4411
2
      return -1;
4412
2
    }
4413
440
    range_start = cdatum->s.value - 1;
4414
440
    cdatum = (cat_datum_t *)hashtab_search(policydbp->p_cats.table,
4415
440
                   (hashtab_key_t)id_end);
4416
440
    if (!cdatum) {
4417
1
      yyerror2("unknown category %s", id_end);
4418
1
      return -1;
4419
1
    }
4420
439
    range_end = cdatum->s.value - 1;
4421
4422
439
    if (range_end < range_start) {
4423
0
      yyerror2("category range %d-%d is invalid", range_start,
4424
0
         range_end);
4425
0
      return -1;
4426
0
    }
4427
785
  } else {
4428
785
    cdatum = (cat_datum_t *)hashtab_search(policydbp->p_cats.table,
4429
785
                   (hashtab_key_t)id);
4430
785
    if (!cdatum) {
4431
16
      yyerror2("unknown category %s", id);
4432
16
      return -1;
4433
16
    }
4434
769
    range_start = range_end = cdatum->s.value - 1;
4435
769
  }
4436
4437
2.41k
  for (i = range_start; i <= range_end; i++) {
4438
1.20k
    if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
4439
1
      uint32_t level_value = levdatum->level->sens - 1;
4440
1
      policydb_index_others(NULL, policydbp, 0);
4441
1
      yyerror2("category %s can not be associated "
4442
1
         "with level %s",
4443
1
         policydbp->p_cat_val_to_name[i],
4444
1
         policydbp->p_sens_val_to_name[level_value]);
4445
1
      return -1;
4446
1
    }
4447
1.20k
    if (ebitmap_set_bit(cats, i, TRUE)) {
4448
0
      yyerror("out of memory");
4449
0
      return -1;
4450
0
    }
4451
1.20k
  }
4452
4453
1.20k
  return 0;
4454
1.20k
}
4455
4456
static int mls_semantic_cats_merge(mls_semantic_cat_t **dst,
4457
           const mls_semantic_cat_t *src)
4458
8.54k
{
4459
8.54k
  mls_semantic_cat_t *new;
4460
4461
125k
  while (src) {
4462
116k
    new = malloc(sizeof(mls_semantic_cat_t));
4463
116k
    if (!new)
4464
0
      return -1;
4465
4466
116k
    mls_semantic_cat_init(new);
4467
116k
    new->low = src->low;
4468
116k
    new->high = src->high;
4469
116k
    new->next = *dst;
4470
116k
    *dst = new;
4471
4472
116k
    src = src->next;
4473
116k
  }
4474
4475
8.54k
  return 0;
4476
8.54k
}
4477
4478
static int mls_add_or_check_level(mls_semantic_level_t *dst,
4479
          const mls_semantic_level_t *src)
4480
12.7k
{
4481
12.7k
  if (!dst->sens) {
4482
4.23k
    if (mls_semantic_level_cpy(dst, src) < 0) {
4483
0
      yyerror("out of memory");
4484
0
      return -1;
4485
0
    }
4486
8.54k
  } else {
4487
8.54k
    if (dst->sens != src->sens) {
4488
3
      return -1;
4489
3
    }
4490
    /* Duplicate cats won't cause problems, but different cats will
4491
     * result in an error during expansion */
4492
8.54k
    if (mls_semantic_cats_merge(&dst->cat, src->cat) < 0) {
4493
0
      yyerror("out of memory");
4494
0
      return -1;
4495
0
    }
4496
8.54k
  }
4497
4498
12.7k
  return 0;
4499
12.7k
}
4500
4501
static int parse_semantic_categories(char *id,
4502
             level_datum_t *levdatum
4503
             __attribute__((unused)),
4504
             mls_semantic_cat_t **cats)
4505
7.02k
{
4506
7.02k
  cat_datum_t *cdatum;
4507
7.02k
  mls_semantic_cat_t *newcat;
4508
7.02k
  unsigned int range_start, range_end;
4509
4510
7.02k
  if (id_has_dot(id)) {
4511
17
    char *id_start = id;
4512
17
    char *id_end = strchr(id, '.');
4513
4514
17
    *(id_end++) = '\0';
4515
4516
17
    cdatum = (cat_datum_t *)hashtab_search(policydbp->p_cats.table,
4517
17
                   (hashtab_key_t)id_start);
4518
17
    if (!cdatum) {
4519
2
      yyerror2("unknown category %s", id_start);
4520
2
      return -1;
4521
2
    }
4522
15
    range_start = cdatum->s.value;
4523
4524
15
    cdatum = (cat_datum_t *)hashtab_search(policydbp->p_cats.table,
4525
15
                   (hashtab_key_t)id_end);
4526
15
    if (!cdatum) {
4527
2
      yyerror2("unknown category %s", id_end);
4528
2
      return -1;
4529
2
    }
4530
13
    range_end = cdatum->s.value;
4531
7.00k
  } else {
4532
7.00k
    cdatum = (cat_datum_t *)hashtab_search(policydbp->p_cats.table,
4533
7.00k
                   (hashtab_key_t)id);
4534
7.00k
    if (!cdatum) {
4535
16
      yyerror2("unknown category %s", id);
4536
16
      return -1;
4537
16
    }
4538
6.98k
    range_start = range_end = cdatum->s.value;
4539
6.98k
  }
4540
4541
7.00k
  newcat = malloc(sizeof(mls_semantic_cat_t));
4542
7.00k
  if (!newcat) {
4543
0
    yyerror("out of memory");
4544
0
    return -1;
4545
0
  }
4546
4547
7.00k
  mls_semantic_cat_init(newcat);
4548
7.00k
  newcat->next = *cats;
4549
7.00k
  newcat->low = range_start;
4550
7.00k
  newcat->high = range_end;
4551
4552
7.00k
  *cats = newcat;
4553
4554
7.00k
  return 0;
4555
7.00k
}
4556
4557
int define_user(void)
4558
33.3k
{
4559
33.3k
  const char *username;
4560
33.3k
  char *id;
4561
33.3k
  user_datum_t *usrdatum, *usr_global;
4562
33.3k
  level_datum_t *levdatum;
4563
33.3k
  int l;
4564
4565
33.3k
  if (pass == 1) {
4566
67.8k
    while ((id = queue_remove(id_queue)))
4567
43.6k
      free(id);
4568
24.1k
    if (mlspol) {
4569
20.5k
      while ((id = queue_remove(id_queue)))
4570
10.2k
        free(id);
4571
10.2k
      id = queue_remove(id_queue);
4572
10.2k
      free(id);
4573
16.0k
      for (l = 0; l < 2; l++) {
4574
23.5k
        while ((id = queue_remove(id_queue))) {
4575
7.46k
          free(id);
4576
7.46k
        }
4577
16.0k
        id = queue_remove(id_queue);
4578
16.0k
        if (!id)
4579
10.2k
          break;
4580
5.80k
        free(id);
4581
5.80k
      }
4582
10.2k
    }
4583
24.1k
    return 0;
4584
24.1k
  }
4585
4586
9.20k
  username = queue_head(id_queue);
4587
9.20k
  if (!username) {
4588
6
    yyerror("no user name");
4589
6
    return -1;
4590
6
  }
4591
4592
9.19k
  id = strdup(username);
4593
9.19k
  if (!id) {
4594
0
    yyerror("out of memory");
4595
0
    return -1;
4596
0
  }
4597
4598
9.19k
  if ((usrdatum = declare_user()) == NULL) {
4599
3
    free(id);
4600
3
    return -1;
4601
3
  }
4602
4603
9.19k
  usr_global =
4604
9.19k
    hashtab_search(policydbp->p_users.table, (hashtab_key_t)id);
4605
9.19k
  free(id);
4606
4607
17.5k
  while ((id = queue_remove(id_queue))) {
4608
9.18k
    if (set_user_roles(&usrdatum->roles, id))
4609
842
      return -1;
4610
9.18k
  }
4611
4612
8.35k
  if (mlspol) {
4613
7.75k
    id = queue_remove(id_queue);
4614
7.75k
    if (!id) {
4615
4
      yyerror("no default level specified for user");
4616
4
      return -1;
4617
4
    }
4618
4619
7.75k
    levdatum = (level_datum_t *)hashtab_search(
4620
7.75k
      policydbp->p_levels.table, (hashtab_key_t)id);
4621
7.75k
    if (!levdatum) {
4622
20
      yyerror2("unknown sensitivity %s used in user"
4623
20
         " level definition",
4624
20
         id);
4625
20
      free(id);
4626
20
      return -1;
4627
20
    }
4628
7.73k
    free(id);
4629
4630
7.73k
    usrdatum->dfltlevel.sens = levdatum->level->sens;
4631
4632
8.63k
    while ((id = queue_remove(id_queue))) {
4633
      /* This will add to any already existing categories */
4634
911
      if (parse_semantic_categories(
4635
911
            id, levdatum, &usrdatum->dfltlevel.cat)) {
4636
3
        free(id);
4637
3
        return -1;
4638
3
      }
4639
908
      free(id);
4640
908
    }
4641
4642
7.72k
    id = queue_remove(id_queue);
4643
4644
12.8k
    for (l = 0; l < 2; l++) {
4645
12.8k
      levdatum = (level_datum_t *)hashtab_search(
4646
12.8k
        policydbp->p_levels.table, (hashtab_key_t)id);
4647
12.8k
      if (!levdatum) {
4648
27
        yyerror2("unknown sensitivity %s used in user"
4649
27
           " range definition",
4650
27
           id);
4651
27
        free(id);
4652
27
        return -1;
4653
27
      }
4654
12.7k
      free(id);
4655
4656
12.7k
      usrdatum->range.level[l].sens = levdatum->level->sens;
4657
4658
18.8k
      while ((id = queue_remove(id_queue))) {
4659
        /* This will add to any already existing categories */
4660
6.10k
        if (parse_semantic_categories(
4661
6.10k
              id, levdatum,
4662
6.10k
              &usrdatum->range.level[l].cat)) {
4663
16
          free(id);
4664
16
          return -1;
4665
16
        }
4666
6.09k
        free(id);
4667
6.09k
      }
4668
4669
12.7k
      id = queue_remove(id_queue);
4670
12.7k
      if (!id)
4671
7.68k
        break;
4672
12.7k
    }
4673
4674
7.68k
    if (l == 0) {
4675
2.61k
      if (mls_semantic_level_cpy(&usrdatum->range.level[1],
4676
2.61k
               &usrdatum->range.level[0])) {
4677
0
        yyerror("out of memory");
4678
0
        return -1;
4679
0
      }
4680
2.61k
    }
4681
4682
7.68k
    if (usr_global && usr_global != usrdatum) {
4683
4.26k
      if (mls_add_or_check_level(&usr_global->dfltlevel,
4684
4.26k
               &usrdatum->dfltlevel)) {
4685
1
        yyerror("Problem with user default level");
4686
1
        return -1;
4687
1
      }
4688
4.25k
      if (mls_add_or_check_level(&usr_global->range.level[0],
4689
4.25k
               &usrdatum->range.level[0])) {
4690
1
        yyerror("Problem with user low level");
4691
1
        return -1;
4692
1
      }
4693
4.25k
      if (mls_add_or_check_level(&usr_global->range.level[1],
4694
4.25k
               &usrdatum->range.level[1])) {
4695
1
        yyerror("Problem with user high level");
4696
1
        return -1;
4697
1
      }
4698
4.25k
    }
4699
7.68k
  }
4700
8.28k
  return 0;
4701
8.35k
}
4702
4703
static int parse_security_context(context_struct_t *c)
4704
22.2k
{
4705
22.2k
  char *id;
4706
22.2k
  role_datum_t *role;
4707
22.2k
  type_datum_t *typdatum;
4708
22.2k
  user_datum_t *usrdatum;
4709
22.2k
  level_datum_t *levdatum;
4710
22.2k
  int l;
4711
4712
22.2k
  if (pass == 1) {
4713
16.1k
    id = queue_remove(id_queue);
4714
16.1k
    free(id); /* user  */
4715
16.1k
    id = queue_remove(id_queue);
4716
16.1k
    free(id); /* role  */
4717
16.1k
    id = queue_remove(id_queue);
4718
16.1k
    free(id); /* type  */
4719
16.1k
    if (mlspol) {
4720
12.5k
      id = queue_remove(id_queue);
4721
12.5k
      free(id);
4722
13.1k
      for (l = 0; l < 2; l++) {
4723
16.5k
        while ((id = queue_remove(id_queue))) {
4724
3.42k
          free(id);
4725
3.42k
        }
4726
13.1k
        id = queue_remove(id_queue);
4727
13.1k
        if (!id)
4728
12.5k
          break;
4729
576
        free(id);
4730
576
      }
4731
12.5k
    }
4732
16.1k
    return 0;
4733
16.1k
  }
4734
4735
  /* check context c to make sure ok to dereference c later */
4736
6.03k
  if (c == NULL) {
4737
0
    yyerror("null context pointer!");
4738
0
    return -1;
4739
0
  }
4740
4741
6.03k
  context_init(c);
4742
4743
  /* extract the user */
4744
6.03k
  id = queue_remove(id_queue);
4745
6.03k
  if (!id) {
4746
1
    yyerror("no effective user?");
4747
1
    goto bad;
4748
1
  }
4749
6.03k
  if (!is_id_in_scope(SYM_USERS, id)) {
4750
1
    yyerror2("user %s is not within scope", id);
4751
1
    free(id);
4752
1
    goto bad;
4753
1
  }
4754
6.03k
  usrdatum = (user_datum_t *)hashtab_search(policydbp->p_users.table,
4755
6.03k
              (hashtab_key_t)id);
4756
6.03k
  if (!usrdatum) {
4757
175
    yyerror2("user %s is not defined", id);
4758
175
    free(id);
4759
175
    goto bad;
4760
175
  }
4761
5.85k
  c->user = usrdatum->s.value;
4762
4763
  /* no need to keep the user name */
4764
5.85k
  free(id);
4765
4766
  /* extract the role */
4767
5.85k
  id = (char *)queue_remove(id_queue);
4768
5.85k
  if (!id) {
4769
0
    yyerror("no role name for sid context definition?");
4770
0
    return -1;
4771
0
  }
4772
5.85k
  if (!is_id_in_scope(SYM_ROLES, id)) {
4773
1
    yyerror2("role %s is not within scope", id);
4774
1
    free(id);
4775
1
    return -1;
4776
1
  }
4777
5.85k
  role = (role_datum_t *)hashtab_search(policydbp->p_roles.table,
4778
5.85k
                (hashtab_key_t)id);
4779
5.85k
  if (!role) {
4780
105
    yyerror2("role %s is not defined", id);
4781
105
    free(id);
4782
105
    return -1;
4783
105
  }
4784
5.75k
  c->role = role->s.value;
4785
4786
  /* no need to keep the role name */
4787
5.75k
  free(id);
4788
4789
  /* extract the type */
4790
5.75k
  id = (char *)queue_remove(id_queue);
4791
5.75k
  if (!id) {
4792
0
    yyerror("no type name for sid context definition?");
4793
0
    return -1;
4794
0
  }
4795
5.75k
  if (!is_id_in_scope(SYM_TYPES, id)) {
4796
1
    yyerror2("type %s is not within scope", id);
4797
1
    free(id);
4798
1
    return -1;
4799
1
  }
4800
5.75k
  typdatum = (type_datum_t *)hashtab_search(policydbp->p_types.table,
4801
5.75k
              (hashtab_key_t)id);
4802
5.75k
  if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
4803
96
    yyerror2("type %s is not defined or is an attribute", id);
4804
96
    free(id);
4805
96
    return -1;
4806
96
  }
4807
5.65k
  c->type = typdatum->s.value;
4808
4809
  /* no need to keep the type name */
4810
5.65k
  free(id);
4811
4812
5.65k
  if (mlspol) {
4813
    /* extract the low sensitivity */
4814
5.65k
    id = (char *)queue_remove(id_queue);
4815
5.65k
    if (!id) {
4816
4
      yyerror("no sensitivity name for sid context"
4817
4
        " definition?");
4818
4
      return -1;
4819
4
    }
4820
4821
5.80k
    for (l = 0; l < 2; l++) {
4822
5.80k
      levdatum = (level_datum_t *)hashtab_search(
4823
5.80k
        policydbp->p_levels.table, (hashtab_key_t)id);
4824
5.80k
      if (!levdatum) {
4825
14
        yyerror2("Sensitivity %s is not defined", id);
4826
14
        free(id);
4827
14
        return -1;
4828
14
      }
4829
5.78k
      free(id);
4830
5.78k
      c->range.level[l].sens = levdatum->level->sens;
4831
4832
      /* extract low category set */
4833
6.99k
      while ((id = queue_remove(id_queue))) {
4834
1.22k
        if (parse_categories(id, levdatum,
4835
1.22k
                 &c->range.level[l].cat)) {
4836
20
          free(id);
4837
20
          return -1;
4838
20
        }
4839
1.20k
        free(id);
4840
1.20k
      }
4841
4842
      /* extract high sensitivity */
4843
5.76k
      id = (char *)queue_remove(id_queue);
4844
5.76k
      if (!id)
4845
5.61k
        break;
4846
5.76k
    }
4847
4848
5.61k
    if (l == 0) {
4849
5.45k
      c->range.level[1].sens = c->range.level[0].sens;
4850
5.45k
      if (ebitmap_cpy(&c->range.level[1].cat,
4851
5.45k
          &c->range.level[0].cat)) {
4852
0
        yyerror("out of memory");
4853
0
        goto bad;
4854
0
      }
4855
5.45k
    }
4856
5.61k
  }
4857
4858
5.61k
  if (!policydb_context_isvalid(policydbp, c)) {
4859
28
    yyerror("invalid security context");
4860
28
    goto bad;
4861
28
  }
4862
5.58k
  return 0;
4863
4864
205
bad:
4865
205
  context_destroy(c);
4866
4867
205
  return -1;
4868
5.61k
}
4869
4870
int define_initial_sid_context(void)
4871
9.58k
{
4872
9.58k
  char *id;
4873
9.58k
  ocontext_t *c, *head;
4874
4875
9.58k
  if (pass == 1) {
4876
6.36k
    id = (char *)queue_remove(id_queue);
4877
6.36k
    free(id);
4878
6.36k
    parse_security_context(NULL);
4879
6.36k
    return 0;
4880
6.36k
  }
4881
4882
3.22k
  id = (char *)queue_remove(id_queue);
4883
3.22k
  if (!id) {
4884
1
    yyerror("no sid name for SID context definition?");
4885
1
    return -1;
4886
1
  }
4887
3.21k
  head = policydbp->ocontexts[OCON_ISID];
4888
5.89k
  for (c = head; c; c = c->next) {
4889
5.68k
    if (!strcmp(id, c->u.name))
4890
3.01k
      break;
4891
5.68k
  }
4892
4893
3.21k
  if (!c) {
4894
209
    yyerror2("SID %s is not defined", id);
4895
209
    free(id);
4896
209
    return -1;
4897
209
  }
4898
3.01k
  if (c->context[0].user) {
4899
2
    yyerror2("The context for SID %s is multiply defined", id);
4900
2
    free(id);
4901
2
    return -1;
4902
2
  }
4903
  /* no need to keep the sid name */
4904
3.00k
  free(id);
4905
4906
3.00k
  if (parse_security_context(&c->context[0]))
4907
79
    return -1;
4908
4909
2.92k
  return 0;
4910
3.00k
}
4911
4912
int define_pirq_context(unsigned int pirq)
4913
78
{
4914
78
  ocontext_t *newc, *c, *l, *head;
4915
4916
78
  if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4917
1
    yyerror("pirqcon not supported for target");
4918
1
    return -1;
4919
1
  }
4920
4921
77
  if (pass == 1) {
4922
77
    parse_security_context(NULL);
4923
77
    return 0;
4924
77
  }
4925
4926
0
  if (pirq > 0xffff) {
4927
0
    yyerror2("pirq %u out of range", pirq);
4928
0
    return -1;
4929
0
  }
4930
4931
0
  newc = calloc(1, sizeof(ocontext_t));
4932
0
  if (!newc) {
4933
0
    yyerror("out of memory");
4934
0
    return -1;
4935
0
  }
4936
4937
0
  newc->u.pirq = pirq;
4938
4939
0
  if (parse_security_context(&newc->context[0])) {
4940
0
    free(newc);
4941
0
    return -1;
4942
0
  }
4943
4944
0
  head = policydbp->ocontexts[OCON_XEN_PIRQ];
4945
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
4946
0
    unsigned int pirq2;
4947
4948
0
    pirq2 = c->u.pirq;
4949
0
    if (pirq == pirq2) {
4950
0
      yyerror2("duplicate pirqcon entry for %d ", pirq);
4951
0
      goto bad;
4952
0
    }
4953
0
  }
4954
4955
0
  if (l)
4956
0
    l->next = newc;
4957
0
  else
4958
0
    policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
4959
4960
0
  return 0;
4961
4962
0
bad:
4963
0
  free(newc);
4964
0
  return -1;
4965
0
}
4966
4967
int define_iomem_context(uint64_t low, uint64_t high)
4968
973
{
4969
973
  ocontext_t *newc, *c, *l, *head;
4970
4971
973
  if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4972
2
    yyerror("iomemcon not supported for target");
4973
2
    return -1;
4974
2
  }
4975
4976
971
  if (pass == 1) {
4977
971
    parse_security_context(NULL);
4978
971
    return 0;
4979
971
  }
4980
4981
0
  newc = calloc(1, sizeof(ocontext_t));
4982
0
  if (!newc) {
4983
0
    yyerror("out of memory");
4984
0
    return -1;
4985
0
  }
4986
4987
0
  newc->u.iomem.low_iomem = low;
4988
0
  newc->u.iomem.high_iomem = high;
4989
4990
0
  if (low > high) {
4991
0
    yyerror2("low memory 0x%" PRIx64
4992
0
       " exceeds high memory 0x%" PRIx64 "",
4993
0
       low, high);
4994
0
    free(newc);
4995
0
    return -1;
4996
0
  }
4997
4998
0
  if (parse_security_context(&newc->context[0])) {
4999
0
    free(newc);
5000
0
    return -1;
5001
0
  }
5002
5003
0
  head = policydbp->ocontexts[OCON_XEN_IOMEM];
5004
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
5005
0
    uint64_t low2, high2;
5006
5007
0
    low2 = c->u.iomem.low_iomem;
5008
0
    high2 = c->u.iomem.high_iomem;
5009
0
    if (low <= high2 && low2 <= high) {
5010
0
      yyerror2("iomemcon entry for 0x%" PRIx64 "-0x%" PRIx64
5011
0
         " overlaps with "
5012
0
         "earlier entry 0x%" PRIx64 "-0x%" PRIx64 "",
5013
0
         low, high, low2, high2);
5014
0
      goto bad;
5015
0
    }
5016
0
  }
5017
5018
0
  if (l)
5019
0
    l->next = newc;
5020
0
  else
5021
0
    policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
5022
5023
0
  return 0;
5024
5025
0
bad:
5026
0
  free(newc);
5027
0
  return -1;
5028
0
}
5029
5030
int define_ioport_context(unsigned long low, unsigned long high)
5031
396
{
5032
396
  ocontext_t *newc, *c, *l, *head;
5033
5034
396
  if (policydbp->target_platform != SEPOL_TARGET_XEN) {
5035
2
    yyerror("ioportcon not supported for target");
5036
2
    return -1;
5037
2
  }
5038
5039
394
  if (pass == 1) {
5040
394
    parse_security_context(NULL);
5041
394
    return 0;
5042
394
  }
5043
5044
0
  newc = calloc(1, sizeof(ocontext_t));
5045
0
  if (!newc) {
5046
0
    yyerror("out of memory");
5047
0
    return -1;
5048
0
  }
5049
5050
0
  newc->u.ioport.low_ioport = low;
5051
0
  newc->u.ioport.high_ioport = high;
5052
5053
0
  if (low > high) {
5054
0
    yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low,
5055
0
       high);
5056
0
    free(newc);
5057
0
    return -1;
5058
0
  }
5059
5060
0
  if (parse_security_context(&newc->context[0])) {
5061
0
    free(newc);
5062
0
    return -1;
5063
0
  }
5064
5065
0
  head = policydbp->ocontexts[OCON_XEN_IOPORT];
5066
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
5067
0
    uint32_t low2, high2;
5068
5069
0
    low2 = c->u.ioport.low_ioport;
5070
0
    high2 = c->u.ioport.high_ioport;
5071
0
    if (low <= high2 && low2 <= high) {
5072
0
      yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with"
5073
0
         "earlier entry 0x%x-0x%x",
5074
0
         low, high, low2, high2);
5075
0
      goto bad;
5076
0
    }
5077
0
  }
5078
5079
0
  if (l)
5080
0
    l->next = newc;
5081
0
  else
5082
0
    policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
5083
5084
0
  return 0;
5085
5086
0
bad:
5087
0
  free(newc);
5088
0
  return -1;
5089
0
}
5090
5091
int define_pcidevice_context(unsigned long device)
5092
67
{
5093
67
  ocontext_t *newc, *c, *l, *head;
5094
5095
67
  if (policydbp->target_platform != SEPOL_TARGET_XEN) {
5096
1
    yyerror("pcidevicecon not supported for target");
5097
1
    return -1;
5098
1
  }
5099
5100
66
  if (pass == 1) {
5101
66
    parse_security_context(NULL);
5102
66
    return 0;
5103
66
  }
5104
5105
0
  newc = calloc(1, sizeof(ocontext_t));
5106
0
  if (!newc) {
5107
0
    yyerror("out of memory");
5108
0
    return -1;
5109
0
  }
5110
5111
0
  newc->u.device = device;
5112
5113
0
  if (parse_security_context(&newc->context[0])) {
5114
0
    free(newc);
5115
0
    return -1;
5116
0
  }
5117
5118
0
  head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
5119
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
5120
0
    unsigned int device2;
5121
5122
0
    device2 = c->u.device;
5123
0
    if (device == device2) {
5124
0
      yyerror2("duplicate pcidevicecon entry for 0x%lx",
5125
0
         device);
5126
0
      goto bad;
5127
0
    }
5128
0
  }
5129
5130
0
  if (l)
5131
0
    l->next = newc;
5132
0
  else
5133
0
    policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
5134
5135
0
  return 0;
5136
5137
0
bad:
5138
0
  free(newc);
5139
0
  return -1;
5140
0
}
5141
5142
int define_devicetree_context(void)
5143
218
{
5144
218
  ocontext_t *newc, *c, *l, *head;
5145
218
  char *path;
5146
5147
218
  if (policydbp->target_platform != SEPOL_TARGET_XEN) {
5148
2
    yyerror("devicetreecon not supported for target");
5149
2
    return -1;
5150
2
  }
5151
5152
216
  if (pass == 1) {
5153
216
    free(queue_remove(id_queue));
5154
216
    parse_security_context(NULL);
5155
216
    return 0;
5156
216
  }
5157
5158
0
  path = (char *)queue_remove(id_queue);
5159
0
  if (!path) {
5160
0
    yyerror("Missing devicetreepath");
5161
0
    return -1;
5162
0
  }
5163
5164
0
  if (!is_valid_dt_path(path)) {
5165
0
    yyerror2("invalid devicetreecon path \"%s\"", path);
5166
0
    free(path);
5167
0
    return -1;
5168
0
  }
5169
5170
0
  newc = calloc(1, sizeof(ocontext_t));
5171
0
  if (!newc) {
5172
0
    yyerror("out of memory");
5173
0
    free(path);
5174
0
    return -1;
5175
0
  }
5176
5177
0
  newc->u.name = path;
5178
5179
0
  if (parse_security_context(&newc->context[0])) {
5180
0
    free(newc->u.name);
5181
0
    free(newc);
5182
0
    return -1;
5183
0
  }
5184
5185
0
  head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
5186
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
5187
0
    if (strcmp(newc->u.name, c->u.name) == 0) {
5188
0
      yyerror2("duplicate devicetree entry for '%s'",
5189
0
         newc->u.name);
5190
0
      goto bad;
5191
0
    }
5192
0
  }
5193
5194
0
  if (l)
5195
0
    l->next = newc;
5196
0
  else
5197
0
    policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
5198
5199
0
  return 0;
5200
5201
0
bad:
5202
0
  free(newc->u.name);
5203
0
  free(newc);
5204
0
  return -1;
5205
0
}
5206
5207
int define_port_context(unsigned int low, unsigned int high)
5208
503
{
5209
503
  ocontext_t *newc, *c, *l, *head;
5210
503
  unsigned int protocol;
5211
503
  char *id;
5212
5213
503
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5214
2
    yyerror("portcon not supported for target");
5215
2
    return -1;
5216
2
  }
5217
5218
501
  if (pass == 1) {
5219
424
    id = (char *)queue_remove(id_queue);
5220
424
    free(id);
5221
424
    parse_security_context(NULL);
5222
424
    return 0;
5223
424
  }
5224
5225
77
  newc = calloc(1, sizeof(ocontext_t));
5226
77
  if (!newc) {
5227
0
    yyerror("out of memory");
5228
0
    return -1;
5229
0
  }
5230
5231
77
  id = (char *)queue_remove(id_queue);
5232
77
  if (!id) {
5233
0
    free(newc);
5234
0
    return -1;
5235
0
  }
5236
77
  if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
5237
0
    protocol = IPPROTO_TCP;
5238
77
  } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
5239
0
    protocol = IPPROTO_UDP;
5240
77
  } else if ((strcmp(id, "dccp") == 0) || (strcmp(id, "DCCP") == 0)) {
5241
6
    protocol = IPPROTO_DCCP;
5242
71
  } else if ((strcmp(id, "sctp") == 0) || (strcmp(id, "SCTP") == 0)) {
5243
0
    protocol = IPPROTO_SCTP;
5244
71
  } else {
5245
71
    yyerror2("unrecognized protocol %s", id);
5246
71
    goto bad;
5247
71
  }
5248
5249
6
  if (low == 0 || low > high || high > 0xffff) {
5250
2
    yyerror2("Invalid port range %u-%u", low, high);
5251
2
    goto bad;
5252
2
  }
5253
5254
4
  newc->u.port.protocol = protocol;
5255
4
  newc->u.port.low_port = low;
5256
4
  newc->u.port.high_port = high;
5257
5258
4
  if (parse_security_context(&newc->context[0])) {
5259
4
    goto bad;
5260
4
  }
5261
5262
  /* Preserve the matching order specified in the configuration. */
5263
0
  head = policydbp->ocontexts[OCON_PORT];
5264
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
5265
0
    unsigned int prot2, low2, high2;
5266
5267
0
    prot2 = c->u.port.protocol;
5268
0
    low2 = c->u.port.low_port;
5269
0
    high2 = c->u.port.high_port;
5270
0
    if (protocol != prot2)
5271
0
      continue;
5272
0
    if (low == low2 && high == high2) {
5273
0
      yyerror2("duplicate portcon entry for %s %d-%d ", id,
5274
0
         low, high);
5275
0
      goto bad;
5276
0
    }
5277
0
    if (low2 <= low && high2 >= high) {
5278
0
      yyerror2("portcon entry for %s %d-%d hidden by earlier "
5279
0
         "entry for %d-%d",
5280
0
         id, low, high, low2, high2);
5281
0
      goto bad;
5282
0
    }
5283
0
  }
5284
5285
0
  if (l)
5286
0
    l->next = newc;
5287
0
  else
5288
0
    policydbp->ocontexts[OCON_PORT] = newc;
5289
5290
0
  free(id);
5291
0
  return 0;
5292
5293
77
bad:
5294
77
  free(id);
5295
77
  free(newc);
5296
77
  return -1;
5297
0
}
5298
5299
int define_ibpkey_context(unsigned int low, unsigned int high)
5300
1.00k
{
5301
1.00k
  ocontext_t *newc, *c, *l, *head;
5302
1.00k
  struct in6_addr subnet_prefix;
5303
1.00k
  char *id;
5304
1.00k
  int rc = 0;
5305
5306
1.00k
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5307
2
    yyerror("ibpkeycon not supported for target");
5308
2
    return -1;
5309
2
  }
5310
5311
998
  if (pass == 1) {
5312
712
    id = (char *)queue_remove(id_queue);
5313
712
    free(id);
5314
712
    parse_security_context(NULL);
5315
712
    return 0;
5316
712
  }
5317
5318
286
  newc = calloc(1, sizeof(*newc));
5319
286
  if (!newc) {
5320
0
    yyerror("out of memory");
5321
0
    return -1;
5322
0
  }
5323
5324
286
  id = queue_remove(id_queue);
5325
286
  if (!id) {
5326
0
    yyerror("failed to read the subnet prefix");
5327
0
    rc = -1;
5328
0
    goto out;
5329
0
  }
5330
5331
286
  rc = inet_pton(AF_INET6, id, &subnet_prefix);
5332
286
  free(id);
5333
286
  if (rc < 1) {
5334
1
    yyerror("failed to parse the subnet prefix");
5335
1
    if (rc == 0)
5336
1
      rc = -1;
5337
1
    goto out;
5338
1
  }
5339
5340
285
  if (subnet_prefix.s6_addr32[2] || subnet_prefix.s6_addr32[3]) {
5341
5
    yyerror("subnet prefix should be 0's in the low order 64 bits.");
5342
5
    rc = -1;
5343
5
    goto out;
5344
5
  }
5345
5346
280
  if (low > 0xffff || high > 0xffff) {
5347
19
    yyerror("pkey value too large, pkeys are 16 bits.");
5348
19
    rc = -1;
5349
19
    goto out;
5350
19
  }
5351
5352
261
  memcpy(&newc->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0],
5353
261
         sizeof(newc->u.ibpkey.subnet_prefix));
5354
5355
261
  newc->u.ibpkey.low_pkey = low;
5356
261
  newc->u.ibpkey.high_pkey = high;
5357
5358
261
  if (low > high) {
5359
16
    yyerror2("low pkey %d exceeds high pkey %d", low, high);
5360
16
    rc = -1;
5361
16
    goto out;
5362
16
  }
5363
5364
245
  rc = parse_security_context(&newc->context[0]);
5365
245
  if (rc)
5366
26
    goto out;
5367
5368
  /* Preserve the matching order specified in the configuration. */
5369
219
  head = policydbp->ocontexts[OCON_IBPKEY];
5370
508
  for (l = NULL, c = head; c; l = c, c = c->next) {
5371
296
    unsigned int low2, high2;
5372
5373
296
    low2 = c->u.ibpkey.low_pkey;
5374
296
    high2 = c->u.ibpkey.high_pkey;
5375
5376
296
    if (low == low2 && high == high2 &&
5377
8
        c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5378
4
      yyerror2("duplicate ibpkeycon entry for %d-%d ", low,
5379
4
         high);
5380
4
      rc = -1;
5381
4
      goto out;
5382
4
    }
5383
292
    if (low2 <= low && high2 >= high &&
5384
7
        c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5385
3
      yyerror2(
5386
3
        "ibpkeycon entry for %d-%d hidden by earlier entry for %d-%d",
5387
3
        low, high, low2, high2);
5388
3
      rc = -1;
5389
3
      goto out;
5390
3
    }
5391
292
  }
5392
5393
212
  if (l)
5394
130
    l->next = newc;
5395
82
  else
5396
82
    policydbp->ocontexts[OCON_IBPKEY] = newc;
5397
5398
212
  return 0;
5399
5400
74
out:
5401
74
  free(newc);
5402
74
  return rc;
5403
219
}
5404
5405
int define_ibendport_context(unsigned int port)
5406
68
{
5407
68
  ocontext_t *newc, *c, *l, *head;
5408
68
  char *id;
5409
68
  int rc = 0;
5410
5411
68
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5412
1
    yyerror("ibendportcon not supported for target");
5413
1
    return -1;
5414
1
  }
5415
5416
67
  if (pass == 1) {
5417
67
    id = (char *)queue_remove(id_queue);
5418
67
    free(id);
5419
67
    parse_security_context(NULL);
5420
67
    return 0;
5421
67
  }
5422
5423
0
  if (port > 0xff || port == 0) {
5424
0
    yyerror2(
5425
0
      "Invalid ibendport port number %d, should be 0 < port < 256",
5426
0
      port);
5427
0
    return -1;
5428
0
  }
5429
5430
0
  newc = calloc(1, sizeof(*newc));
5431
0
  if (!newc) {
5432
0
    yyerror("out of memory");
5433
0
    return -1;
5434
0
  }
5435
5436
0
  newc->u.ibendport.dev_name = queue_remove(id_queue);
5437
0
  if (!newc->u.ibendport.dev_name) {
5438
0
    yyerror("failed to read infiniband device name.");
5439
0
    rc = -1;
5440
0
    goto out;
5441
0
  }
5442
5443
0
  if (strlen(newc->u.ibendport.dev_name) > IB_DEVICE_NAME_MAX - 1) {
5444
0
    yyerror2("infiniband device name %s exceeds max length of 63.",
5445
0
       newc->u.ibendport.dev_name);
5446
0
    rc = -1;
5447
0
    goto out;
5448
0
  }
5449
5450
0
  newc->u.ibendport.port = port;
5451
5452
0
  if (parse_security_context(&newc->context[0])) {
5453
0
    free(newc);
5454
0
    return -1;
5455
0
  }
5456
5457
  /* Preserve the matching order specified in the configuration. */
5458
0
  head = policydbp->ocontexts[OCON_IBENDPORT];
5459
0
  for (l = NULL, c = head; c; l = c, c = c->next) {
5460
0
    unsigned int port2;
5461
5462
0
    port2 = c->u.ibendport.port;
5463
5464
0
    if (port == port2 && !strcmp(c->u.ibendport.dev_name,
5465
0
               newc->u.ibendport.dev_name)) {
5466
0
      yyerror2("duplicate ibendportcon entry for %s port %u",
5467
0
         newc->u.ibendport.dev_name, port);
5468
0
      rc = -1;
5469
0
      goto out;
5470
0
    }
5471
0
  }
5472
5473
0
  if (l)
5474
0
    l->next = newc;
5475
0
  else
5476
0
    policydbp->ocontexts[OCON_IBENDPORT] = newc;
5477
5478
0
  return 0;
5479
5480
0
out:
5481
0
  free(newc->u.ibendport.dev_name);
5482
0
  free(newc);
5483
0
  return rc;
5484
0
}
5485
5486
int define_netif_context(void)
5487
783
{
5488
783
  ocontext_t *newc, *c, *head;
5489
5490
783
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5491
1
    yyerror("netifcon not supported for target");
5492
1
    return -1;
5493
1
  }
5494
5495
782
  if (pass == 1) {
5496
782
    free(queue_remove(id_queue));
5497
782
    parse_security_context(NULL);
5498
782
    parse_security_context(NULL);
5499
782
    return 0;
5500
782
  }
5501
5502
0
  newc = calloc(1, sizeof(ocontext_t));
5503
0
  if (!newc) {
5504
0
    yyerror("out of memory");
5505
0
    return -1;
5506
0
  }
5507
5508
0
  newc->u.name = (char *)queue_remove(id_queue);
5509
0
  if (!newc->u.name) {
5510
0
    free(newc);
5511
0
    return -1;
5512
0
  }
5513
0
  if (parse_security_context(&newc->context[0])) {
5514
0
    free(newc->u.name);
5515
0
    free(newc);
5516
0
    return -1;
5517
0
  }
5518
0
  if (parse_security_context(&newc->context[1])) {
5519
0
    context_destroy(&newc->context[0]);
5520
0
    free(newc->u.name);
5521
0
    free(newc);
5522
0
    return -1;
5523
0
  }
5524
0
  head = policydbp->ocontexts[OCON_NETIF];
5525
5526
0
  for (c = head; c; c = c->next) {
5527
0
    if (!strcmp(newc->u.name, c->u.name)) {
5528
0
      yyerror2("duplicate entry for network interface %s",
5529
0
         newc->u.name);
5530
0
      context_destroy(&newc->context[0]);
5531
0
      context_destroy(&newc->context[1]);
5532
0
      free(newc->u.name);
5533
0
      free(newc);
5534
0
      return -1;
5535
0
    }
5536
0
  }
5537
5538
0
  newc->next = head;
5539
0
  policydbp->ocontexts[OCON_NETIF] = newc;
5540
0
  return 0;
5541
0
}
5542
5543
static int insert_ipv4_node(ocontext_t *newc)
5544
459
{
5545
459
  ocontext_t *c, *l;
5546
459
  char addr[INET_ADDRSTRLEN];
5547
459
  char mask[INET_ADDRSTRLEN];
5548
5549
  /* Create order of most specific to least retaining
5550
     the order specified in the configuration. */
5551
877
  for (l = NULL, c = policydbp->ocontexts[OCON_NODE]; c;
5552
593
       l = c, c = c->next) {
5553
593
    if (newc->u.node.mask == c->u.node.mask &&
5554
185
        newc->u.node.addr == c->u.node.addr) {
5555
9
      yyerror2(
5556
9
        "duplicate entry for network node %s %s",
5557
9
        inet_ntop(AF_INET, &newc->u.node.addr, addr, INET_ADDRSTRLEN) ?:
5558
9
          "<invalid>",
5559
9
        inet_ntop(AF_INET, &newc->u.node.mask, mask, INET_ADDRSTRLEN) ?:
5560
9
          "<invalid>");
5561
9
      context_destroy(&newc->context[0]);
5562
9
      free(newc);
5563
9
      return -1;
5564
9
    }
5565
5566
584
    if (newc->u.node.mask > c->u.node.mask)
5567
166
      break;
5568
584
  }
5569
5570
450
  newc->next = c;
5571
5572
450
  if (l)
5573
195
    l->next = newc;
5574
255
  else
5575
255
    policydbp->ocontexts[OCON_NODE] = newc;
5576
5577
450
  return 0;
5578
459
}
5579
5580
int define_ipv4_node_context(void)
5581
1.06k
{
5582
1.06k
  char *id;
5583
1.06k
  int rc = 0;
5584
1.06k
  struct in_addr addr, mask;
5585
1.06k
  ocontext_t *newc;
5586
5587
1.06k
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5588
1
    yyerror("nodecon not supported for target");
5589
1
    return -1;
5590
1
  }
5591
5592
1.06k
  if (pass == 1) {
5593
682
    free(queue_remove(id_queue));
5594
682
    free(queue_remove(id_queue));
5595
682
    parse_security_context(NULL);
5596
682
    return 0;
5597
682
  }
5598
5599
382
  id = queue_remove(id_queue);
5600
382
  if (!id) {
5601
0
    yyerror("failed to read ipv4 address");
5602
0
    return -1;
5603
0
  }
5604
5605
382
  rc = inet_pton(AF_INET, id, &addr);
5606
382
  if (rc < 1) {
5607
1
    yyerror2("failed to parse ipv4 address %s", id);
5608
1
    free(id);
5609
1
    return -1;
5610
1
  }
5611
381
  free(id);
5612
5613
381
  id = queue_remove(id_queue);
5614
381
  if (!id) {
5615
0
    yyerror("failed to read ipv4 address");
5616
0
    return -1;
5617
0
  }
5618
5619
381
  rc = inet_pton(AF_INET, id, &mask);
5620
381
  if (rc < 1) {
5621
1
    yyerror2("failed to parse ipv4 mask %s", id);
5622
1
    free(id);
5623
1
    return -1;
5624
1
  }
5625
5626
380
  free(id);
5627
5628
380
  if (mask.s_addr != 0 &&
5629
380
      ((~be32toh(mask.s_addr) + 1) & ~be32toh(mask.s_addr)) != 0) {
5630
380
    yywarn("ipv4 mask is not contiguous");
5631
380
  }
5632
5633
380
  if ((~mask.s_addr & addr.s_addr) != 0) {
5634
304
    yywarn("host bits in ipv4 address set");
5635
304
  }
5636
5637
380
  newc = calloc(1, sizeof(ocontext_t));
5638
380
  if (!newc) {
5639
0
    yyerror("out of memory");
5640
0
    return -1;
5641
0
  }
5642
5643
380
  newc->u.node.addr = addr.s_addr;
5644
380
  newc->u.node.mask = mask.s_addr;
5645
5646
380
  if (parse_security_context(&newc->context[0])) {
5647
43
    free(newc);
5648
43
    return -1;
5649
43
  }
5650
5651
337
  return insert_ipv4_node(newc);
5652
380
}
5653
5654
int define_ipv4_cidr_node_context(void)
5655
488
{
5656
488
  char *endptr, *id, *split;
5657
488
  unsigned long mask_bits;
5658
488
  uint32_t mask;
5659
488
  struct in_addr addr;
5660
488
  ocontext_t *newc;
5661
488
  int rc;
5662
5663
488
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5664
1
    yyerror("nodecon not supported for target");
5665
1
    return -1;
5666
1
  }
5667
5668
487
  if (pass == 1) {
5669
343
    free(queue_remove(id_queue));
5670
343
    parse_security_context(NULL);
5671
343
    return 0;
5672
343
  }
5673
5674
144
  id = queue_remove(id_queue);
5675
144
  if (!id) {
5676
0
    yyerror("failed to read IPv4 address");
5677
0
    return -1;
5678
0
  }
5679
5680
144
  split = strchr(id, '/');
5681
144
  if (!split) {
5682
0
    yyerror2("invalid IPv4 CIDR notation: %s", id);
5683
0
    free(id);
5684
0
    return -1;
5685
0
  }
5686
144
  *split = '\0';
5687
5688
144
  rc = inet_pton(AF_INET, id, &addr);
5689
144
  if (rc < 1) {
5690
1
    yyerror2("failed to parse IPv4 address %s", id);
5691
1
    free(id);
5692
1
    return -1;
5693
1
  }
5694
5695
144
  errno = 0;
5696
143
  mask_bits = strtoul(split + 1, &endptr, 10);
5697
143
  if (errno || *endptr != '\0' || mask_bits > 32) {
5698
1
    yyerror2("invalid mask in IPv4 CIDR notation: %s", split + 1);
5699
1
    free(id);
5700
1
    return -1;
5701
1
  }
5702
5703
142
  free(id);
5704
5705
142
  if (mask_bits == 0) {
5706
13
    yywarn("IPv4 CIDR mask of 0, matching all IPs");
5707
13
    mask = 0;
5708
129
  } else {
5709
129
    mask = ~((UINT32_C(1) << (32 - mask_bits)) - 1);
5710
129
    mask = htobe32(mask);
5711
129
  }
5712
5713
142
  if ((~mask & addr.s_addr) != 0)
5714
66
    yywarn("host bits in IPv4 address set");
5715
5716
142
  newc = calloc(1, sizeof(ocontext_t));
5717
142
  if (!newc) {
5718
0
    yyerror("out of memory");
5719
0
    return -1;
5720
0
  }
5721
5722
142
  newc->u.node.addr = addr.s_addr & mask;
5723
142
  newc->u.node.mask = mask;
5724
5725
142
  if (parse_security_context(&newc->context[0])) {
5726
20
    free(newc);
5727
20
    return -1;
5728
20
  }
5729
5730
122
  return insert_ipv4_node(newc);
5731
142
}
5732
5733
static int ipv6_is_mask_contiguous(const struct in6_addr *mask)
5734
145
{
5735
145
  int filled = 1;
5736
145
  unsigned i;
5737
5738
2.04k
  for (i = 0; i < 16; i++) {
5739
1.92k
    if ((((~mask->s6_addr[i] & 0xFF) + 1) &
5740
1.92k
         (~mask->s6_addr[i] & 0xFF)) != 0) {
5741
30
      return 0;
5742
30
    }
5743
1.89k
    if (!filled && mask->s6_addr[i] != 0) {
5744
1
      return 0;
5745
1
    }
5746
5747
1.89k
    if (filled && mask->s6_addr[i] != 0xFF) {
5748
145
      filled = 0;
5749
145
    }
5750
1.89k
  }
5751
5752
114
  return 1;
5753
145
}
5754
5755
static int ipv6_has_host_bits_set(const struct in6_addr *addr,
5756
          const struct in6_addr *mask)
5757
591
{
5758
591
  unsigned i;
5759
5760
9.84k
  for (i = 0; i < 16; i++) {
5761
9.39k
    if ((addr->s6_addr[i] & ~mask->s6_addr[i]) != 0) {
5762
137
      return 1;
5763
137
    }
5764
9.39k
  }
5765
5766
454
  return 0;
5767
591
}
5768
5769
static void ipv6_cidr_bits_to_mask(unsigned long cidr_bits,
5770
           struct in6_addr *mask)
5771
446
{
5772
446
  unsigned i;
5773
5774
2.23k
  for (i = 0; i < 4; i++) {
5775
1.78k
    if (cidr_bits == 0) {
5776
693
      mask->s6_addr32[i] = 0;
5777
1.09k
    } else if (cidr_bits >= 32) {
5778
693
      mask->s6_addr32[i] = ~UINT32_C(0);
5779
693
    } else {
5780
398
      mask->s6_addr32[i] = htobe32(
5781
398
        ~((UINT32_C(1) << (32 - cidr_bits)) - 1));
5782
398
    }
5783
5784
1.78k
    if (cidr_bits >= 32)
5785
693
      cidr_bits -= 32;
5786
1.09k
    else
5787
1.09k
      cidr_bits = 0;
5788
1.78k
  }
5789
446
}
5790
5791
static void ipv6_apply_mask(struct in6_addr *restrict addr,
5792
          const struct in6_addr *restrict mask)
5793
446
{
5794
446
  unsigned i;
5795
5796
2.23k
  for (i = 0; i < 4; i++)
5797
1.78k
    addr->s6_addr32[i] &= mask->s6_addr32[i];
5798
446
}
5799
5800
static int insert_ipv6_node(ocontext_t *newc)
5801
521
{
5802
521
  ocontext_t *c, *l;
5803
521
  char addr[INET6_ADDRSTRLEN];
5804
521
  char mask[INET6_ADDRSTRLEN];
5805
5806
  /* Create order of most specific to least retaining
5807
     the order specified in the configuration. */
5808
1.09k
  for (l = NULL, c = policydbp->ocontexts[OCON_NODE6]; c;
5809
757
       l = c, c = c->next) {
5810
757
    if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) == 0 &&
5811
213
        memcmp(&newc->u.node6.addr, &c->u.node6.addr, 16) == 0) {
5812
12
      yyerror2(
5813
12
        "duplicate entry for network node %s %s",
5814
12
        inet_ntop(AF_INET6, &newc->u.node6.addr, addr, INET6_ADDRSTRLEN) ?:
5815
12
          "<invalid>",
5816
12
        inet_ntop(AF_INET6, &newc->u.node6.mask, mask, INET6_ADDRSTRLEN) ?:
5817
12
          "<invalid>");
5818
12
      context_destroy(&newc->context[0]);
5819
12
      free(newc);
5820
12
      return -1;
5821
12
    }
5822
5823
745
    if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
5824
173
      break;
5825
745
  }
5826
5827
509
  newc->next = c;
5828
5829
509
  if (l)
5830
220
    l->next = newc;
5831
289
  else
5832
289
    policydbp->ocontexts[OCON_NODE6] = newc;
5833
5834
509
  return 0;
5835
521
}
5836
5837
int define_ipv6_node_context(void)
5838
673
{
5839
673
  char *id;
5840
673
  int rc = 0;
5841
673
  struct in6_addr addr, mask;
5842
673
  ocontext_t *newc;
5843
5844
673
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5845
1
    yyerror("nodecon not supported for target");
5846
1
    return -1;
5847
1
  }
5848
5849
672
  if (pass == 1) {
5850
525
    free(queue_remove(id_queue));
5851
525
    free(queue_remove(id_queue));
5852
525
    parse_security_context(NULL);
5853
525
    return 0;
5854
525
  }
5855
5856
147
  id = queue_remove(id_queue);
5857
147
  if (!id) {
5858
0
    yyerror("failed to read ipv6 address");
5859
0
    return -1;
5860
0
  }
5861
5862
147
  rc = inet_pton(AF_INET6, id, &addr);
5863
147
  if (rc < 1) {
5864
1
    yyerror2("failed to parse ipv6 address %s", id);
5865
1
    free(id);
5866
1
    return -1;
5867
1
  }
5868
5869
146
  free(id);
5870
5871
146
  id = queue_remove(id_queue);
5872
146
  if (!id) {
5873
0
    yyerror("failed to read ipv6 address");
5874
0
    return -1;
5875
0
  }
5876
5877
146
  rc = inet_pton(AF_INET6, id, &mask);
5878
146
  if (rc < 1) {
5879
1
    yyerror2("failed to parse ipv6 mask %s", id);
5880
1
    free(id);
5881
1
    return -1;
5882
1
  }
5883
5884
145
  free(id);
5885
5886
145
  if (!ipv6_is_mask_contiguous(&mask)) {
5887
31
    yywarn("ipv6 mask is not contiguous");
5888
31
  }
5889
5890
145
  if (ipv6_has_host_bits_set(&addr, &mask)) {
5891
114
    yywarn("host bits in ipv6 address set");
5892
114
  }
5893
5894
145
  newc = calloc(1, sizeof(ocontext_t));
5895
145
  if (!newc) {
5896
0
    yyerror("out of memory");
5897
0
    return -1;
5898
0
  }
5899
5900
145
  memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5901
145
  memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5902
5903
145
  if (parse_security_context(&newc->context[0])) {
5904
28
    free(newc);
5905
28
    return -1;
5906
28
  }
5907
5908
117
  return insert_ipv6_node(newc);
5909
145
}
5910
5911
int define_ipv6_cidr_node_context(void)
5912
1.25k
{
5913
1.25k
  char *endptr, *id, *split;
5914
1.25k
  unsigned long mask_bits;
5915
1.25k
  int rc;
5916
1.25k
  struct in6_addr addr, mask;
5917
1.25k
  ocontext_t *newc;
5918
5919
1.25k
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5920
1
    yyerror("nodecon not supported for target");
5921
1
    return -1;
5922
1
  }
5923
5924
1.25k
  if (pass == 1) {
5925
803
    free(queue_remove(id_queue));
5926
803
    parse_security_context(NULL);
5927
803
    return 0;
5928
803
  }
5929
5930
450
  id = queue_remove(id_queue);
5931
450
  if (!id) {
5932
0
    yyerror("failed to read IPv6 address");
5933
0
    return -1;
5934
0
  }
5935
5936
450
  split = strchr(id, '/');
5937
450
  if (!split) {
5938
0
    yyerror2("invalid IPv6 CIDR notation: %s", id);
5939
0
    free(id);
5940
0
    return -1;
5941
0
  }
5942
450
  *split = '\0';
5943
5944
450
  rc = inet_pton(AF_INET6, id, &addr);
5945
450
  if (rc < 1) {
5946
2
    yyerror2("failed to parse IPv6 address %s", id);
5947
2
    free(id);
5948
2
    return -1;
5949
2
  }
5950
5951
450
  errno = 0;
5952
448
  mask_bits = strtoul(split + 1, &endptr, 10);
5953
448
  if (errno || *endptr != '\0' || mask_bits > 128) {
5954
2
    yyerror2("invalid mask in IPv6 CIDR notation: %s", split + 1);
5955
2
    free(id);
5956
2
    return -1;
5957
2
  }
5958
5959
446
  if (mask_bits == 0) {
5960
9
    yywarn("IPv6 CIDR mask of 0, matching all IPs");
5961
9
  }
5962
5963
446
  ipv6_cidr_bits_to_mask(mask_bits, &mask);
5964
5965
446
  if (ipv6_has_host_bits_set(&addr, &mask)) {
5966
23
    yywarn("host bits in ipv6 address set");
5967
23
  }
5968
5969
446
  free(id);
5970
5971
446
  newc = calloc(1, sizeof(ocontext_t));
5972
446
  if (!newc) {
5973
0
    yyerror("out of memory");
5974
0
    return -1;
5975
0
  }
5976
5977
446
  ipv6_apply_mask(&addr, &mask);
5978
446
  memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5979
446
  memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5980
5981
446
  if (parse_security_context(&newc->context[0])) {
5982
42
    free(newc);
5983
42
    return -1;
5984
42
  }
5985
5986
404
  return insert_ipv6_node(newc);
5987
446
}
5988
5989
int define_fs_use(int behavior)
5990
226
{
5991
226
  ocontext_t *newc, *c, *head;
5992
5993
226
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5994
3
    yyerror("fsuse not supported for target");
5995
3
    return -1;
5996
3
  }
5997
5998
223
  if (pass == 1) {
5999
222
    free(queue_remove(id_queue));
6000
222
    parse_security_context(NULL);
6001
222
    return 0;
6002
222
  }
6003
6004
1
  newc = calloc(1, sizeof(ocontext_t));
6005
1
  if (!newc) {
6006
0
    yyerror("out of memory");
6007
0
    return -1;
6008
0
  }
6009
6010
1
  newc->u.name = (char *)queue_remove(id_queue);
6011
1
  if (!newc->u.name) {
6012
0
    free(newc);
6013
0
    return -1;
6014
0
  }
6015
1
  newc->v.behavior = behavior;
6016
1
  if (parse_security_context(&newc->context[0])) {
6017
1
    free(newc->u.name);
6018
1
    free(newc);
6019
1
    return -1;
6020
1
  }
6021
6022
0
  head = policydbp->ocontexts[OCON_FSUSE];
6023
6024
0
  for (c = head; c; c = c->next) {
6025
0
    if (!strcmp(newc->u.name, c->u.name)) {
6026
0
      yyerror2(
6027
0
        "duplicate fs_use entry for filesystem type %s",
6028
0
        newc->u.name);
6029
0
      context_destroy(&newc->context[0]);
6030
0
      free(newc->u.name);
6031
0
      free(newc);
6032
0
      return -1;
6033
0
    }
6034
0
  }
6035
6036
0
  newc->next = head;
6037
0
  policydbp->ocontexts[OCON_FSUSE] = newc;
6038
0
  return 0;
6039
0
}
6040
6041
static int define_genfs_context_helper(char *fstype, int has_type)
6042
4.42k
{
6043
4.42k
  struct genfs *genfs_p, *genfs, *newgenfs;
6044
4.42k
  ocontext_t *newc, *c, *head, *p;
6045
4.42k
  class_datum_t *cladatum;
6046
4.42k
  char *type = NULL;
6047
4.42k
  const char *sclass;
6048
4.42k
  size_t len, len2;
6049
4.42k
  int wildcard = ebitmap_get_bit(&policydbp->policycaps,
6050
4.42k
               POLICYDB_CAP_GENFS_SECLABEL_WILDCARD);
6051
6052
4.42k
  if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
6053
3
    yyerror("genfs not supported for target");
6054
3
    return -1;
6055
3
  }
6056
6057
4.41k
  if (pass == 1) {
6058
2.73k
    free(fstype);
6059
2.73k
    free(queue_remove(id_queue));
6060
2.73k
    if (has_type)
6061
961
      free(queue_remove(id_queue));
6062
2.73k
    parse_security_context(NULL);
6063
2.73k
    return 0;
6064
2.73k
  }
6065
6066
2.92k
  for (genfs_p = NULL, genfs = policydbp->genfs; genfs;
6067
2.17k
       genfs_p = genfs, genfs = genfs->next) {
6068
2.17k
    if (strcmp(fstype, genfs->fstype) <= 0)
6069
933
      break;
6070
2.17k
  }
6071
6072
1.68k
  if (!genfs || strcmp(fstype, genfs->fstype)) {
6073
1.21k
    newgenfs = calloc(1, sizeof(struct genfs));
6074
1.21k
    if (!newgenfs) {
6075
0
      yyerror("out of memory");
6076
0
      return -1;
6077
0
    }
6078
1.21k
    newgenfs->fstype = fstype;
6079
    /* ownership transferred into the genfs list; do not free on error */
6080
1.21k
    fstype = NULL;
6081
1.21k
    newgenfs->next = genfs;
6082
1.21k
    if (genfs_p)
6083
441
      genfs_p->next = newgenfs;
6084
775
    else
6085
775
      policydbp->genfs = newgenfs;
6086
1.21k
    genfs = newgenfs;
6087
1.21k
  } else {
6088
466
    free(fstype);
6089
466
    fstype = NULL;
6090
466
  }
6091
6092
1.68k
  newc = calloc(1, sizeof(ocontext_t));
6093
1.68k
  if (!newc) {
6094
0
    yyerror("out of memory");
6095
0
    return -1;
6096
0
  }
6097
6098
1.68k
  newc->u.name = (char *)queue_remove(id_queue);
6099
1.68k
  if (!newc->u.name)
6100
1
    goto fail;
6101
6102
1.68k
  if (wildcard) {
6103
0
    size_t name_len = strlen(newc->u.name);
6104
0
    newc->u.name = realloc(newc->u.name, name_len + 2);
6105
0
    if (newc->u.name == NULL) {
6106
0
      yyerror("out of memory");
6107
0
      return -1;
6108
0
    }
6109
6110
0
    newc->u.name[name_len] = '*';
6111
0
    newc->u.name[name_len + 1] = '\0';
6112
0
  }
6113
6114
1.68k
  if (has_type) {
6115
507
    type = (char *)queue_remove(id_queue);
6116
507
    if (!type)
6117
1
      goto fail;
6118
506
    if (type[1] != 0) {
6119
6
      yyerror2("invalid type %s", type);
6120
6
      goto fail;
6121
6
    }
6122
500
    switch (type[0]) {
6123
490
    case 'b':
6124
490
      sclass = "blk_file";
6125
490
      break;
6126
1
    case 'c':
6127
1
      sclass = "chr_file";
6128
1
      break;
6129
1
    case 'd':
6130
1
      sclass = "dir";
6131
1
      break;
6132
1
    case 'p':
6133
1
      sclass = "fifo_file";
6134
1
      break;
6135
1
    case 'l':
6136
1
      sclass = "lnk_file";
6137
1
      break;
6138
2
    case 's':
6139
2
      sclass = "sock_file";
6140
2
      break;
6141
1
    case '-':
6142
1
      sclass = "file";
6143
1
      break;
6144
3
    default:
6145
3
      yyerror2("invalid type %s", type);
6146
3
      goto fail;
6147
500
    }
6148
6149
497
    cladatum = hashtab_search(policydbp->p_classes.table, sclass);
6150
497
    if (!cladatum) {
6151
7
      yyerror2("could not find class %s for "
6152
7
         "genfscon statement",
6153
7
         sclass);
6154
7
      goto fail;
6155
7
    }
6156
490
    newc->v.sclass = cladatum->s.value;
6157
490
  }
6158
1.66k
  if (parse_security_context(&newc->context[0]))
6159
203
    goto fail;
6160
6161
1.46k
  head = genfs->head;
6162
6163
2.47k
  for (p = NULL, c = head; c; p = c, c = c->next) {
6164
1.28k
    if (!strcmp(newc->u.name, c->u.name) &&
6165
7
        (!newc->v.sclass || !c->v.sclass ||
6166
7
         newc->v.sclass == c->v.sclass)) {
6167
7
      yyerror2("duplicate entry for genfs entry (%s, %s)",
6168
7
         genfs->fstype, newc->u.name);
6169
7
      goto fail;
6170
7
    }
6171
1.28k
    len = strlen(newc->u.name);
6172
1.28k
    len2 = strlen(c->u.name);
6173
1.28k
    if (len > len2)
6174
272
      break;
6175
1.28k
  }
6176
6177
1.45k
  newc->next = c;
6178
1.45k
  if (p)
6179
336
    p->next = newc;
6180
1.11k
  else
6181
1.11k
    genfs->head = newc;
6182
1.45k
  free(type);
6183
1.45k
  return 0;
6184
228
fail:
6185
228
  free(type);
6186
228
  context_destroy(&newc->context[0]);
6187
228
  free(fstype);
6188
228
  free(newc->u.name);
6189
228
  free(newc);
6190
228
  return -1;
6191
1.46k
}
6192
6193
int define_genfs_context(int has_type)
6194
4.42k
{
6195
4.42k
  return define_genfs_context_helper(queue_remove(id_queue), has_type);
6196
4.42k
}
6197
6198
int define_range_trans(int class_specified)
6199
2.17k
{
6200
2.17k
  char *id;
6201
2.17k
  level_datum_t *levdatum = NULL;
6202
2.17k
  class_datum_t *cladatum;
6203
2.17k
  range_trans_rule_t *rule;
6204
2.17k
  int l, add = 1;
6205
6206
2.17k
  if (!mlspol) {
6207
2
    yyerror("range_transition rule in non-MLS configuration");
6208
2
    return -1;
6209
2
  }
6210
6211
2.17k
  if (pass == 1) {
6212
5.61k
    while ((id = queue_remove(id_queue)))
6213
3.64k
      free(id);
6214
6.66k
    while ((id = queue_remove(id_queue)))
6215
4.69k
      free(id);
6216
1.97k
    if (class_specified)
6217
3.35k
      while ((id = queue_remove(id_queue)))
6218
2.35k
        free(id);
6219
1.97k
    id = queue_remove(id_queue);
6220
1.97k
    free(id);
6221
3.03k
    for (l = 0; l < 2; l++) {
6222
4.31k
      while ((id = queue_remove(id_queue))) {
6223
1.28k
        free(id);
6224
1.28k
      }
6225
3.03k
      id = queue_remove(id_queue);
6226
3.03k
      if (!id)
6227
1.97k
        break;
6228
1.06k
      free(id);
6229
1.06k
    }
6230
1.97k
    return 0;
6231
1.97k
  }
6232
6233
203
  rule = malloc(sizeof(struct range_trans_rule));
6234
203
  if (!rule) {
6235
0
    yyerror("out of memory");
6236
0
    return -1;
6237
0
  }
6238
203
  range_trans_rule_init(rule);
6239
6240
405
  while ((id = queue_remove(id_queue))) {
6241
203
    if (set_types(&rule->stypes, id, &add, 0))
6242
1
      goto out;
6243
203
  }
6244
202
  add = 1;
6245
2.77k
  while ((id = queue_remove(id_queue))) {
6246
2.57k
    if (set_types(&rule->ttypes, id, &add, 0))
6247
2
      goto out;
6248
2.57k
  }
6249
6250
200
  if (class_specified) {
6251
197
    if (read_classes(&rule->tclasses))
6252
2
      goto out;
6253
197
  } else {
6254
3
    cladatum =
6255
3
      hashtab_search(policydbp->p_classes.table, "process");
6256
3
    if (!cladatum) {
6257
3
      yyerror2("could not find process class for "
6258
3
         "legacy range_transition statement");
6259
3
      goto out;
6260
3
    }
6261
6262
0
    if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1,
6263
0
            TRUE)) {
6264
0
      yyerror("out of memory");
6265
0
      goto out;
6266
0
    }
6267
0
  }
6268
6269
195
  id = (char *)queue_remove(id_queue);
6270
195
  if (!id) {
6271
0
    yyerror("no range in range_transition definition?");
6272
0
    goto out;
6273
0
  }
6274
195
  for (l = 0; l < 2; l++) {
6275
195
    levdatum = hashtab_search(policydbp->p_levels.table, id);
6276
195
    if (!levdatum) {
6277
2
      yyerror2("unknown level %s used in range_transition "
6278
2
         "definition",
6279
2
         id);
6280
2
      free(id);
6281
2
      goto out;
6282
2
    }
6283
193
    free(id);
6284
6285
193
    rule->trange.level[l].sens = levdatum->level->sens;
6286
6287
193
    while ((id = queue_remove(id_queue))) {
6288
1
      if (parse_semantic_categories(
6289
1
            id, levdatum, &rule->trange.level[l].cat)) {
6290
1
        free(id);
6291
1
        goto out;
6292
1
      }
6293
0
      free(id);
6294
0
    }
6295
6296
192
    id = (char *)queue_remove(id_queue);
6297
192
    if (!id)
6298
192
      break;
6299
192
  }
6300
192
  if (l == 0) {
6301
192
    if (mls_semantic_level_cpy(&rule->trange.level[1],
6302
192
             &rule->trange.level[0])) {
6303
0
      yyerror("out of memory");
6304
0
      goto out;
6305
0
    }
6306
192
  }
6307
6308
192
  append_range_trans(rule);
6309
192
  return 0;
6310
6311
11
out:
6312
11
  range_trans_rule_destroy(rule);
6313
11
  free(rule);
6314
11
  return -1;
6315
192
}
6316
6317
/* FLASK */