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
3480 #define PERMISSION_MASK(nprim) ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : ((UINT32_C(1) << (nprim)) - 1))
3481
define_constraint(constraint_expr_t * expr)3482 int define_constraint(constraint_expr_t * expr)
3483 {
3484 struct constraint_node *node;
3485 char *id;
3486 class_datum_t *cladatum;
3487 perm_datum_t *perdatum;
3488 ebitmap_t classmap;
3489 ebitmap_node_t *enode;
3490 constraint_expr_t *e;
3491 unsigned int i;
3492 int depth;
3493 unsigned char useexpr = 1;
3494
3495 if (pass == 1) {
3496 while ((id = queue_remove(id_queue)))
3497 free(id);
3498 while ((id = queue_remove(id_queue)))
3499 free(id);
3500 return 0;
3501 }
3502
3503 depth = -1;
3504 for (e = expr; e; e = e->next) {
3505 switch (e->expr_type) {
3506 case CEXPR_NOT:
3507 if (depth < 0) {
3508 yyerror("illegal constraint expression");
3509 return -1;
3510 }
3511 break;
3512 case CEXPR_AND:
3513 case CEXPR_OR:
3514 if (depth < 1) {
3515 yyerror("illegal constraint expression");
3516 return -1;
3517 }
3518 depth--;
3519 break;
3520 case CEXPR_ATTR:
3521 case CEXPR_NAMES:
3522 if (e->attr & CEXPR_XTARGET) {
3523 yyerror("illegal constraint expression");
3524 return -1; /* only for validatetrans rules */
3525 }
3526 if (depth == (CEXPR_MAXDEPTH - 1)) {
3527 yyerror("constraint expression is too deep");
3528 return -1;
3529 }
3530 depth++;
3531 break;
3532 default:
3533 yyerror("illegal constraint expression");
3534 return -1;
3535 }
3536 }
3537 if (depth != 0) {
3538 yyerror("illegal constraint expression");
3539 return -1;
3540 }
3541
3542 ebitmap_init(&classmap);
3543 while ((id = queue_remove(id_queue))) {
3544 if (!is_id_in_scope(SYM_CLASSES, id)) {
3545 yyerror2("class %s is not within scope", id);
3546 free(id);
3547 return -1;
3548 }
3549 cladatum =
3550 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3551 (hashtab_key_t) id);
3552 if (!cladatum) {
3553 yyerror2("class %s is not defined", id);
3554 ebitmap_destroy(&classmap);
3555 free(id);
3556 return -1;
3557 }
3558 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
3559 yyerror("out of memory");
3560 ebitmap_destroy(&classmap);
3561 free(id);
3562 return -1;
3563 }
3564 node = malloc(sizeof(struct constraint_node));
3565 if (!node) {
3566 yyerror("out of memory");
3567 free(node);
3568 return -1;
3569 }
3570 memset(node, 0, sizeof(constraint_node_t));
3571 if (useexpr) {
3572 node->expr = expr;
3573 useexpr = 0;
3574 } else {
3575 node->expr = constraint_expr_clone(expr);
3576 }
3577 if (!node->expr) {
3578 yyerror("out of memory");
3579 free(node);
3580 return -1;
3581 }
3582 node->permissions = 0;
3583
3584 node->next = cladatum->constraints;
3585 cladatum->constraints = node;
3586
3587 free(id);
3588 }
3589
3590 while ((id = queue_remove(id_queue))) {
3591 ebitmap_for_each_positive_bit(&classmap, enode, i) {
3592 cladatum = policydbp->class_val_to_struct[i];
3593 node = cladatum->constraints;
3594
3595 if (strcmp(id, "*") == 0) {
3596 node->permissions = PERMISSION_MASK(cladatum->permissions.nprim);
3597 continue;
3598 }
3599
3600 if (strcmp(id, "~") == 0) {
3601 node->permissions = ~node->permissions & PERMISSION_MASK(cladatum->permissions.nprim);
3602 if (node->permissions == 0) {
3603 yywarn("omitting constraint with no permission set");
3604 cladatum->constraints = node->next;
3605 constraint_expr_destroy(node->expr);
3606 free(node);
3607 }
3608 continue;
3609 }
3610
3611 perdatum =
3612 (perm_datum_t *) hashtab_search(cladatum->
3613 permissions.
3614 table,
3615 (hashtab_key_t)
3616 id);
3617 if (!perdatum) {
3618 if (cladatum->comdatum) {
3619 perdatum =
3620 (perm_datum_t *)
3621 hashtab_search(cladatum->
3622 comdatum->
3623 permissions.
3624 table,
3625 (hashtab_key_t)
3626 id);
3627 }
3628 if (!perdatum) {
3629 yyerror2("permission %s is not"
3630 " defined", id);
3631 free(id);
3632 ebitmap_destroy(&classmap);
3633 return -1;
3634 }
3635 }
3636 node->permissions |= (UINT32_C(1) << (perdatum->s.value - 1));
3637 }
3638 free(id);
3639 }
3640
3641 ebitmap_destroy(&classmap);
3642
3643 return 0;
3644 }
3645
define_validatetrans(constraint_expr_t * expr)3646 int define_validatetrans(constraint_expr_t * expr)
3647 {
3648 struct constraint_node *node;
3649 char *id;
3650 class_datum_t *cladatum;
3651 ebitmap_t classmap;
3652 constraint_expr_t *e;
3653 int depth;
3654 unsigned char useexpr = 1;
3655
3656 if (pass == 1) {
3657 while ((id = queue_remove(id_queue)))
3658 free(id);
3659 return 0;
3660 }
3661
3662 depth = -1;
3663 for (e = expr; e; e = e->next) {
3664 switch (e->expr_type) {
3665 case CEXPR_NOT:
3666 if (depth < 0) {
3667 yyerror("illegal validatetrans expression");
3668 return -1;
3669 }
3670 break;
3671 case CEXPR_AND:
3672 case CEXPR_OR:
3673 if (depth < 1) {
3674 yyerror("illegal validatetrans expression");
3675 return -1;
3676 }
3677 depth--;
3678 break;
3679 case CEXPR_ATTR:
3680 case CEXPR_NAMES:
3681 if (depth == (CEXPR_MAXDEPTH - 1)) {
3682 yyerror("validatetrans expression is too deep");
3683 return -1;
3684 }
3685 depth++;
3686 break;
3687 default:
3688 yyerror("illegal validatetrans expression");
3689 return -1;
3690 }
3691 }
3692 if (depth != 0) {
3693 yyerror("illegal validatetrans expression");
3694 return -1;
3695 }
3696
3697 ebitmap_init(&classmap);
3698 while ((id = queue_remove(id_queue))) {
3699 if (!is_id_in_scope(SYM_CLASSES, id)) {
3700 yyerror2("class %s is not within scope", id);
3701 free(id);
3702 return -1;
3703 }
3704 cladatum =
3705 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3706 (hashtab_key_t) id);
3707 if (!cladatum) {
3708 yyerror2("class %s is not defined", id);
3709 ebitmap_destroy(&classmap);
3710 free(id);
3711 return -1;
3712 }
3713 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
3714 yyerror("out of memory");
3715 ebitmap_destroy(&classmap);
3716 free(id);
3717 return -1;
3718 }
3719
3720 node = malloc(sizeof(struct constraint_node));
3721 if (!node) {
3722 yyerror("out of memory");
3723 return -1;
3724 }
3725 memset(node, 0, sizeof(constraint_node_t));
3726 if (useexpr) {
3727 node->expr = expr;
3728 useexpr = 0;
3729 } else {
3730 node->expr = constraint_expr_clone(expr);
3731 }
3732 node->permissions = 0;
3733
3734 node->next = cladatum->validatetrans;
3735 cladatum->validatetrans = node;
3736
3737 free(id);
3738 }
3739
3740 ebitmap_destroy(&classmap);
3741
3742 return 0;
3743 }
3744
define_cexpr(uint32_t expr_type,uintptr_t arg1,uintptr_t arg2)3745 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
3746 {
3747 struct constraint_expr *expr, *e1 = NULL, *e2;
3748 user_datum_t *user;
3749 role_datum_t *role;
3750 ebitmap_t negset;
3751 char *id;
3752 uint32_t val;
3753 int add = 1;
3754
3755 if (pass == 1) {
3756 if (expr_type == CEXPR_NAMES) {
3757 while ((id = queue_remove(id_queue)))
3758 free(id);
3759 }
3760 return 1; /* any non-NULL value */
3761 }
3762
3763 if ((expr = malloc(sizeof(*expr))) == NULL ||
3764 constraint_expr_init(expr) == -1) {
3765 yyerror("out of memory");
3766 free(expr);
3767 return 0;
3768 }
3769 expr->expr_type = expr_type;
3770
3771 switch (expr_type) {
3772 case CEXPR_NOT:
3773 e1 = NULL;
3774 e2 = (struct constraint_expr *)arg1;
3775 while (e2) {
3776 e1 = e2;
3777 e2 = e2->next;
3778 }
3779 if (!e1 || e1->next) {
3780 yyerror("illegal constraint expression");
3781 constraint_expr_destroy(expr);
3782 return 0;
3783 }
3784 e1->next = expr;
3785 return arg1;
3786 case CEXPR_AND:
3787 case CEXPR_OR:
3788 e1 = NULL;
3789 e2 = (struct constraint_expr *)arg1;
3790 while (e2) {
3791 e1 = e2;
3792 e2 = e2->next;
3793 }
3794 if (!e1 || e1->next) {
3795 yyerror("illegal constraint expression");
3796 constraint_expr_destroy(expr);
3797 return 0;
3798 }
3799 e1->next = (struct constraint_expr *)arg2;
3800
3801 e1 = NULL;
3802 e2 = (struct constraint_expr *)arg2;
3803 while (e2) {
3804 e1 = e2;
3805 e2 = e2->next;
3806 }
3807 if (!e1 || e1->next) {
3808 yyerror("illegal constraint expression");
3809 constraint_expr_destroy(expr);
3810 return 0;
3811 }
3812 e1->next = expr;
3813 return arg1;
3814 case CEXPR_ATTR:
3815 expr->attr = arg1;
3816 expr->op = arg2;
3817 return (uintptr_t) expr;
3818 case CEXPR_NAMES:
3819 add = 1;
3820 expr->attr = arg1;
3821 expr->op = arg2;
3822 ebitmap_init(&negset);
3823 while ((id = (char *)queue_remove(id_queue))) {
3824 if (expr->attr & CEXPR_USER) {
3825 if (!is_id_in_scope(SYM_USERS, id)) {
3826 yyerror2("user %s is not within scope",
3827 id);
3828 constraint_expr_destroy(expr);
3829 return 0;
3830 }
3831 user =
3832 (user_datum_t *) hashtab_search(policydbp->
3833 p_users.
3834 table,
3835 (hashtab_key_t)
3836 id);
3837 if (!user) {
3838 yyerror2("unknown user %s", id);
3839 constraint_expr_destroy(expr);
3840 return 0;
3841 }
3842 val = user->s.value;
3843 } else if (expr->attr & CEXPR_ROLE) {
3844 if (!is_id_in_scope(SYM_ROLES, id)) {
3845 yyerror2("role %s is not within scope",
3846 id);
3847 constraint_expr_destroy(expr);
3848 return 0;
3849 }
3850 role =
3851 (role_datum_t *) hashtab_search(policydbp->
3852 p_roles.
3853 table,
3854 (hashtab_key_t)
3855 id);
3856 if (!role) {
3857 yyerror2("unknown role %s", id);
3858 constraint_expr_destroy(expr);
3859 return 0;
3860 }
3861 val = role->s.value;
3862 } else if (expr->attr & CEXPR_TYPE) {
3863 if (set_types(expr->type_names, id, &add, 0)) {
3864 constraint_expr_destroy(expr);
3865 return 0;
3866 }
3867 continue;
3868 } else {
3869 yyerror("invalid constraint expression");
3870 constraint_expr_destroy(expr);
3871 return 0;
3872 }
3873 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3874 yyerror("out of memory");
3875 ebitmap_destroy(&expr->names);
3876 constraint_expr_destroy(expr);
3877 return 0;
3878 }
3879 free(id);
3880 }
3881 ebitmap_destroy(&negset);
3882 return (uintptr_t) expr;
3883 default:
3884 break;
3885 }
3886
3887 yyerror("invalid constraint expression");
3888 constraint_expr_destroy(expr);
3889 return 0;
3890 }
3891
define_conditional(cond_expr_t * expr,avrule_t * t,avrule_t * f)3892 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3893 {
3894 cond_expr_t *e;
3895 int depth;
3896 cond_node_t cn, *cn_old;
3897
3898 /* expression cannot be NULL */
3899 if (!expr) {
3900 yyerror("illegal conditional expression");
3901 return -1;
3902 }
3903 if (!t) {
3904 if (!f) {
3905 /* empty is fine, destroy expression and return */
3906 cond_expr_destroy(expr);
3907 return 0;
3908 }
3909 /* Invert */
3910 t = f;
3911 f = 0;
3912 expr = define_cond_expr(COND_NOT, expr, 0);
3913 if (!expr) {
3914 yyerror("unable to invert");
3915 return -1;
3916 }
3917 }
3918
3919 /* verify expression */
3920 depth = -1;
3921 for (e = expr; e; e = e->next) {
3922 switch (e->expr_type) {
3923 case COND_NOT:
3924 if (depth < 0) {
3925 yyerror
3926 ("illegal conditional expression; Bad NOT");
3927 return -1;
3928 }
3929 break;
3930 case COND_AND:
3931 case COND_OR:
3932 case COND_XOR:
3933 case COND_EQ:
3934 case COND_NEQ:
3935 if (depth < 1) {
3936 yyerror
3937 ("illegal conditional expression; Bad binary op");
3938 return -1;
3939 }
3940 depth--;
3941 break;
3942 case COND_BOOL:
3943 if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3944 yyerror
3945 ("conditional expression is like totally too deep");
3946 return -1;
3947 }
3948 depth++;
3949 break;
3950 default:
3951 yyerror("illegal conditional expression");
3952 return -1;
3953 }
3954 }
3955 if (depth != 0) {
3956 yyerror("illegal conditional expression");
3957 return -1;
3958 }
3959
3960 /* use tmp conditional node to partially build new node */
3961 memset(&cn, 0, sizeof(cn));
3962 cn.expr = expr;
3963 cn.avtrue_list = t;
3964 cn.avfalse_list = f;
3965
3966 /* normalize/precompute expression */
3967 if (cond_normalize_expr(policydbp, &cn) < 0) {
3968 yyerror("problem normalizing conditional expression");
3969 return -1;
3970 }
3971
3972 /* get the existing conditional node, or create a new one */
3973 cn_old = get_current_cond_list(&cn);
3974 if (!cn_old) {
3975 return -1;
3976 }
3977
3978 append_cond_list(&cn);
3979
3980 /* note that there is no check here for duplicate rules, nor
3981 * check that rule already exists in base -- that will be
3982 * handled during conditional expansion, in expand.c */
3983
3984 cn.avtrue_list = NULL;
3985 cn.avfalse_list = NULL;
3986 cond_node_destroy(&cn);
3987
3988 return 0;
3989 }
3990
define_cond_expr(uint32_t expr_type,void * arg1,void * arg2)3991 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3992 {
3993 struct cond_expr *expr, *e1 = NULL, *e2;
3994 cond_bool_datum_t *bool_var;
3995 char *id;
3996
3997 /* expressions are handled in the second pass */
3998 if (pass == 1) {
3999 if (expr_type == COND_BOOL) {
4000 while ((id = queue_remove(id_queue))) {
4001 free(id);
4002 }
4003 }
4004 return (cond_expr_t *) 1; /* any non-NULL value */
4005 }
4006
4007 /* create a new expression struct */
4008 expr = malloc(sizeof(struct cond_expr));
4009 if (!expr) {
4010 yyerror("out of memory");
4011 return NULL;
4012 }
4013 memset(expr, 0, sizeof(cond_expr_t));
4014 expr->expr_type = expr_type;
4015
4016 /* create the type asked for */
4017 switch (expr_type) {
4018 case COND_NOT:
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("illegal conditional NOT expression");
4027 free(expr);
4028 return NULL;
4029 }
4030 e1->next = expr;
4031 return (struct cond_expr *)arg1;
4032 case COND_AND:
4033 case COND_OR:
4034 case COND_XOR:
4035 case COND_EQ:
4036 case COND_NEQ:
4037 e1 = NULL;
4038 e2 = (struct cond_expr *)arg1;
4039 while (e2) {
4040 e1 = e2;
4041 e2 = e2->next;
4042 }
4043 if (!e1 || e1->next) {
4044 yyerror
4045 ("illegal left side of conditional binary op expression");
4046 free(expr);
4047 return NULL;
4048 }
4049 e1->next = (struct cond_expr *)arg2;
4050
4051 e1 = NULL;
4052 e2 = (struct cond_expr *)arg2;
4053 while (e2) {
4054 e1 = e2;
4055 e2 = e2->next;
4056 }
4057 if (!e1 || e1->next) {
4058 yyerror
4059 ("illegal right side of conditional binary op expression");
4060 free(expr);
4061 return NULL;
4062 }
4063 e1->next = expr;
4064 return (struct cond_expr *)arg1;
4065 case COND_BOOL:
4066 id = (char *)queue_remove(id_queue);
4067 if (!id) {
4068 yyerror("bad conditional; expected boolean id");
4069 free(id);
4070 free(expr);
4071 return NULL;
4072 }
4073 if (!is_id_in_scope(SYM_BOOLS, id)) {
4074 yyerror2("boolean %s is not within scope", id);
4075 free(id);
4076 free(expr);
4077 return NULL;
4078 }
4079 bool_var =
4080 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
4081 table,
4082 (hashtab_key_t) id);
4083 if (!bool_var) {
4084 yyerror2("unknown boolean %s in conditional expression",
4085 id);
4086 free(expr);
4087 free(id);
4088 return NULL;
4089 }
4090 expr->bool = bool_var->s.value;
4091 free(id);
4092 return expr;
4093 default:
4094 yyerror("illegal conditional expression");
4095 free(expr);
4096 return NULL;
4097 }
4098 }
4099
set_user_roles(role_set_t * set,char * id)4100 static int set_user_roles(role_set_t * set, char *id)
4101 {
4102 role_datum_t *r;
4103
4104 if (strcmp(id, "*") == 0) {
4105 free(id);
4106 yyerror("* is not allowed in user declarations");
4107 return -1;
4108 }
4109
4110 if (strcmp(id, "~") == 0) {
4111 free(id);
4112 yyerror("~ is not allowed in user declarations");
4113 return -1;
4114 }
4115
4116 if (!is_id_in_scope(SYM_ROLES, id)) {
4117 yyerror2("role %s is not within scope", id);
4118 free(id);
4119 return -1;
4120 }
4121 r = hashtab_search(policydbp->p_roles.table, id);
4122 if (!r) {
4123 yyerror2("unknown role %s", id);
4124 free(id);
4125 return -1;
4126 }
4127
4128 free(id);
4129 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE))
4130 goto oom;
4131 return 0;
4132 oom:
4133 yyerror("out of memory");
4134 return -1;
4135 }
4136
parse_categories(char * id,level_datum_t * levdatum,ebitmap_t * cats)4137 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
4138 {
4139 cat_datum_t *cdatum;
4140 int range_start, range_end, i;
4141
4142 if (id_has_dot(id)) {
4143 char *id_start = id;
4144 char *id_end = strchr(id, '.');
4145
4146 *(id_end++) = '\0';
4147
4148 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4149 (hashtab_key_t)
4150 id_start);
4151 if (!cdatum) {
4152 yyerror2("unknown category %s", id_start);
4153 return -1;
4154 }
4155 range_start = cdatum->s.value - 1;
4156 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4157 (hashtab_key_t) id_end);
4158 if (!cdatum) {
4159 yyerror2("unknown category %s", id_end);
4160 return -1;
4161 }
4162 range_end = cdatum->s.value - 1;
4163
4164 if (range_end < range_start) {
4165 yyerror2("category range is invalid");
4166 return -1;
4167 }
4168 } else {
4169 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4170 (hashtab_key_t) id);
4171 if (!cdatum) {
4172 yyerror2("unknown category %s", id);
4173 return -1;
4174 }
4175 range_start = range_end = cdatum->s.value - 1;
4176 }
4177
4178 for (i = range_start; i <= range_end; i++) {
4179 if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
4180 uint32_t level_value = levdatum->level->sens - 1;
4181 policydb_index_others(NULL, policydbp, 0);
4182 yyerror2("category %s can not be associated "
4183 "with level %s",
4184 policydbp->p_cat_val_to_name[i],
4185 policydbp->p_sens_val_to_name[level_value]);
4186 return -1;
4187 }
4188 if (ebitmap_set_bit(cats, i, TRUE)) {
4189 yyerror("out of memory");
4190 return -1;
4191 }
4192 }
4193
4194 return 0;
4195 }
4196
parse_semantic_categories(char * id,level_datum_t * levdatum,mls_semantic_cat_t ** cats)4197 static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)),
4198 mls_semantic_cat_t ** cats)
4199 {
4200 cat_datum_t *cdatum;
4201 mls_semantic_cat_t *newcat;
4202 unsigned int range_start, range_end;
4203
4204 if (id_has_dot(id)) {
4205 char *id_start = id;
4206 char *id_end = strchr(id, '.');
4207
4208 *(id_end++) = '\0';
4209
4210 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4211 (hashtab_key_t)
4212 id_start);
4213 if (!cdatum) {
4214 yyerror2("unknown category %s", id_start);
4215 return -1;
4216 }
4217 range_start = cdatum->s.value;
4218
4219 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4220 (hashtab_key_t) id_end);
4221 if (!cdatum) {
4222 yyerror2("unknown category %s", id_end);
4223 return -1;
4224 }
4225 range_end = cdatum->s.value;
4226 } else {
4227 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4228 (hashtab_key_t) id);
4229 if (!cdatum) {
4230 yyerror2("unknown category %s", id);
4231 return -1;
4232 }
4233 range_start = range_end = cdatum->s.value;
4234 }
4235
4236 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
4237 if (!newcat) {
4238 yyerror("out of memory");
4239 return -1;
4240 }
4241
4242 mls_semantic_cat_init(newcat);
4243 newcat->next = *cats;
4244 newcat->low = range_start;
4245 newcat->high = range_end;
4246
4247 *cats = newcat;
4248
4249 return 0;
4250 }
4251
define_user(void)4252 int define_user(void)
4253 {
4254 char *id;
4255 user_datum_t *usrdatum;
4256 level_datum_t *levdatum;
4257 int l;
4258
4259 if (pass == 1) {
4260 while ((id = queue_remove(id_queue)))
4261 free(id);
4262 if (mlspol) {
4263 while ((id = queue_remove(id_queue)))
4264 free(id);
4265 id = queue_remove(id_queue);
4266 free(id);
4267 for (l = 0; l < 2; l++) {
4268 while ((id = queue_remove(id_queue))) {
4269 free(id);
4270 }
4271 id = queue_remove(id_queue);
4272 if (!id)
4273 break;
4274 free(id);
4275 }
4276 }
4277 return 0;
4278 }
4279
4280 if ((usrdatum = declare_user()) == NULL) {
4281 return -1;
4282 }
4283
4284 while ((id = queue_remove(id_queue))) {
4285 if (set_user_roles(&usrdatum->roles, id))
4286 continue;
4287 }
4288
4289 if (mlspol) {
4290 id = queue_remove(id_queue);
4291 if (!id) {
4292 yyerror("no default level specified for user");
4293 return -1;
4294 }
4295
4296 levdatum = (level_datum_t *)
4297 hashtab_search(policydbp->p_levels.table,
4298 (hashtab_key_t) id);
4299 if (!levdatum) {
4300 yyerror2("unknown sensitivity %s used in user"
4301 " level definition", id);
4302 free(id);
4303 return -1;
4304 }
4305 free(id);
4306
4307 usrdatum->dfltlevel.sens = levdatum->level->sens;
4308
4309 while ((id = queue_remove(id_queue))) {
4310 if (parse_semantic_categories(id, levdatum,
4311 &usrdatum->dfltlevel.cat)) {
4312 free(id);
4313 return -1;
4314 }
4315 free(id);
4316 }
4317
4318 id = queue_remove(id_queue);
4319
4320 for (l = 0; l < 2; l++) {
4321 levdatum = (level_datum_t *)
4322 hashtab_search(policydbp->p_levels.table,
4323 (hashtab_key_t) id);
4324 if (!levdatum) {
4325 yyerror2("unknown sensitivity %s used in user"
4326 " range definition", id);
4327 free(id);
4328 return -1;
4329 }
4330 free(id);
4331
4332 usrdatum->range.level[l].sens = levdatum->level->sens;
4333
4334 while ((id = queue_remove(id_queue))) {
4335 if (parse_semantic_categories(id, levdatum,
4336 &usrdatum->range.level[l].cat)) {
4337 free(id);
4338 return -1;
4339 }
4340 free(id);
4341 }
4342
4343 id = queue_remove(id_queue);
4344 if (!id)
4345 break;
4346 }
4347
4348 if (l == 0) {
4349 if (mls_semantic_level_cpy(&usrdatum->range.level[1],
4350 &usrdatum->range.level[0])) {
4351 yyerror("out of memory");
4352 return -1;
4353 }
4354 }
4355 }
4356 return 0;
4357 }
4358
parse_security_context(context_struct_t * c)4359 static int parse_security_context(context_struct_t * c)
4360 {
4361 char *id;
4362 role_datum_t *role;
4363 type_datum_t *typdatum;
4364 user_datum_t *usrdatum;
4365 level_datum_t *levdatum;
4366 int l;
4367
4368 if (pass == 1) {
4369 id = queue_remove(id_queue);
4370 free(id); /* user */
4371 id = queue_remove(id_queue);
4372 free(id); /* role */
4373 id = queue_remove(id_queue);
4374 free(id); /* type */
4375 if (mlspol) {
4376 id = queue_remove(id_queue);
4377 free(id);
4378 for (l = 0; l < 2; l++) {
4379 while ((id = queue_remove(id_queue))) {
4380 free(id);
4381 }
4382 id = queue_remove(id_queue);
4383 if (!id)
4384 break;
4385 free(id);
4386 }
4387 }
4388 return 0;
4389 }
4390
4391 /* check context c to make sure ok to dereference c later */
4392 if (c == NULL) {
4393 yyerror("null context pointer!");
4394 return -1;
4395 }
4396
4397 context_init(c);
4398
4399 /* extract the user */
4400 id = queue_remove(id_queue);
4401 if (!id) {
4402 yyerror("no effective user?");
4403 goto bad;
4404 }
4405 if (!is_id_in_scope(SYM_USERS, id)) {
4406 yyerror2("user %s is not within scope", id);
4407 free(id);
4408 goto bad;
4409 }
4410 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
4411 (hashtab_key_t) id);
4412 if (!usrdatum) {
4413 yyerror2("user %s is not defined", id);
4414 free(id);
4415 goto bad;
4416 }
4417 c->user = usrdatum->s.value;
4418
4419 /* no need to keep the user name */
4420 free(id);
4421
4422 /* extract the role */
4423 id = (char *)queue_remove(id_queue);
4424 if (!id) {
4425 yyerror("no role name for sid context definition?");
4426 return -1;
4427 }
4428 if (!is_id_in_scope(SYM_ROLES, id)) {
4429 yyerror2("role %s is not within scope", id);
4430 free(id);
4431 return -1;
4432 }
4433 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
4434 (hashtab_key_t) id);
4435 if (!role) {
4436 yyerror2("role %s is not defined", id);
4437 free(id);
4438 return -1;
4439 }
4440 c->role = role->s.value;
4441
4442 /* no need to keep the role name */
4443 free(id);
4444
4445 /* extract the type */
4446 id = (char *)queue_remove(id_queue);
4447 if (!id) {
4448 yyerror("no type name for sid context definition?");
4449 return -1;
4450 }
4451 if (!is_id_in_scope(SYM_TYPES, id)) {
4452 yyerror2("type %s is not within scope", id);
4453 free(id);
4454 return -1;
4455 }
4456 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
4457 (hashtab_key_t) id);
4458 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
4459 yyerror2("type %s is not defined or is an attribute", id);
4460 free(id);
4461 return -1;
4462 }
4463 c->type = typdatum->s.value;
4464
4465 /* no need to keep the type name */
4466 free(id);
4467
4468 if (mlspol) {
4469 /* extract the low sensitivity */
4470 id = (char *)queue_head(id_queue);
4471 if (!id) {
4472 yyerror("no sensitivity name for sid context"
4473 " definition?");
4474 return -1;
4475 }
4476
4477 id = (char *)queue_remove(id_queue);
4478 for (l = 0; l < 2; l++) {
4479 levdatum = (level_datum_t *)
4480 hashtab_search(policydbp->p_levels.table,
4481 (hashtab_key_t) id);
4482 if (!levdatum) {
4483 yyerror2("Sensitivity %s is not defined", id);
4484 free(id);
4485 return -1;
4486 }
4487 free(id);
4488 c->range.level[l].sens = levdatum->level->sens;
4489
4490 /* extract low category set */
4491 while ((id = queue_remove(id_queue))) {
4492 if (parse_categories(id, levdatum,
4493 &c->range.level[l].cat)) {
4494 free(id);
4495 return -1;
4496 }
4497 free(id);
4498 }
4499
4500 /* extract high sensitivity */
4501 id = (char *)queue_remove(id_queue);
4502 if (!id)
4503 break;
4504 }
4505
4506 if (l == 0) {
4507 c->range.level[1].sens = c->range.level[0].sens;
4508 if (ebitmap_cpy(&c->range.level[1].cat,
4509 &c->range.level[0].cat)) {
4510
4511 yyerror("out of memory");
4512 goto bad;
4513 }
4514 }
4515 }
4516
4517 if (!policydb_context_isvalid(policydbp, c)) {
4518 yyerror("invalid security context");
4519 goto bad;
4520 }
4521 return 0;
4522
4523 bad:
4524 context_destroy(c);
4525
4526 return -1;
4527 }
4528
define_initial_sid_context(void)4529 int define_initial_sid_context(void)
4530 {
4531 char *id;
4532 ocontext_t *c, *head;
4533
4534 if (pass == 1) {
4535 id = (char *)queue_remove(id_queue);
4536 free(id);
4537 parse_security_context(NULL);
4538 return 0;
4539 }
4540
4541 id = (char *)queue_remove(id_queue);
4542 if (!id) {
4543 yyerror("no sid name for SID context definition?");
4544 return -1;
4545 }
4546 head = policydbp->ocontexts[OCON_ISID];
4547 for (c = head; c; c = c->next) {
4548 if (!strcmp(id, c->u.name))
4549 break;
4550 }
4551
4552 if (!c) {
4553 yyerror2("SID %s is not defined", id);
4554 free(id);
4555 return -1;
4556 }
4557 if (c->context[0].user) {
4558 yyerror2("The context for SID %s is multiply defined", id);
4559 free(id);
4560 return -1;
4561 }
4562 /* no need to keep the sid name */
4563 free(id);
4564
4565 if (parse_security_context(&c->context[0]))
4566 return -1;
4567
4568 return 0;
4569 }
4570
define_fs_context(unsigned int major,unsigned int minor)4571 int define_fs_context(unsigned int major, unsigned int minor)
4572 {
4573 ocontext_t *newc, *c, *head;
4574
4575 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4576 yyerror("fscon not supported for target");
4577 return -1;
4578 }
4579
4580 if (pass == 1) {
4581 parse_security_context(NULL);
4582 parse_security_context(NULL);
4583 return 0;
4584 }
4585
4586 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4587 if (!newc) {
4588 yyerror("out of memory");
4589 return -1;
4590 }
4591 memset(newc, 0, sizeof(ocontext_t));
4592
4593 newc->u.name = (char *)malloc(6);
4594 if (!newc->u.name) {
4595 yyerror("out of memory");
4596 free(newc);
4597 return -1;
4598 }
4599 sprintf(newc->u.name, "%02x:%02x", major, minor);
4600
4601 if (parse_security_context(&newc->context[0])) {
4602 free(newc->u.name);
4603 free(newc);
4604 return -1;
4605 }
4606 if (parse_security_context(&newc->context[1])) {
4607 context_destroy(&newc->context[0]);
4608 free(newc->u.name);
4609 free(newc);
4610 return -1;
4611 }
4612 head = policydbp->ocontexts[OCON_FS];
4613
4614 for (c = head; c; c = c->next) {
4615 if (!strcmp(newc->u.name, c->u.name)) {
4616 yyerror2("duplicate entry for file system %s",
4617 newc->u.name);
4618 context_destroy(&newc->context[0]);
4619 context_destroy(&newc->context[1]);
4620 free(newc->u.name);
4621 free(newc);
4622 return -1;
4623 }
4624 }
4625
4626 newc->next = head;
4627 policydbp->ocontexts[OCON_FS] = newc;
4628
4629 return 0;
4630 }
4631
define_pirq_context(unsigned int pirq)4632 int define_pirq_context(unsigned int pirq)
4633 {
4634 ocontext_t *newc, *c, *l, *head;
4635 char *id;
4636
4637 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4638 yyerror("pirqcon not supported for target");
4639 return -1;
4640 }
4641
4642 if (pass == 1) {
4643 id = (char *) queue_remove(id_queue);
4644 free(id);
4645 parse_security_context(NULL);
4646 return 0;
4647 }
4648
4649 newc = malloc(sizeof(ocontext_t));
4650 if (!newc) {
4651 yyerror("out of memory");
4652 return -1;
4653 }
4654 memset(newc, 0, sizeof(ocontext_t));
4655
4656 newc->u.pirq = pirq;
4657
4658 if (parse_security_context(&newc->context[0])) {
4659 free(newc);
4660 return -1;
4661 }
4662
4663 head = policydbp->ocontexts[OCON_XEN_PIRQ];
4664 for (l = NULL, c = head; c; l = c, c = c->next) {
4665 unsigned int pirq2;
4666
4667 pirq2 = c->u.pirq;
4668 if (pirq == pirq2) {
4669 yyerror2("duplicate pirqcon entry for %d ", pirq);
4670 goto bad;
4671 }
4672 }
4673
4674 if (l)
4675 l->next = newc;
4676 else
4677 policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
4678
4679 return 0;
4680
4681 bad:
4682 free(newc);
4683 return -1;
4684 }
4685
define_iomem_context(uint64_t low,uint64_t high)4686 int define_iomem_context(uint64_t low, uint64_t high)
4687 {
4688 ocontext_t *newc, *c, *l, *head;
4689 char *id;
4690
4691 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4692 yyerror("iomemcon not supported for target");
4693 return -1;
4694 }
4695
4696 if (pass == 1) {
4697 id = (char *)queue_remove(id_queue);
4698 free(id);
4699 parse_security_context(NULL);
4700 return 0;
4701 }
4702
4703 newc = malloc(sizeof(ocontext_t));
4704 if (!newc) {
4705 yyerror("out of memory");
4706 return -1;
4707 }
4708 memset(newc, 0, sizeof(ocontext_t));
4709
4710 newc->u.iomem.low_iomem = low;
4711 newc->u.iomem.high_iomem = high;
4712
4713 if (low > high) {
4714 yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
4715 free(newc);
4716 return -1;
4717 }
4718
4719 if (parse_security_context(&newc->context[0])) {
4720 free(newc);
4721 return -1;
4722 }
4723
4724 head = policydbp->ocontexts[OCON_XEN_IOMEM];
4725 for (l = NULL, c = head; c; l = c, c = c->next) {
4726 uint64_t low2, high2;
4727
4728 low2 = c->u.iomem.low_iomem;
4729 high2 = c->u.iomem.high_iomem;
4730 if (low <= high2 && low2 <= high) {
4731 yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
4732 "earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
4733 low2, high2);
4734 goto bad;
4735 }
4736 }
4737
4738 if (l)
4739 l->next = newc;
4740 else
4741 policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
4742
4743 return 0;
4744
4745 bad:
4746 free(newc);
4747 return -1;
4748 }
4749
define_ioport_context(unsigned long low,unsigned long high)4750 int define_ioport_context(unsigned long low, unsigned long high)
4751 {
4752 ocontext_t *newc, *c, *l, *head;
4753 char *id;
4754
4755 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4756 yyerror("ioportcon not supported for target");
4757 return -1;
4758 }
4759
4760 if (pass == 1) {
4761 id = (char *)queue_remove(id_queue);
4762 free(id);
4763 parse_security_context(NULL);
4764 return 0;
4765 }
4766
4767 newc = malloc(sizeof(ocontext_t));
4768 if (!newc) {
4769 yyerror("out of memory");
4770 return -1;
4771 }
4772 memset(newc, 0, sizeof(ocontext_t));
4773
4774 newc->u.ioport.low_ioport = low;
4775 newc->u.ioport.high_ioport = high;
4776
4777 if (low > high) {
4778 yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low, high);
4779 free(newc);
4780 return -1;
4781 }
4782
4783 if (parse_security_context(&newc->context[0])) {
4784 free(newc);
4785 return -1;
4786 }
4787
4788 head = policydbp->ocontexts[OCON_XEN_IOPORT];
4789 for (l = NULL, c = head; c; l = c, c = c->next) {
4790 uint32_t low2, high2;
4791
4792 low2 = c->u.ioport.low_ioport;
4793 high2 = c->u.ioport.high_ioport;
4794 if (low <= high2 && low2 <= high) {
4795 yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with"
4796 "earlier entry 0x%x-0x%x", low, high,
4797 low2, high2);
4798 goto bad;
4799 }
4800 }
4801
4802 if (l)
4803 l->next = newc;
4804 else
4805 policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
4806
4807 return 0;
4808
4809 bad:
4810 free(newc);
4811 return -1;
4812 }
4813
define_pcidevice_context(unsigned long device)4814 int define_pcidevice_context(unsigned long device)
4815 {
4816 ocontext_t *newc, *c, *l, *head;
4817 char *id;
4818
4819 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4820 yyerror("pcidevicecon not supported for target");
4821 return -1;
4822 }
4823
4824 if (pass == 1) {
4825 id = (char *) queue_remove(id_queue);
4826 free(id);
4827 parse_security_context(NULL);
4828 return 0;
4829 }
4830
4831 newc = malloc(sizeof(ocontext_t));
4832 if (!newc) {
4833 yyerror("out of memory");
4834 return -1;
4835 }
4836 memset(newc, 0, sizeof(ocontext_t));
4837
4838 newc->u.device = device;
4839
4840 if (parse_security_context(&newc->context[0])) {
4841 free(newc);
4842 return -1;
4843 }
4844
4845 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4846 for (l = NULL, c = head; c; l = c, c = c->next) {
4847 unsigned int device2;
4848
4849 device2 = c->u.device;
4850 if (device == device2) {
4851 yyerror2("duplicate pcidevicecon entry for 0x%lx",
4852 device);
4853 goto bad;
4854 }
4855 }
4856
4857 if (l)
4858 l->next = newc;
4859 else
4860 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4861
4862 return 0;
4863
4864 bad:
4865 free(newc);
4866 return -1;
4867 }
4868
define_devicetree_context()4869 int define_devicetree_context()
4870 {
4871 ocontext_t *newc, *c, *l, *head;
4872
4873 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4874 yyerror("devicetreecon not supported for target");
4875 return -1;
4876 }
4877
4878 if (pass == 1) {
4879 free(queue_remove(id_queue));
4880 parse_security_context(NULL);
4881 return 0;
4882 }
4883
4884 newc = malloc(sizeof(ocontext_t));
4885 if (!newc) {
4886 yyerror("out of memory");
4887 return -1;
4888 }
4889 memset(newc, 0, sizeof(ocontext_t));
4890
4891 newc->u.name = (char *)queue_remove(id_queue);
4892 if (!newc->u.name) {
4893 free(newc);
4894 return -1;
4895 }
4896
4897 if (parse_security_context(&newc->context[0])) {
4898 free(newc->u.name);
4899 free(newc);
4900 return -1;
4901 }
4902
4903 head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
4904 for (l = NULL, c = head; c; l = c, c = c->next) {
4905 if (strcmp(newc->u.name, c->u.name) == 0) {
4906 yyerror2("duplicate devicetree entry for '%s'", newc->u.name);
4907 goto bad;
4908 }
4909 }
4910
4911 if (l)
4912 l->next = newc;
4913 else
4914 policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
4915
4916 return 0;
4917
4918 bad:
4919 free(newc->u.name);
4920 free(newc);
4921 return -1;
4922 }
4923
define_port_context(unsigned int low,unsigned int high)4924 int define_port_context(unsigned int low, unsigned int high)
4925 {
4926 ocontext_t *newc, *c, *l, *head;
4927 unsigned int protocol;
4928 char *id;
4929
4930 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4931 yyerror("portcon not supported for target");
4932 return -1;
4933 }
4934
4935 if (pass == 1) {
4936 id = (char *)queue_remove(id_queue);
4937 free(id);
4938 parse_security_context(NULL);
4939 return 0;
4940 }
4941
4942 newc = malloc(sizeof(ocontext_t));
4943 if (!newc) {
4944 yyerror("out of memory");
4945 return -1;
4946 }
4947 memset(newc, 0, sizeof(ocontext_t));
4948
4949 id = (char *)queue_remove(id_queue);
4950 if (!id) {
4951 free(newc);
4952 return -1;
4953 }
4954 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4955 protocol = IPPROTO_TCP;
4956 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4957 protocol = IPPROTO_UDP;
4958 } else if ((strcmp(id, "dccp") == 0) || (strcmp(id, "DCCP") == 0)) {
4959 protocol = IPPROTO_DCCP;
4960 } else if ((strcmp(id, "sctp") == 0) || (strcmp(id, "SCTP") == 0)) {
4961 protocol = IPPROTO_SCTP;
4962 } else {
4963 yyerror2("unrecognized protocol %s", id);
4964 goto bad;
4965 }
4966
4967 newc->u.port.protocol = protocol;
4968 newc->u.port.low_port = low;
4969 newc->u.port.high_port = high;
4970
4971 if (low > high) {
4972 yyerror2("low port %d exceeds high port %d", low, high);
4973 goto bad;
4974 }
4975
4976 if (parse_security_context(&newc->context[0])) {
4977 goto bad;
4978 }
4979
4980 /* Preserve the matching order specified in the configuration. */
4981 head = policydbp->ocontexts[OCON_PORT];
4982 for (l = NULL, c = head; c; l = c, c = c->next) {
4983 unsigned int prot2, low2, high2;
4984
4985 prot2 = c->u.port.protocol;
4986 low2 = c->u.port.low_port;
4987 high2 = c->u.port.high_port;
4988 if (protocol != prot2)
4989 continue;
4990 if (low == low2 && high == high2) {
4991 yyerror2("duplicate portcon entry for %s %d-%d ", id,
4992 low, high);
4993 goto bad;
4994 }
4995 if (low2 <= low && high2 >= high) {
4996 yyerror2("portcon entry for %s %d-%d hidden by earlier "
4997 "entry for %d-%d", id, low, high, low2, high2);
4998 goto bad;
4999 }
5000 }
5001
5002 if (l)
5003 l->next = newc;
5004 else
5005 policydbp->ocontexts[OCON_PORT] = newc;
5006
5007 free(id);
5008 return 0;
5009
5010 bad:
5011 free(id);
5012 free(newc);
5013 return -1;
5014 }
5015
define_ibpkey_context(unsigned int low,unsigned int high)5016 int define_ibpkey_context(unsigned int low, unsigned int high)
5017 {
5018 ocontext_t *newc, *c, *l, *head;
5019 struct in6_addr subnet_prefix;
5020 char *id;
5021 int rc = 0;
5022
5023 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5024 yyerror("ibpkeycon not supported for target");
5025 return -1;
5026 }
5027
5028 if (pass == 1) {
5029 id = (char *)queue_remove(id_queue);
5030 free(id);
5031 parse_security_context(NULL);
5032 return 0;
5033 }
5034
5035 newc = malloc(sizeof(*newc));
5036 if (!newc) {
5037 yyerror("out of memory");
5038 return -1;
5039 }
5040 memset(newc, 0, sizeof(*newc));
5041
5042 id = queue_remove(id_queue);
5043 if (!id) {
5044 yyerror("failed to read the subnet prefix");
5045 rc = -1;
5046 goto out;
5047 }
5048
5049 rc = inet_pton(AF_INET6, id, &subnet_prefix);
5050 free(id);
5051 if (rc < 1) {
5052 yyerror("failed to parse the subnet prefix");
5053 if (rc == 0)
5054 rc = -1;
5055 goto out;
5056 }
5057
5058 if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) {
5059 yyerror("subnet prefix should be 0's in the low order 64 bits.");
5060 rc = -1;
5061 goto out;
5062 }
5063
5064 if (low > 0xffff || high > 0xffff) {
5065 yyerror("pkey value too large, pkeys are 16 bits.");
5066 rc = -1;
5067 goto out;
5068 }
5069
5070 memcpy(&newc->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0],
5071 sizeof(newc->u.ibpkey.subnet_prefix));
5072
5073 newc->u.ibpkey.low_pkey = low;
5074 newc->u.ibpkey.high_pkey = high;
5075
5076 if (low > high) {
5077 yyerror2("low pkey %d exceeds high pkey %d", low, high);
5078 rc = -1;
5079 goto out;
5080 }
5081
5082 rc = parse_security_context(&newc->context[0]);
5083 if (rc)
5084 goto out;
5085
5086 /* Preserve the matching order specified in the configuration. */
5087 head = policydbp->ocontexts[OCON_IBPKEY];
5088 for (l = NULL, c = head; c; l = c, c = c->next) {
5089 unsigned int low2, high2;
5090
5091 low2 = c->u.ibpkey.low_pkey;
5092 high2 = c->u.ibpkey.high_pkey;
5093
5094 if (low == low2 && high == high2 &&
5095 c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5096 yyerror2("duplicate ibpkeycon entry for %d-%d ",
5097 low, high);
5098 rc = -1;
5099 goto out;
5100 }
5101 if (low2 <= low && high2 >= high &&
5102 c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5103 yyerror2("ibpkeycon entry for %d-%d hidden by earlier entry for %d-%d",
5104 low, high, low2, high2);
5105 rc = -1;
5106 goto out;
5107 }
5108 }
5109
5110 if (l)
5111 l->next = newc;
5112 else
5113 policydbp->ocontexts[OCON_IBPKEY] = newc;
5114
5115 return 0;
5116
5117 out:
5118 free(newc);
5119 return rc;
5120 }
5121
define_ibendport_context(unsigned int port)5122 int define_ibendport_context(unsigned int port)
5123 {
5124 ocontext_t *newc, *c, *l, *head;
5125 char *id;
5126 int rc = 0;
5127
5128 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5129 yyerror("ibendportcon not supported for target");
5130 return -1;
5131 }
5132
5133 if (pass == 1) {
5134 id = (char *)queue_remove(id_queue);
5135 free(id);
5136 parse_security_context(NULL);
5137 return 0;
5138 }
5139
5140 if (port > 0xff || port == 0) {
5141 yyerror("Invalid ibendport port number, should be 0 < port < 256");
5142 return -1;
5143 }
5144
5145 newc = malloc(sizeof(*newc));
5146 if (!newc) {
5147 yyerror("out of memory");
5148 return -1;
5149 }
5150 memset(newc, 0, sizeof(*newc));
5151
5152 newc->u.ibendport.dev_name = queue_remove(id_queue);
5153 if (!newc->u.ibendport.dev_name) {
5154 yyerror("failed to read infiniband device name.");
5155 rc = -1;
5156 goto out;
5157 }
5158
5159 if (strlen(newc->u.ibendport.dev_name) > IB_DEVICE_NAME_MAX - 1) {
5160 yyerror("infiniband device name exceeds max length of 63.");
5161 rc = -1;
5162 goto out;
5163 }
5164
5165 newc->u.ibendport.port = port;
5166
5167 if (parse_security_context(&newc->context[0])) {
5168 free(newc);
5169 return -1;
5170 }
5171
5172 /* Preserve the matching order specified in the configuration. */
5173 head = policydbp->ocontexts[OCON_IBENDPORT];
5174 for (l = NULL, c = head; c; l = c, c = c->next) {
5175 unsigned int port2;
5176
5177 port2 = c->u.ibendport.port;
5178
5179 if (port == port2 &&
5180 !strcmp(c->u.ibendport.dev_name,
5181 newc->u.ibendport.dev_name)) {
5182 yyerror2("duplicate ibendportcon entry for %s port %u",
5183 newc->u.ibendport.dev_name, port);
5184 rc = -1;
5185 goto out;
5186 }
5187 }
5188
5189 if (l)
5190 l->next = newc;
5191 else
5192 policydbp->ocontexts[OCON_IBENDPORT] = newc;
5193
5194 return 0;
5195
5196 out:
5197 free(newc->u.ibendport.dev_name);
5198 free(newc);
5199 return rc;
5200 }
5201
define_netif_context(void)5202 int define_netif_context(void)
5203 {
5204 ocontext_t *newc, *c, *head;
5205
5206 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5207 yyerror("netifcon not supported for target");
5208 return -1;
5209 }
5210
5211 if (pass == 1) {
5212 free(queue_remove(id_queue));
5213 parse_security_context(NULL);
5214 parse_security_context(NULL);
5215 return 0;
5216 }
5217
5218 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5219 if (!newc) {
5220 yyerror("out of memory");
5221 return -1;
5222 }
5223 memset(newc, 0, sizeof(ocontext_t));
5224
5225 newc->u.name = (char *)queue_remove(id_queue);
5226 if (!newc->u.name) {
5227 free(newc);
5228 return -1;
5229 }
5230 if (parse_security_context(&newc->context[0])) {
5231 free(newc->u.name);
5232 free(newc);
5233 return -1;
5234 }
5235 if (parse_security_context(&newc->context[1])) {
5236 context_destroy(&newc->context[0]);
5237 free(newc->u.name);
5238 free(newc);
5239 return -1;
5240 }
5241 head = policydbp->ocontexts[OCON_NETIF];
5242
5243 for (c = head; c; c = c->next) {
5244 if (!strcmp(newc->u.name, c->u.name)) {
5245 yyerror2("duplicate entry for network interface %s",
5246 newc->u.name);
5247 context_destroy(&newc->context[0]);
5248 context_destroy(&newc->context[1]);
5249 free(newc->u.name);
5250 free(newc);
5251 return -1;
5252 }
5253 }
5254
5255 newc->next = head;
5256 policydbp->ocontexts[OCON_NETIF] = newc;
5257 return 0;
5258 }
5259
define_ipv4_node_context()5260 int define_ipv4_node_context()
5261 {
5262 char *id;
5263 int rc = 0;
5264 struct in_addr addr, mask;
5265 ocontext_t *newc, *c, *l, *head;
5266
5267 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5268 yyerror("nodecon not supported for target");
5269 return -1;
5270 }
5271
5272 if (pass == 1) {
5273 free(queue_remove(id_queue));
5274 free(queue_remove(id_queue));
5275 parse_security_context(NULL);
5276 goto out;
5277 }
5278
5279 id = queue_remove(id_queue);
5280 if (!id) {
5281 yyerror("failed to read ipv4 address");
5282 rc = -1;
5283 goto out;
5284 }
5285
5286 rc = inet_pton(AF_INET, id, &addr);
5287 free(id);
5288 if (rc < 1) {
5289 yyerror("failed to parse ipv4 address");
5290 if (rc == 0)
5291 rc = -1;
5292 goto out;
5293 }
5294
5295 id = queue_remove(id_queue);
5296 if (!id) {
5297 yyerror("failed to read ipv4 address");
5298 rc = -1;
5299 goto out;
5300 }
5301
5302 rc = inet_pton(AF_INET, id, &mask);
5303 free(id);
5304 if (rc < 1) {
5305 yyerror("failed to parse ipv4 mask");
5306 if (rc == 0)
5307 rc = -1;
5308 goto out;
5309 }
5310
5311 if (mask.s_addr != 0 && ((~mask.s_addr + 1) & ~mask.s_addr) != 0) {
5312 yywarn("ipv4 mask is not contiguous");
5313 }
5314
5315 if ((~mask.s_addr & addr.s_addr) != 0) {
5316 yywarn("host bits in ipv4 address set");
5317 }
5318
5319 newc = malloc(sizeof(ocontext_t));
5320 if (!newc) {
5321 yyerror("out of memory");
5322 rc = -1;
5323 goto out;
5324 }
5325
5326 memset(newc, 0, sizeof(ocontext_t));
5327 newc->u.node.addr = addr.s_addr;
5328 newc->u.node.mask = mask.s_addr;
5329
5330 if (parse_security_context(&newc->context[0])) {
5331 free(newc);
5332 return -1;
5333 }
5334
5335 /* Create order of most specific to least retaining
5336 the order specified in the configuration. */
5337 head = policydbp->ocontexts[OCON_NODE];
5338 for (l = NULL, c = head; c; l = c, c = c->next) {
5339 if (newc->u.node.mask > c->u.node.mask)
5340 break;
5341 }
5342
5343 newc->next = c;
5344
5345 if (l)
5346 l->next = newc;
5347 else
5348 policydbp->ocontexts[OCON_NODE] = newc;
5349 rc = 0;
5350 out:
5351 return rc;
5352 }
5353
ipv6_is_mask_contiguous(const struct in6_addr * mask)5354 static int ipv6_is_mask_contiguous(const struct in6_addr *mask)
5355 {
5356 int filled = 1;
5357 unsigned i;
5358
5359 for (i = 0; i < 16; i++) {
5360 if ((((~mask->s6_addr[i] & 0xFF) + 1) & (~mask->s6_addr[i] & 0xFF)) != 0) {
5361 return 0;
5362 }
5363 if (!filled && mask->s6_addr[i] != 0) {
5364 return 0;
5365 }
5366
5367 if (filled && mask->s6_addr[i] != 0xFF) {
5368 filled = 0;
5369 }
5370 }
5371
5372 return 1;
5373 }
5374
ipv6_has_host_bits_set(const struct in6_addr * addr,const struct in6_addr * mask)5375 static int ipv6_has_host_bits_set(const struct in6_addr *addr, const struct in6_addr *mask)
5376 {
5377 unsigned i;
5378
5379 for (i = 0; i < 16; i++) {
5380 if ((addr->s6_addr[i] & ~mask->s6_addr[i]) != 0) {
5381 return 1;
5382 }
5383 }
5384
5385 return 0;
5386 }
5387
define_ipv6_node_context(void)5388 int define_ipv6_node_context(void)
5389 {
5390 char *id;
5391 int rc = 0;
5392 struct in6_addr addr, mask;
5393 ocontext_t *newc, *c, *l, *head;
5394
5395 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5396 yyerror("nodecon not supported for target");
5397 return -1;
5398 }
5399
5400 if (pass == 1) {
5401 free(queue_remove(id_queue));
5402 free(queue_remove(id_queue));
5403 parse_security_context(NULL);
5404 goto out;
5405 }
5406
5407 id = queue_remove(id_queue);
5408 if (!id) {
5409 yyerror("failed to read ipv6 address");
5410 rc = -1;
5411 goto out;
5412 }
5413
5414 rc = inet_pton(AF_INET6, id, &addr);
5415 free(id);
5416 if (rc < 1) {
5417 yyerror("failed to parse ipv6 address");
5418 if (rc == 0)
5419 rc = -1;
5420 goto out;
5421 }
5422
5423 id = queue_remove(id_queue);
5424 if (!id) {
5425 yyerror("failed to read ipv6 address");
5426 rc = -1;
5427 goto out;
5428 }
5429
5430 rc = inet_pton(AF_INET6, id, &mask);
5431 free(id);
5432 if (rc < 1) {
5433 yyerror("failed to parse ipv6 mask");
5434 if (rc == 0)
5435 rc = -1;
5436 goto out;
5437 }
5438
5439 if (!ipv6_is_mask_contiguous(&mask)) {
5440 yywarn("ipv6 mask is not contiguous");
5441 }
5442
5443 if (ipv6_has_host_bits_set(&addr, &mask)) {
5444 yywarn("host bits in ipv6 address set");
5445 }
5446
5447 newc = malloc(sizeof(ocontext_t));
5448 if (!newc) {
5449 yyerror("out of memory");
5450 rc = -1;
5451 goto out;
5452 }
5453
5454 memset(newc, 0, sizeof(ocontext_t));
5455 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5456 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5457
5458 if (parse_security_context(&newc->context[0])) {
5459 free(newc);
5460 rc = -1;
5461 goto out;
5462 }
5463
5464 /* Create order of most specific to least retaining
5465 the order specified in the configuration. */
5466 head = policydbp->ocontexts[OCON_NODE6];
5467 for (l = NULL, c = head; c; l = c, c = c->next) {
5468 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
5469 break;
5470 }
5471
5472 newc->next = c;
5473
5474 if (l)
5475 l->next = newc;
5476 else
5477 policydbp->ocontexts[OCON_NODE6] = newc;
5478
5479 rc = 0;
5480 out:
5481 return rc;
5482 }
5483
define_fs_use(int behavior)5484 int define_fs_use(int behavior)
5485 {
5486 ocontext_t *newc, *c, *head;
5487
5488 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5489 yyerror("fsuse not supported for target");
5490 return -1;
5491 }
5492
5493 if (pass == 1) {
5494 free(queue_remove(id_queue));
5495 parse_security_context(NULL);
5496 return 0;
5497 }
5498
5499 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5500 if (!newc) {
5501 yyerror("out of memory");
5502 return -1;
5503 }
5504 memset(newc, 0, sizeof(ocontext_t));
5505
5506 newc->u.name = (char *)queue_remove(id_queue);
5507 if (!newc->u.name) {
5508 free(newc);
5509 return -1;
5510 }
5511 newc->v.behavior = behavior;
5512 if (parse_security_context(&newc->context[0])) {
5513 free(newc->u.name);
5514 free(newc);
5515 return -1;
5516 }
5517
5518 head = policydbp->ocontexts[OCON_FSUSE];
5519
5520 for (c = head; c; c = c->next) {
5521 if (!strcmp(newc->u.name, c->u.name)) {
5522 yyerror2("duplicate fs_use entry for filesystem type %s",
5523 newc->u.name);
5524 context_destroy(&newc->context[0]);
5525 free(newc->u.name);
5526 free(newc);
5527 return -1;
5528 }
5529 }
5530
5531 newc->next = head;
5532 policydbp->ocontexts[OCON_FSUSE] = newc;
5533 return 0;
5534 }
5535
define_genfs_context_helper(char * fstype,int has_type)5536 static int define_genfs_context_helper(char *fstype, int has_type)
5537 {
5538 struct genfs *genfs_p, *genfs, *newgenfs;
5539 ocontext_t *newc, *c, *head, *p;
5540 class_datum_t *cladatum;
5541 char *type = NULL;
5542 const char *sclass;
5543 int len, len2;
5544
5545 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5546 yyerror("genfs not supported for target");
5547 return -1;
5548 }
5549
5550 if (pass == 1) {
5551 free(fstype);
5552 free(queue_remove(id_queue));
5553 if (has_type)
5554 free(queue_remove(id_queue));
5555 parse_security_context(NULL);
5556 return 0;
5557 }
5558
5559 for (genfs_p = NULL, genfs = policydbp->genfs;
5560 genfs; genfs_p = genfs, genfs = genfs->next) {
5561 if (strcmp(fstype, genfs->fstype) <= 0)
5562 break;
5563 }
5564
5565 if (!genfs || strcmp(fstype, genfs->fstype)) {
5566 newgenfs = malloc(sizeof(struct genfs));
5567 if (!newgenfs) {
5568 yyerror("out of memory");
5569 return -1;
5570 }
5571 memset(newgenfs, 0, sizeof(struct genfs));
5572 newgenfs->fstype = fstype;
5573 newgenfs->next = genfs;
5574 if (genfs_p)
5575 genfs_p->next = newgenfs;
5576 else
5577 policydbp->genfs = newgenfs;
5578 genfs = newgenfs;
5579 } else {
5580 free(fstype);
5581 fstype = NULL;
5582 }
5583
5584 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5585 if (!newc) {
5586 yyerror("out of memory");
5587 return -1;
5588 }
5589 memset(newc, 0, sizeof(ocontext_t));
5590
5591 newc->u.name = (char *)queue_remove(id_queue);
5592 if (!newc->u.name)
5593 goto fail;
5594 if (has_type) {
5595 type = (char *)queue_remove(id_queue);
5596 if (!type)
5597 goto fail;
5598 if (type[1] != 0) {
5599 yyerror2("invalid type %s", type);
5600 goto fail;
5601 }
5602 switch (type[0]) {
5603 case 'b':
5604 sclass = "blk_file";
5605 break;
5606 case 'c':
5607 sclass = "chr_file";
5608 break;
5609 case 'd':
5610 sclass = "dir";
5611 break;
5612 case 'p':
5613 sclass = "fifo_file";
5614 break;
5615 case 'l':
5616 sclass = "lnk_file";
5617 break;
5618 case 's':
5619 sclass = "sock_file";
5620 break;
5621 case '-':
5622 sclass = "file";
5623 break;
5624 default:
5625 yyerror2("invalid type %s", type);
5626 goto fail;
5627 }
5628
5629 cladatum = hashtab_search(policydbp->p_classes.table,
5630 sclass);
5631 if (!cladatum) {
5632 yyerror2("could not find class %s for "
5633 "genfscon statement", sclass);
5634 goto fail;
5635 }
5636 newc->v.sclass = cladatum->s.value;
5637 }
5638 if (parse_security_context(&newc->context[0]))
5639 goto fail;
5640
5641 head = genfs->head;
5642
5643 for (p = NULL, c = head; c; p = c, c = c->next) {
5644 if (!strcmp(newc->u.name, c->u.name) &&
5645 (!newc->v.sclass || !c->v.sclass
5646 || newc->v.sclass == c->v.sclass)) {
5647 yyerror2("duplicate entry for genfs entry (%s, %s)",
5648 genfs->fstype, newc->u.name);
5649 goto fail;
5650 }
5651 len = strlen(newc->u.name);
5652 len2 = strlen(c->u.name);
5653 if (len > len2)
5654 break;
5655 }
5656
5657 newc->next = c;
5658 if (p)
5659 p->next = newc;
5660 else
5661 genfs->head = newc;
5662 free(type);
5663 return 0;
5664 fail:
5665 if (type)
5666 free(type);
5667 context_destroy(&newc->context[0]);
5668 if (fstype)
5669 free(fstype);
5670 if (newc->u.name)
5671 free(newc->u.name);
5672 free(newc);
5673 return -1;
5674 }
5675
define_genfs_context(int has_type)5676 int define_genfs_context(int has_type)
5677 {
5678 return define_genfs_context_helper(queue_remove(id_queue), has_type);
5679 }
5680
define_range_trans(int class_specified)5681 int define_range_trans(int class_specified)
5682 {
5683 char *id;
5684 level_datum_t *levdatum = 0;
5685 class_datum_t *cladatum;
5686 range_trans_rule_t *rule;
5687 int l, add = 1;
5688
5689 if (!mlspol) {
5690 yyerror("range_transition rule in non-MLS configuration");
5691 return -1;
5692 }
5693
5694 if (pass == 1) {
5695 while ((id = queue_remove(id_queue)))
5696 free(id);
5697 while ((id = queue_remove(id_queue)))
5698 free(id);
5699 if (class_specified)
5700 while ((id = queue_remove(id_queue)))
5701 free(id);
5702 id = queue_remove(id_queue);
5703 free(id);
5704 for (l = 0; l < 2; l++) {
5705 while ((id = queue_remove(id_queue))) {
5706 free(id);
5707 }
5708 id = queue_remove(id_queue);
5709 if (!id)
5710 break;
5711 free(id);
5712 }
5713 return 0;
5714 }
5715
5716 rule = malloc(sizeof(struct range_trans_rule));
5717 if (!rule) {
5718 yyerror("out of memory");
5719 return -1;
5720 }
5721 range_trans_rule_init(rule);
5722
5723 while ((id = queue_remove(id_queue))) {
5724 if (set_types(&rule->stypes, id, &add, 0))
5725 goto out;
5726 }
5727 add = 1;
5728 while ((id = queue_remove(id_queue))) {
5729 if (set_types(&rule->ttypes, id, &add, 0))
5730 goto out;
5731 }
5732
5733 if (class_specified) {
5734 if (read_classes(&rule->tclasses))
5735 goto out;
5736 } else {
5737 cladatum = hashtab_search(policydbp->p_classes.table,
5738 "process");
5739 if (!cladatum) {
5740 yyerror2("could not find process class for "
5741 "legacy range_transition statement");
5742 goto out;
5743 }
5744
5745 if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) {
5746 yyerror("out of memory");
5747 goto out;
5748 }
5749 }
5750
5751 id = (char *)queue_remove(id_queue);
5752 if (!id) {
5753 yyerror("no range in range_transition definition?");
5754 goto out;
5755 }
5756 for (l = 0; l < 2; l++) {
5757 levdatum = hashtab_search(policydbp->p_levels.table, id);
5758 if (!levdatum) {
5759 yyerror2("unknown level %s used in range_transition "
5760 "definition", id);
5761 free(id);
5762 goto out;
5763 }
5764 free(id);
5765
5766 rule->trange.level[l].sens = levdatum->level->sens;
5767
5768 while ((id = queue_remove(id_queue))) {
5769 if (parse_semantic_categories(id, levdatum,
5770 &rule->trange.level[l].cat)) {
5771 free(id);
5772 goto out;
5773 }
5774 free(id);
5775 }
5776
5777 id = (char *)queue_remove(id_queue);
5778 if (!id)
5779 break;
5780 }
5781 if (l == 0) {
5782 if (mls_semantic_level_cpy(&rule->trange.level[1],
5783 &rule->trange.level[0])) {
5784 yyerror("out of memory");
5785 goto out;
5786 }
5787 }
5788
5789 append_range_trans(rule);
5790 return 0;
5791
5792 out:
5793 range_trans_rule_destroy(rule);
5794 free(rule);
5795 return -1;
5796 }
5797
5798 /* FLASK */
5799