Coverage Report

Created: 2026-01-17 06:04

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