Coverage Report

Created: 2024-07-27 06:22

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