Coverage Report

Created: 2025-07-23 06:25

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