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