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 (strcmp(id, "self") == 0) {
1638 free(id);
1639 if (add == 0) {
1640 yyerror("-self is not supported");
1641 goto bad;
1642 }
1643 avrule->flags |= RULE_SELF;
1644 continue;
1645 }
1646 if (set_types(&avrule->ttypes, id, &add, 0))
1647 goto bad;
1648 }
1649
1650 ebitmap_init(&tclasses);
1651 if (read_classes(&tclasses))
1652 goto bad;
1653
1654 id = (char *)queue_remove(id_queue);
1655 if (!id) {
1656 yyerror("no newtype?");
1657 goto bad;
1658 }
1659 if (!is_id_in_scope(SYM_TYPES, id)) {
1660 yyerror2("type %s is not within scope", id);
1661 free(id);
1662 goto bad;
1663 }
1664 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1665 (hashtab_key_t) id);
1666 if (!datum || datum->flavor == TYPE_ATTRIB) {
1667 yyerror2("unknown type %s", id);
1668 free(id);
1669 goto bad;
1670 }
1671 free(id);
1672
1673 ebitmap_for_each_positive_bit(&tclasses, node, i) {
1674 perm = malloc(sizeof(class_perm_node_t));
1675 if (!perm) {
1676 yyerror("out of memory");
1677 goto bad;
1678 }
1679 class_perm_node_init(perm);
1680 perm->tclass = i + 1;
1681 perm->data = datum->s.value;
1682 perm->next = avrule->perms;
1683 avrule->perms = perm;
1684 }
1685 ebitmap_destroy(&tclasses);
1686
1687 *rule = avrule;
1688 return 0;
1689
1690 bad:
1691 avrule_destroy(avrule);
1692 free(avrule);
1693 return -1;
1694 }
1695
define_compute_type(int which)1696 int define_compute_type(int which)
1697 {
1698 char *id;
1699 avrule_t *avrule;
1700
1701 if (pass == 1) {
1702 while ((id = queue_remove(id_queue)))
1703 free(id);
1704 while ((id = queue_remove(id_queue)))
1705 free(id);
1706 while ((id = queue_remove(id_queue)))
1707 free(id);
1708 id = queue_remove(id_queue);
1709 free(id);
1710 return 0;
1711 }
1712
1713 if (define_compute_type_helper(which, &avrule))
1714 return -1;
1715
1716 append_avrule(avrule);
1717 return 0;
1718 }
1719
define_cond_compute_type(int which)1720 avrule_t *define_cond_compute_type(int which)
1721 {
1722 char *id;
1723 avrule_t *avrule;
1724
1725 if (pass == 1) {
1726 while ((id = queue_remove(id_queue)))
1727 free(id);
1728 while ((id = queue_remove(id_queue)))
1729 free(id);
1730 while ((id = queue_remove(id_queue)))
1731 free(id);
1732 id = queue_remove(id_queue);
1733 free(id);
1734 return (avrule_t *) 1;
1735 }
1736
1737 if (define_compute_type_helper(which, &avrule))
1738 return COND_ERR;
1739
1740 return avrule;
1741 }
1742
define_bool_tunable(int is_tunable)1743 int define_bool_tunable(int is_tunable)
1744 {
1745 char *id, *bool_value;
1746 cond_bool_datum_t *datum;
1747 int ret;
1748 uint32_t value;
1749
1750 if (pass == 2) {
1751 while ((id = queue_remove(id_queue)))
1752 free(id);
1753 return 0;
1754 }
1755
1756 id = (char *)queue_remove(id_queue);
1757 if (!id) {
1758 yyerror("no identifier for bool definition?");
1759 return -1;
1760 }
1761 if (id_has_dot(id)) {
1762 free(id);
1763 yyerror("boolean identifiers may not contain periods");
1764 return -1;
1765 }
1766 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1767 if (!datum) {
1768 yyerror("out of memory");
1769 free(id);
1770 return -1;
1771 }
1772 memset(datum, 0, sizeof(cond_bool_datum_t));
1773 if (is_tunable)
1774 datum->flags |= COND_BOOL_FLAGS_TUNABLE;
1775 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1776 switch (ret) {
1777 case -3:{
1778 yyerror("Out of memory!");
1779 goto cleanup;
1780 }
1781 case -2:{
1782 yyerror2("duplicate declaration of boolean %s", id);
1783 goto cleanup;
1784 }
1785 case -1:{
1786 yyerror("could not declare boolean here");
1787 goto cleanup;
1788 }
1789 case 0:
1790 case 1:{
1791 break;
1792 }
1793 default:{
1794 assert(0); /* should never get here */
1795 }
1796 }
1797 datum->s.value = value;
1798
1799 bool_value = (char *)queue_remove(id_queue);
1800 if (!bool_value) {
1801 yyerror("no default value for bool definition?");
1802 return -1;
1803 }
1804
1805 datum->state = (bool_value[0] == 'T') ? 1 : 0;
1806 free(bool_value);
1807 return 0;
1808 cleanup:
1809 cond_destroy_bool(id, datum, NULL);
1810 return -1;
1811 }
1812
define_cond_pol_list(avrule_t * avlist,avrule_t * sl)1813 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1814 {
1815 if (pass == 1) {
1816 /* return something so we get through pass 1 */
1817 return (avrule_t *) 1;
1818 }
1819
1820 if (sl == NULL) {
1821 /* This is a require block, return previous list */
1822 return avlist;
1823 }
1824
1825 /* prepend the new avlist to the pre-existing one */
1826 sl->next = avlist;
1827 return sl;
1828 }
1829
1830 typedef struct av_ioctl_range {
1831 uint16_t low;
1832 uint16_t high;
1833 } av_ioctl_range_t;
1834
1835 struct av_ioctl_range_list {
1836 uint8_t omit;
1837 av_ioctl_range_t range;
1838 struct av_ioctl_range_list *next;
1839 };
1840
avrule_sort_ioctls(struct av_ioctl_range_list ** rangehead)1841 static int avrule_sort_ioctls(struct av_ioctl_range_list **rangehead)
1842 {
1843 struct av_ioctl_range_list *r, *r2, *sorted, *sortedhead = NULL;
1844
1845 /* order list by range.low */
1846 for (r = *rangehead; r != NULL; r = r->next) {
1847 sorted = malloc(sizeof(struct av_ioctl_range_list));
1848 if (sorted == NULL)
1849 goto error;
1850 memcpy(sorted, r, sizeof(struct av_ioctl_range_list));
1851 sorted->next = NULL;
1852 if (sortedhead == NULL) {
1853 sortedhead = sorted;
1854 continue;
1855 }
1856 for (r2 = sortedhead; r2 != NULL; r2 = r2->next) {
1857 if (sorted->range.low < r2->range.low) {
1858 /* range is the new head */
1859 sorted->next = r2;
1860 sortedhead = sorted;
1861 break;
1862 } else if ((r2 ->next != NULL) &&
1863 (r->range.low < r2->next->range.low)) {
1864 /* insert range between elements */
1865 sorted->next = r2->next;
1866 r2->next = sorted;
1867 break;
1868 } else if (r2->next == NULL) {
1869 /* range is the new tail*/
1870 r2->next = sorted;
1871 break;
1872 }
1873 }
1874 }
1875
1876 r = *rangehead;
1877 while (r != NULL) {
1878 r2 = r;
1879 r = r->next;
1880 free(r2);
1881 }
1882 *rangehead = sortedhead;
1883 return 0;
1884 error:
1885 yyerror("out of memory");
1886 return -1;
1887 }
1888
avrule_merge_ioctls(struct av_ioctl_range_list ** rangehead)1889 static int avrule_merge_ioctls(struct av_ioctl_range_list **rangehead)
1890 {
1891 struct av_ioctl_range_list *r, *tmp;
1892 r = *rangehead;
1893 while (r != NULL && r->next != NULL) {
1894 /* merge */
1895 if ((r->range.high + 1) >= r->next->range.low) {
1896 /* keep the higher of the two */
1897 if (r->range.high < r->next->range.high)
1898 r->range.high = r->next->range.high;
1899 tmp = r->next;
1900 r->next = r->next->next;
1901 free(tmp);
1902 continue;
1903 }
1904 r = r->next;
1905 }
1906 return 0;
1907 }
1908
avrule_read_ioctls(struct av_ioctl_range_list ** rangehead)1909 static int avrule_read_ioctls(struct av_ioctl_range_list **rangehead)
1910 {
1911 char *id;
1912 struct av_ioctl_range_list *rnew, *r = NULL;
1913 uint8_t omit = 0;
1914
1915 *rangehead = NULL;
1916
1917 /* read in all the ioctl commands */
1918 while ((id = queue_remove(id_queue))) {
1919 if (strcmp(id,"~") == 0) {
1920 /* these are values to be omitted */
1921 free(id);
1922 omit = 1;
1923 } else if (strcmp(id,"-") == 0) {
1924 /* high value of range */
1925 free(id);
1926 id = queue_remove(id_queue);
1927 r->range.high = (uint16_t) strtoul(id,NULL,0);
1928 if (r->range.high < r->range.low) {
1929 yyerror("Ioctl ranges must be in ascending order.");
1930 return -1;
1931 }
1932 free(id);
1933 } else {
1934 /* read in new low value */
1935 rnew = malloc(sizeof(struct av_ioctl_range_list));
1936 if (rnew == NULL)
1937 goto error;
1938 rnew->next = NULL;
1939 if (*rangehead == NULL) {
1940 *rangehead = rnew;
1941 r = *rangehead;
1942 } else {
1943 r->next = rnew;
1944 r = r->next;
1945 }
1946 rnew->range.low = (uint16_t) strtoul(id,NULL,0);
1947 rnew->range.high = rnew->range.low;
1948 free(id);
1949 }
1950 }
1951 r = *rangehead;
1952 if (r) {
1953 r->omit = omit;
1954 }
1955 return 0;
1956 error:
1957 yyerror("out of memory");
1958 return -1;
1959 }
1960
1961 /* flip to included ranges */
avrule_omit_ioctls(struct av_ioctl_range_list ** rangehead)1962 static int avrule_omit_ioctls(struct av_ioctl_range_list **rangehead)
1963 {
1964 struct av_ioctl_range_list *rnew, *r, *newhead, *r2;
1965
1966 rnew = calloc(1, sizeof(struct av_ioctl_range_list));
1967 if (!rnew)
1968 goto error;
1969
1970 newhead = rnew;
1971
1972 r = *rangehead;
1973 r2 = newhead;
1974
1975 if (r->range.low == 0) {
1976 r2->range.low = r->range.high + 1;
1977 r = r->next;
1978 } else {
1979 r2->range.low = 0;
1980 }
1981
1982 while (r) {
1983 r2->range.high = r->range.low - 1;
1984 rnew = calloc(1, sizeof(struct av_ioctl_range_list));
1985 if (!rnew)
1986 goto error;
1987 r2->next = rnew;
1988 r2 = r2->next;
1989
1990 r2->range.low = r->range.high + 1;
1991 if (!r->next)
1992 r2->range.high = 0xffff;
1993 r = r->next;
1994 }
1995
1996 r = *rangehead;
1997 while (r != NULL) {
1998 r2 = r;
1999 r = r->next;
2000 free(r2);
2001 }
2002 *rangehead = newhead;
2003 return 0;
2004
2005 error:
2006 yyerror("out of memory");
2007 return -1;
2008 }
2009
avrule_ioctl_ranges(struct av_ioctl_range_list ** rangelist)2010 static int avrule_ioctl_ranges(struct av_ioctl_range_list **rangelist)
2011 {
2012 struct av_ioctl_range_list *rangehead;
2013 uint8_t omit;
2014
2015 /* read in ranges to include and omit */
2016 if (avrule_read_ioctls(&rangehead))
2017 return -1;
2018 if (rangehead == NULL) {
2019 yyerror("error processing ioctl commands");
2020 return -1;
2021 }
2022 omit = rangehead->omit;
2023 /* sort and merge the input ioctls */
2024 if (avrule_sort_ioctls(&rangehead))
2025 return -1;
2026 if (avrule_merge_ioctls(&rangehead))
2027 return -1;
2028 /* flip ranges if these are omitted */
2029 if (omit) {
2030 if (avrule_omit_ioctls(&rangehead))
2031 return -1;
2032 }
2033
2034 *rangelist = rangehead;
2035 return 0;
2036 }
2037
define_te_avtab_xperms_helper(int which,avrule_t ** rule)2038 static int define_te_avtab_xperms_helper(int which, avrule_t ** rule)
2039 {
2040 char *id;
2041 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2042 class_datum_t *cladatum;
2043 perm_datum_t *perdatum = NULL;
2044 ebitmap_t tclasses;
2045 ebitmap_node_t *node;
2046 avrule_t *avrule;
2047 unsigned int i;
2048 int add = 1, ret = 0;
2049
2050 avrule = (avrule_t *) malloc(sizeof(avrule_t));
2051 if (!avrule) {
2052 yyerror("out of memory");
2053 ret = -1;
2054 goto out;
2055 }
2056 avrule_init(avrule);
2057 avrule->specified = which;
2058 avrule->line = policydb_lineno;
2059 avrule->source_line = source_lineno;
2060 avrule->source_filename = strdup(source_file);
2061 avrule->xperms = NULL;
2062 if (!avrule->source_filename) {
2063 yyerror("out of memory");
2064 return -1;
2065 }
2066
2067 while ((id = queue_remove(id_queue))) {
2068 if (set_types
2069 (&avrule->stypes, id, &add,
2070 which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
2071 ret = -1;
2072 goto out;
2073 }
2074 }
2075 add = 1;
2076 while ((id = queue_remove(id_queue))) {
2077 if (strcmp(id, "self") == 0) {
2078 free(id);
2079 if (add == 0) {
2080 yyerror("-self is not supported");
2081 ret = -1;
2082 goto out;
2083 }
2084 avrule->flags |= RULE_SELF;
2085 continue;
2086 }
2087 if (set_types
2088 (&avrule->ttypes, id, &add,
2089 which == AVRULE_XPERMS_NEVERALLOW ? 1 : 0)) {
2090 ret = -1;
2091 goto out;
2092 }
2093 }
2094
2095 ebitmap_init(&tclasses);
2096 ret = read_classes(&tclasses);
2097 if (ret)
2098 goto out;
2099
2100 perms = NULL;
2101 id = queue_head(id_queue);
2102 ebitmap_for_each_positive_bit(&tclasses, node, i) {
2103 cur_perms =
2104 (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2105 if (!cur_perms) {
2106 yyerror("out of memory");
2107 ret = -1;
2108 goto out;
2109 }
2110 class_perm_node_init(cur_perms);
2111 cur_perms->tclass = i + 1;
2112 if (!perms)
2113 perms = cur_perms;
2114 if (tail)
2115 tail->next = cur_perms;
2116 tail = cur_perms;
2117
2118 cladatum = policydbp->class_val_to_struct[i];
2119 perdatum = hashtab_search(cladatum->permissions.table, id);
2120 if (!perdatum) {
2121 if (cladatum->comdatum) {
2122 perdatum = hashtab_search(cladatum->comdatum->
2123 permissions.table,
2124 id);
2125 }
2126 }
2127 if (!perdatum) {
2128 yyerror2("permission %s is not defined"
2129 " for class %s", id,
2130 policydbp->p_class_val_to_name[i]);
2131 continue;
2132 } else if (!is_perm_in_scope (id, policydbp->p_class_val_to_name[i])) {
2133 yyerror2("permission %s of class %s is"
2134 " not within scope", id,
2135 policydbp->p_class_val_to_name[i]);
2136 continue;
2137 } else {
2138 cur_perms->data |= UINT32_C(1) << (perdatum->s.value - 1);
2139 }
2140 }
2141
2142 ebitmap_destroy(&tclasses);
2143
2144 avrule->perms = perms;
2145 *rule = avrule;
2146
2147 out:
2148 return ret;
2149 }
2150
2151 /* index of the u32 containing the permission */
2152 #define XPERM_IDX(x) ((x) >> 5)
2153 /* set bits 0 through x-1 within the u32 */
2154 #define XPERM_SETBITS(x) ((UINT32_C(1) << ((x) & 0x1f)) - 1)
2155 /* low value for this u32 */
2156 #define XPERM_LOW(x) ((x) << 5)
2157 /* high value for this u32 */
2158 #define XPERM_HIGH(x) ((((x) + 1) << 5) - 1)
avrule_xperm_setrangebits(uint16_t low,uint16_t high,av_extended_perms_t * xperms)2159 static void avrule_xperm_setrangebits(uint16_t low, uint16_t high,
2160 av_extended_perms_t *xperms)
2161 {
2162 unsigned int i;
2163 uint16_t h = high + 1;
2164 /* for each u32 that this low-high range touches, set driver permissions */
2165 for (i = XPERM_IDX(low); i <= XPERM_IDX(high); i++) {
2166 /* set all bits in u32 */
2167 if ((low <= XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
2168 xperms->perms[i] |= ~0U;
2169 /* set low bits */
2170 else if ((low <= XPERM_LOW(i)) && (high < XPERM_HIGH(i)))
2171 xperms->perms[i] |= XPERM_SETBITS(h);
2172 /* set high bits */
2173 else if ((low > XPERM_LOW(i)) && (high >= XPERM_HIGH(i)))
2174 xperms->perms[i] |= ~0U - XPERM_SETBITS(low);
2175 /* set middle bits */
2176 else if ((low > XPERM_LOW(i)) && (high <= XPERM_HIGH(i)))
2177 xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);
2178 }
2179 }
2180
avrule_xperms_used(const av_extended_perms_t * xperms)2181 static int avrule_xperms_used(const av_extended_perms_t *xperms)
2182 {
2183 unsigned int i;
2184
2185 for (i = 0; i < sizeof(xperms->perms)/sizeof(xperms->perms[0]); i++) {
2186 if (xperms->perms[i])
2187 return 1;
2188 }
2189 return 0;
2190 }
2191
2192 /*
2193 * using definitions found in kernel document ioctl-number.txt
2194 * The kernel components of an ioctl command are:
2195 * dir, size, driver, and function. Only the driver and function fields
2196 * are considered here
2197 */
2198 #define IOC_DRIV(x) ((x) >> 8)
2199 #define IOC_FUNC(x) ((x) & 0xff)
2200 #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)2201 static int avrule_ioctl_partialdriver(struct av_ioctl_range_list *rangelist,
2202 av_extended_perms_t *complete_driver,
2203 av_extended_perms_t **extended_perms)
2204 {
2205 struct av_ioctl_range_list *r;
2206 av_extended_perms_t *xperms;
2207 uint8_t low, high;
2208
2209 xperms = calloc(1, sizeof(av_extended_perms_t));
2210 if (!xperms) {
2211 yyerror("out of memory");
2212 return - 1;
2213 }
2214
2215 r = rangelist;
2216 while(r) {
2217 low = IOC_DRIV(r->range.low);
2218 high = IOC_DRIV(r->range.high);
2219 if (complete_driver) {
2220 if (!xperm_test(low, complete_driver->perms))
2221 xperm_set(low, xperms->perms);
2222 if (!xperm_test(high, complete_driver->perms))
2223 xperm_set(high, xperms->perms);
2224 } else {
2225 xperm_set(low, xperms->perms);
2226 xperm_set(high, xperms->perms);
2227 }
2228 r = r->next;
2229 }
2230 if (avrule_xperms_used(xperms)) {
2231 *extended_perms = xperms;
2232 } else {
2233 free(xperms);
2234 *extended_perms = NULL;
2235 }
2236 return 0;
2237
2238 }
2239
avrule_ioctl_completedriver(struct av_ioctl_range_list * rangelist,av_extended_perms_t ** extended_perms)2240 static int avrule_ioctl_completedriver(struct av_ioctl_range_list *rangelist,
2241 av_extended_perms_t **extended_perms)
2242 {
2243 struct av_ioctl_range_list *r;
2244 av_extended_perms_t *xperms;
2245 uint16_t low, high;
2246 xperms = calloc(1, sizeof(av_extended_perms_t));
2247 if (!xperms) {
2248 yyerror("out of memory");
2249 return - 1;
2250 }
2251
2252 r = rangelist;
2253 while(r) {
2254 /*
2255 * Any driver code that has sequence 0x00 - 0xff is a complete code,
2256 *
2257 * if command number = 0xff, then round high up to next code,
2258 * else 0x00 - 0xfe keep current code
2259 * of this range. temporarily u32 for the + 1
2260 * to account for possible rollover before right shift
2261 */
2262 high = IOC_DRIV((uint32_t) (r->range.high + 1));
2263 /* if 0x00 keep current driver code else 0x01 - 0xff round up to next code*/
2264 low = IOC_DRIV(r->range.low);
2265 if (IOC_FUNC(r->range.low))
2266 low++;
2267 if (high > low)
2268 avrule_xperm_setrangebits(low, high - 1, xperms);
2269 r = r->next;
2270 }
2271 if (avrule_xperms_used(xperms)) {
2272 xperms->driver = 0x00;
2273 xperms->specified = AVRULE_XPERMS_IOCTLDRIVER;
2274 *extended_perms = xperms;
2275 } else {
2276 free(xperms);
2277 *extended_perms = NULL;
2278 }
2279 return 0;
2280 }
2281
avrule_ioctl_func(struct av_ioctl_range_list * rangelist,av_extended_perms_t ** extended_perms,unsigned int driver)2282 static int avrule_ioctl_func(struct av_ioctl_range_list *rangelist,
2283 av_extended_perms_t **extended_perms, unsigned int driver)
2284 {
2285 struct av_ioctl_range_list *r;
2286 av_extended_perms_t *xperms;
2287 uint16_t low, high;
2288
2289 *extended_perms = NULL;
2290 xperms = calloc(1, sizeof(av_extended_perms_t));
2291 if (!xperms) {
2292 yyerror("out of memory");
2293 return - 1;
2294 }
2295
2296 r = rangelist;
2297 /* for the passed in driver code, find the ranges that apply */
2298 while (r) {
2299 low = r->range.low;
2300 high = r->range.high;
2301 if ((driver != IOC_DRIV(low)) && (driver != IOC_DRIV(high))) {
2302 r = r->next;
2303 continue;
2304 }
2305
2306 if (driver == IOC_DRIV(low)) {
2307 if (high > IOC_CMD(driver, 0xff))
2308 high = IOC_CMD(driver, 0xff);
2309
2310 } else {
2311 if (low < IOC_CMD(driver, 0))
2312 low = IOC_CMD(driver, 0);
2313 }
2314
2315 low = IOC_FUNC(low);
2316 high = IOC_FUNC(high);
2317 avrule_xperm_setrangebits(low, high, xperms);
2318 xperms->driver = driver;
2319 xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION;
2320 r = r->next;
2321 }
2322
2323 if (avrule_xperms_used(xperms)) {
2324 *extended_perms = xperms;
2325 } else {
2326 free(xperms);
2327 *extended_perms = NULL;
2328 }
2329 return 0;
2330 }
2331
xperms_for_each_bit(unsigned int * bit,av_extended_perms_t * xperms)2332 static unsigned int xperms_for_each_bit(unsigned int *bit, av_extended_perms_t *xperms)
2333 {
2334 unsigned int i;
2335 for (i = *bit; i < sizeof(xperms->perms)*8; i++) {
2336 if (xperm_test(i,xperms->perms)) {
2337 xperm_clear(i, xperms->perms);
2338 *bit = i;
2339 return 1;
2340 }
2341 }
2342 return 0;
2343 }
2344
avrule_cpy(avrule_t * dest,const avrule_t * src)2345 static int avrule_cpy(avrule_t *dest, const avrule_t *src)
2346 {
2347 class_perm_node_t *src_perms;
2348 class_perm_node_t *dest_perms, *dest_tail;
2349 dest_tail = NULL;
2350
2351 avrule_init(dest);
2352 dest->specified = src->specified;
2353 dest->flags = src->flags;
2354 if (type_set_cpy(&dest->stypes, &src->stypes)) {
2355 yyerror("out of memory");
2356 return - 1;
2357 }
2358 if (type_set_cpy(&dest->ttypes, &src->ttypes)) {
2359 yyerror("out of memory");
2360 return - 1;
2361 }
2362 dest->line = src->line;
2363 dest->source_filename = strdup(source_file);
2364 if (!dest->source_filename) {
2365 yyerror("out of memory");
2366 return -1;
2367 }
2368 dest->source_line = src->source_line;
2369
2370 /* increment through the class perms and copy over */
2371 src_perms = src->perms;
2372 while (src_perms) {
2373 dest_perms = (class_perm_node_t *) calloc(1, sizeof(class_perm_node_t));
2374 class_perm_node_init(dest_perms);
2375 if (!dest_perms) {
2376 yyerror("out of memory");
2377 return -1;
2378 }
2379 if (!dest->perms)
2380 dest->perms = dest_perms;
2381 else
2382 dest_tail->next = dest_perms;
2383
2384 dest_perms->tclass = src_perms->tclass;
2385 dest_perms->data = src_perms->data;
2386 dest_perms->next = NULL;
2387 dest_tail = dest_perms;
2388 src_perms = src_perms->next;
2389 }
2390 return 0;
2391 }
2392
define_te_avtab_ioctl(const avrule_t * avrule_template)2393 static int define_te_avtab_ioctl(const avrule_t *avrule_template)
2394 {
2395 avrule_t *avrule;
2396 struct av_ioctl_range_list *rangelist, *r;
2397 av_extended_perms_t *complete_driver, *partial_driver, *xperms;
2398 unsigned int i;
2399
2400
2401 /* organize ioctl ranges */
2402 if (avrule_ioctl_ranges(&rangelist))
2403 return -1;
2404
2405 /* create rule for ioctl driver types that are entirely enabled */
2406 if (avrule_ioctl_completedriver(rangelist, &complete_driver))
2407 return -1;
2408 if (complete_driver) {
2409 avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
2410 if (!avrule) {
2411 yyerror("out of memory");
2412 return -1;
2413 }
2414 if (avrule_cpy(avrule, avrule_template))
2415 return -1;
2416 avrule->xperms = complete_driver;
2417 append_avrule(avrule);
2418 }
2419
2420 /* flag ioctl driver codes that are partially enabled */
2421 if (avrule_ioctl_partialdriver(rangelist, complete_driver, &partial_driver))
2422 return -1;
2423
2424 if (!partial_driver || !avrule_xperms_used(partial_driver))
2425 goto done;
2426
2427 /*
2428 * create rule for each partially used driver codes
2429 * "partially used" meaning that the code number e.g. socket 0x89
2430 * has some permission bits set and others not set.
2431 */
2432 i = 0;
2433 while (xperms_for_each_bit(&i, partial_driver)) {
2434 if (avrule_ioctl_func(rangelist, &xperms, i))
2435 return -1;
2436
2437 if (xperms) {
2438 avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
2439 if (!avrule) {
2440 yyerror("out of memory");
2441 return -1;
2442 }
2443 if (avrule_cpy(avrule, avrule_template))
2444 return -1;
2445 avrule->xperms = xperms;
2446 append_avrule(avrule);
2447 }
2448 }
2449
2450 done:
2451 if (partial_driver)
2452 free(partial_driver);
2453
2454 while (rangelist != NULL) {
2455 r = rangelist;
2456 rangelist = rangelist->next;
2457 free(r);
2458 }
2459
2460 return 0;
2461 }
2462
define_te_avtab_extended_perms(int which)2463 int define_te_avtab_extended_perms(int which)
2464 {
2465 char *id;
2466 unsigned int i;
2467 avrule_t *avrule_template;
2468 int rc = 0;
2469
2470 if (pass == 1) {
2471 for (i = 0; i < 4; i++) {
2472 while ((id = queue_remove(id_queue)))
2473 free(id);
2474 }
2475 return 0;
2476 }
2477
2478 /* populate avrule template with source/target/tclass */
2479 if (define_te_avtab_xperms_helper(which, &avrule_template))
2480 return -1;
2481
2482 id = queue_remove(id_queue);
2483 if (strcmp(id,"ioctl") == 0) {
2484 rc = define_te_avtab_ioctl(avrule_template);
2485 } else {
2486 yyerror("only ioctl extended permissions are supported");
2487 rc = -1;
2488 }
2489
2490 free(id);
2491 avrule_destroy(avrule_template);
2492 free(avrule_template);
2493
2494 return rc;
2495 }
2496
define_te_avtab_helper(int which,avrule_t ** rule)2497 static int define_te_avtab_helper(int which, avrule_t ** rule)
2498 {
2499 char *id;
2500 class_datum_t *cladatum;
2501 perm_datum_t *perdatum = NULL;
2502 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
2503 ebitmap_t tclasses;
2504 ebitmap_node_t *node;
2505 avrule_t *avrule;
2506 unsigned int i;
2507 int add = 1, ret = 0;
2508 int suppress = 0;
2509
2510 avrule = (avrule_t *) malloc(sizeof(avrule_t));
2511 if (!avrule) {
2512 yyerror("memory error");
2513 ret = -1;
2514 goto out;
2515 }
2516 avrule_init(avrule);
2517 avrule->specified = which;
2518 avrule->line = policydb_lineno;
2519 avrule->source_line = source_lineno;
2520 avrule->source_filename = strdup(source_file);
2521 avrule->xperms = NULL;
2522 if (!avrule->source_filename) {
2523 yyerror("out of memory");
2524 return -1;
2525 }
2526
2527
2528 while ((id = queue_remove(id_queue))) {
2529 if (set_types
2530 (&avrule->stypes, id, &add,
2531 which == AVRULE_NEVERALLOW ? 1 : 0)) {
2532 ret = -1;
2533 goto out;
2534 }
2535 }
2536 add = 1;
2537 while ((id = queue_remove(id_queue))) {
2538 if (strcmp(id, "self") == 0) {
2539 free(id);
2540 if (add == 0) {
2541 yyerror("-self is not supported");
2542 ret = -1;
2543 goto out;
2544 }
2545 avrule->flags |= RULE_SELF;
2546 continue;
2547 }
2548 if (set_types
2549 (&avrule->ttypes, id, &add,
2550 which == AVRULE_NEVERALLOW ? 1 : 0)) {
2551 ret = -1;
2552 goto out;
2553 }
2554 }
2555
2556 ebitmap_init(&tclasses);
2557 ret = read_classes(&tclasses);
2558 if (ret)
2559 goto out;
2560
2561 perms = NULL;
2562 ebitmap_for_each_positive_bit(&tclasses, node, i) {
2563 cur_perms =
2564 (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
2565 if (!cur_perms) {
2566 yyerror("out of memory");
2567 ret = -1;
2568 goto out;
2569 }
2570 class_perm_node_init(cur_perms);
2571 cur_perms->tclass = i + 1;
2572 if (!perms)
2573 perms = cur_perms;
2574 if (tail)
2575 tail->next = cur_perms;
2576 tail = cur_perms;
2577 }
2578
2579 while ((id = queue_remove(id_queue))) {
2580 cur_perms = perms;
2581 ebitmap_for_each_positive_bit(&tclasses, node, i) {
2582 cladatum = policydbp->class_val_to_struct[i];
2583
2584 if (strcmp(id, "*") == 0) {
2585 /* set all permissions in the class */
2586 cur_perms->data = ~0U;
2587 goto next;
2588 }
2589
2590 if (strcmp(id, "~") == 0) {
2591 /* complement the set */
2592 if (which == AVRULE_DONTAUDIT)
2593 yywarn("dontaudit rule with a ~?");
2594 cur_perms->data = ~cur_perms->data;
2595 goto next;
2596 }
2597
2598 perdatum =
2599 hashtab_search(cladatum->permissions.table, id);
2600 if (!perdatum) {
2601 if (cladatum->comdatum) {
2602 perdatum =
2603 hashtab_search(cladatum->comdatum->
2604 permissions.table,
2605 id);
2606 }
2607 }
2608 if (!perdatum) {
2609 if (!suppress)
2610 yyerror2("permission %s is not defined"
2611 " for class %s", id,
2612 policydbp->p_class_val_to_name[i]);
2613 continue;
2614 } else
2615 if (!is_perm_in_scope
2616 (id, policydbp->p_class_val_to_name[i])) {
2617 if (!suppress) {
2618 yyerror2("permission %s of class %s is"
2619 " not within scope", id,
2620 policydbp->p_class_val_to_name[i]);
2621 }
2622 continue;
2623 } else {
2624 cur_perms->data |= UINT32_C(1) << (perdatum->s.value - 1);
2625 }
2626 next:
2627 cur_perms = cur_perms->next;
2628 }
2629
2630 free(id);
2631 }
2632
2633 ebitmap_destroy(&tclasses);
2634
2635 avrule->perms = perms;
2636 *rule = avrule;
2637
2638 out:
2639 if (ret) {
2640 avrule_destroy(avrule);
2641 free(avrule);
2642 }
2643 return ret;
2644
2645 }
2646
define_cond_te_avtab(int which)2647 avrule_t *define_cond_te_avtab(int which)
2648 {
2649 char *id;
2650 avrule_t *avrule;
2651 int i;
2652
2653 if (pass == 1) {
2654 for (i = 0; i < 4; i++) {
2655 while ((id = queue_remove(id_queue)))
2656 free(id);
2657 }
2658 return (avrule_t *) 1; /* any non-NULL value */
2659 }
2660
2661 if (define_te_avtab_helper(which, &avrule))
2662 return COND_ERR;
2663
2664 return avrule;
2665 }
2666
define_te_avtab(int which)2667 int define_te_avtab(int which)
2668 {
2669 char *id;
2670 avrule_t *avrule;
2671 int i;
2672
2673 if (pass == 1) {
2674 for (i = 0; i < 4; i++) {
2675 while ((id = queue_remove(id_queue)))
2676 free(id);
2677 }
2678 return 0;
2679 }
2680
2681 if (define_te_avtab_helper(which, &avrule))
2682 return -1;
2683
2684 /* append this avrule to the end of the current rules list */
2685 append_avrule(avrule);
2686 return 0;
2687 }
2688
2689 /* The role-types rule is no longer used to declare regular role or
2690 * role attribute, but solely aimed for declaring role-types associations.
2691 */
define_role_types(void)2692 int define_role_types(void)
2693 {
2694 role_datum_t *role;
2695 char *id;
2696 int add = 1;
2697
2698 if (pass == 1) {
2699 while ((id = queue_remove(id_queue)))
2700 free(id);
2701 return 0;
2702 }
2703
2704 id = (char *)queue_remove(id_queue);
2705 if (!id) {
2706 yyerror("no role name for role-types rule?");
2707 return -1;
2708 }
2709
2710 if (!is_id_in_scope(SYM_ROLES, id)) {
2711 yyerror2("role %s is not within scope", id);
2712 free(id);
2713 return -1;
2714 }
2715
2716 role = hashtab_search(policydbp->p_roles.table, id);
2717 if (!role) {
2718 yyerror2("unknown role %s", id);
2719 free(id);
2720 return -1;
2721 }
2722 role = get_local_role(id, role->s.value, (role->flavor == ROLE_ATTRIB));
2723
2724 while ((id = queue_remove(id_queue))) {
2725 if (set_types(&role->types, id, &add, 0))
2726 return -1;
2727 }
2728
2729 return 0;
2730 }
2731
define_attrib_role(void)2732 int define_attrib_role(void)
2733 {
2734 if (pass == 2) {
2735 free(queue_remove(id_queue));
2736 return 0;
2737 }
2738
2739 /* Declare a role attribute */
2740 if (declare_role(TRUE) == NULL)
2741 return -1;
2742
2743 return 0;
2744 }
2745
define_role_attr(void)2746 int define_role_attr(void)
2747 {
2748 char *id;
2749 role_datum_t *r, *attr;
2750
2751 if (pass == 2) {
2752 while ((id = queue_remove(id_queue)))
2753 free(id);
2754 return 0;
2755 }
2756
2757 /* Declare a regular role */
2758 if ((r = declare_role(FALSE)) == NULL)
2759 return -1;
2760
2761 while ((id = queue_remove(id_queue))) {
2762 if (!is_id_in_scope(SYM_ROLES, id)) {
2763 yyerror2("attribute %s is not within scope", id);
2764 free(id);
2765 return -1;
2766 }
2767 attr = hashtab_search(policydbp->p_roles.table, id);
2768 if (!attr) {
2769 /* treat it as a fatal error */
2770 yyerror2("role attribute %s is not declared", id);
2771 free(id);
2772 return -1;
2773 }
2774
2775 if (attr->flavor != ROLE_ATTRIB) {
2776 yyerror2("%s is a regular role, not an attribute", id);
2777 free(id);
2778 return -1;
2779 }
2780
2781 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2782 yyerror("Out of memory!");
2783 return -1;
2784 }
2785
2786 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2787 yyerror("out of memory");
2788 return -1;
2789 }
2790 }
2791
2792 return 0;
2793 }
2794
define_roleattribute(void)2795 int define_roleattribute(void)
2796 {
2797 char *id;
2798 role_datum_t *r, *attr;
2799
2800 if (pass == 2) {
2801 while ((id = queue_remove(id_queue)))
2802 free(id);
2803 return 0;
2804 }
2805
2806 id = (char *)queue_remove(id_queue);
2807 if (!id) {
2808 yyerror("no role name for roleattribute definition?");
2809 return -1;
2810 }
2811
2812 if (!is_id_in_scope(SYM_ROLES, id)) {
2813 yyerror2("role %s is not within scope", id);
2814 free(id);
2815 return -1;
2816 }
2817 r = hashtab_search(policydbp->p_roles.table, id);
2818 /* We support adding one role attribute into another */
2819 if (!r) {
2820 yyerror2("unknown role %s", id);
2821 free(id);
2822 return -1;
2823 }
2824 free(id);
2825
2826 while ((id = queue_remove(id_queue))) {
2827 if (!is_id_in_scope(SYM_ROLES, id)) {
2828 yyerror2("attribute %s is not within scope", id);
2829 free(id);
2830 return -1;
2831 }
2832 attr = hashtab_search(policydbp->p_roles.table, id);
2833 if (!attr) {
2834 /* treat it as a fatal error */
2835 yyerror2("role attribute %s is not declared", id);
2836 free(id);
2837 return -1;
2838 }
2839
2840 if (attr->flavor != ROLE_ATTRIB) {
2841 yyerror2("%s is a regular role, not an attribute", id);
2842 free(id);
2843 return -1;
2844 }
2845
2846 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2847 yyerror("Out of memory!");
2848 return -1;
2849 }
2850
2851 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2852 yyerror("out of memory");
2853 return -1;
2854 }
2855 }
2856
2857 return 0;
2858 }
2859
merge_roles_dom(role_datum_t * r1,role_datum_t * r2)2860 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2861 {
2862 role_datum_t *new;
2863
2864 if (pass == 1) {
2865 return (role_datum_t *) 1; /* any non-NULL value */
2866 }
2867
2868 new = malloc(sizeof(role_datum_t));
2869 if (!new) {
2870 yyerror("out of memory");
2871 return NULL;
2872 }
2873 memset(new, 0, sizeof(role_datum_t));
2874 new->s.value = 0; /* temporary role */
2875 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2876 yyerror("out of memory");
2877 free(new);
2878 return NULL;
2879 }
2880 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
2881 yyerror("out of memory");
2882 free(new);
2883 return NULL;
2884 }
2885 if (!r1->s.value) {
2886 /* free intermediate result */
2887 type_set_destroy(&r1->types);
2888 ebitmap_destroy(&r1->dominates);
2889 free(r1);
2890 }
2891 if (!r2->s.value) {
2892 /* free intermediate result */
2893 yyerror("right hand role is temporary?");
2894 type_set_destroy(&r2->types);
2895 ebitmap_destroy(&r2->dominates);
2896 free(r2);
2897 }
2898 return new;
2899 }
2900
2901 /* This function eliminates the ordering dependency of role dominance rule */
dominate_role_recheck(hashtab_key_t key,hashtab_datum_t datum,void * arg)2902 static int dominate_role_recheck(hashtab_key_t key __attribute__ ((unused)),
2903 hashtab_datum_t datum, void *arg)
2904 {
2905 role_datum_t *rdp = (role_datum_t *) arg;
2906 role_datum_t *rdatum = (role_datum_t *) datum;
2907 ebitmap_node_t *node;
2908 uint32_t i;
2909
2910 /* Don't bother to process against self role */
2911 if (rdatum->s.value == rdp->s.value)
2912 return 0;
2913
2914 /* If a dominating role found */
2915 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
2916 ebitmap_t types;
2917 ebitmap_init(&types);
2918 if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
2919 ebitmap_destroy(&types);
2920 return -1;
2921 }
2922 /* raise types and dominates from dominated role */
2923 ebitmap_for_each_positive_bit(&rdp->dominates, node, i) {
2924 if (ebitmap_set_bit(&rdatum->dominates, i, TRUE))
2925 goto oom;
2926 }
2927 ebitmap_for_each_positive_bit(&types, node, i) {
2928 if (ebitmap_set_bit(&rdatum->types.types, i, TRUE))
2929 goto oom;
2930 }
2931 ebitmap_destroy(&types);
2932 }
2933
2934 /* go through all the roles */
2935 return 0;
2936 oom:
2937 yyerror("Out of memory");
2938 return -1;
2939 }
2940
define_role_dom(role_datum_t * r)2941 role_datum_t *define_role_dom(role_datum_t * r)
2942 {
2943 role_datum_t *role;
2944 char *role_id;
2945 ebitmap_node_t *node;
2946 unsigned int i;
2947 int ret;
2948
2949 if (pass == 1) {
2950 role_id = queue_remove(id_queue);
2951 free(role_id);
2952 return (role_datum_t *) 1; /* any non-NULL value */
2953 }
2954
2955 yywarn("Role dominance has been deprecated");
2956
2957 role_id = queue_remove(id_queue);
2958 if (!is_id_in_scope(SYM_ROLES, role_id)) {
2959 yyerror2("role %s is not within scope", role_id);
2960 free(role_id);
2961 return NULL;
2962 }
2963 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2964 role_id);
2965 if (!role) {
2966 role = (role_datum_t *) malloc(sizeof(role_datum_t));
2967 if (!role) {
2968 yyerror("out of memory");
2969 free(role_id);
2970 return NULL;
2971 }
2972 memset(role, 0, sizeof(role_datum_t));
2973 ret =
2974 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2975 (hashtab_datum_t) role, &role->s.value,
2976 &role->s.value);
2977 switch (ret) {
2978 case -3:{
2979 yyerror("Out of memory!");
2980 goto cleanup;
2981 }
2982 case -2:{
2983 yyerror2("duplicate declaration of role %s",
2984 role_id);
2985 goto cleanup;
2986 }
2987 case -1:{
2988 yyerror("could not declare role here");
2989 goto cleanup;
2990 }
2991 case 0:
2992 case 1:{
2993 break;
2994 }
2995 default:{
2996 assert(0); /* should never get here */
2997 }
2998 }
2999 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
3000 yyerror("Out of memory!");
3001 goto cleanup;
3002 }
3003 }
3004 if (r) {
3005 ebitmap_t types;
3006 ebitmap_init(&types);
3007 ebitmap_for_each_positive_bit(&r->dominates, node, i) {
3008 if (ebitmap_set_bit(&role->dominates, i, TRUE))
3009 goto oom;
3010 }
3011 if (type_set_expand(&r->types, &types, policydbp, 1)) {
3012 ebitmap_destroy(&types);
3013 return NULL;
3014 }
3015 ebitmap_for_each_positive_bit(&types, node, i) {
3016 if (ebitmap_set_bit(&role->types.types, i, TRUE))
3017 goto oom;
3018 }
3019 ebitmap_destroy(&types);
3020 if (!r->s.value) {
3021 /* free intermediate result */
3022 type_set_destroy(&r->types);
3023 ebitmap_destroy(&r->dominates);
3024 free(r);
3025 }
3026 /*
3027 * Now go through all the roles and escalate this role's
3028 * dominates and types if a role dominates this role.
3029 */
3030 hashtab_map(policydbp->p_roles.table,
3031 dominate_role_recheck, role);
3032 }
3033 return role;
3034 cleanup:
3035 free(role_id);
3036 role_datum_destroy(role);
3037 free(role);
3038 return NULL;
3039 oom:
3040 yyerror("Out of memory");
3041 goto cleanup;
3042 }
3043
role_val_to_name_helper(hashtab_key_t key,hashtab_datum_t datum,void * p)3044 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
3045 void *p)
3046 {
3047 struct val_to_name *v = p;
3048 role_datum_t *roldatum;
3049
3050 roldatum = (role_datum_t *) datum;
3051
3052 if (v->val == roldatum->s.value) {
3053 v->name = key;
3054 return 1;
3055 }
3056
3057 return 0;
3058 }
3059
role_val_to_name(unsigned int val)3060 static char *role_val_to_name(unsigned int val)
3061 {
3062 struct val_to_name v;
3063 int rc;
3064
3065 v.val = val;
3066 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
3067 if (rc)
3068 return v.name;
3069 return NULL;
3070 }
3071
set_roles(role_set_t * set,char * id)3072 static int set_roles(role_set_t * set, char *id)
3073 {
3074 role_datum_t *r;
3075
3076 if (strcmp(id, "*") == 0) {
3077 free(id);
3078 yyerror("* is not allowed for role sets");
3079 return -1;
3080 }
3081
3082 if (strcmp(id, "~") == 0) {
3083 free(id);
3084 yyerror("~ is not allowed for role sets");
3085 return -1;
3086 }
3087 if (!is_id_in_scope(SYM_ROLES, id)) {
3088 yyerror2("role %s is not within scope", id);
3089 free(id);
3090 return -1;
3091 }
3092 r = hashtab_search(policydbp->p_roles.table, id);
3093 if (!r) {
3094 yyerror2("unknown role %s", id);
3095 free(id);
3096 return -1;
3097 }
3098
3099 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
3100 yyerror("out of memory");
3101 free(id);
3102 return -1;
3103 }
3104 free(id);
3105 return 0;
3106 }
3107
define_role_trans(int class_specified)3108 int define_role_trans(int class_specified)
3109 {
3110 char *id;
3111 role_datum_t *role;
3112 role_set_t roles;
3113 type_set_t types;
3114 class_datum_t *cladatum;
3115 ebitmap_t e_types, e_roles, e_classes;
3116 ebitmap_node_t *tnode, *rnode, *cnode;
3117 struct role_trans *tr = NULL;
3118 struct role_trans_rule *rule = NULL;
3119 unsigned int i, j, k;
3120 int add = 1;
3121
3122 if (pass == 1) {
3123 while ((id = queue_remove(id_queue)))
3124 free(id);
3125 while ((id = queue_remove(id_queue)))
3126 free(id);
3127 if (class_specified)
3128 while ((id = queue_remove(id_queue)))
3129 free(id);
3130 id = queue_remove(id_queue);
3131 free(id);
3132 return 0;
3133 }
3134
3135 role_set_init(&roles);
3136 ebitmap_init(&e_roles);
3137 type_set_init(&types);
3138 ebitmap_init(&e_types);
3139 ebitmap_init(&e_classes);
3140
3141 while ((id = queue_remove(id_queue))) {
3142 if (set_roles(&roles, id))
3143 return -1;
3144 }
3145 add = 1;
3146 while ((id = queue_remove(id_queue))) {
3147 if (set_types(&types, id, &add, 0))
3148 return -1;
3149 }
3150
3151 if (class_specified) {
3152 if (read_classes(&e_classes))
3153 return -1;
3154 } else {
3155 cladatum = hashtab_search(policydbp->p_classes.table,
3156 "process");
3157 if (!cladatum) {
3158 yyerror2("could not find process class for "
3159 "legacy role_transition statement");
3160 return -1;
3161 }
3162
3163 if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
3164 yyerror("out of memory");
3165 return -1;
3166 }
3167 }
3168
3169 id = (char *)queue_remove(id_queue);
3170 if (!id) {
3171 yyerror("no new role in transition definition?");
3172 goto bad;
3173 }
3174 if (!is_id_in_scope(SYM_ROLES, id)) {
3175 yyerror2("role %s is not within scope", id);
3176 free(id);
3177 goto bad;
3178 }
3179 role = hashtab_search(policydbp->p_roles.table, id);
3180 if (!role) {
3181 yyerror2("unknown role %s used in transition definition", id);
3182 free(id);
3183 goto bad;
3184 }
3185
3186 if (role->flavor != ROLE_ROLE) {
3187 yyerror2("the new role %s must be a regular role", id);
3188 free(id);
3189 goto bad;
3190 }
3191 free(id);
3192
3193 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
3194 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
3195 goto bad;
3196
3197 if (type_set_expand(&types, &e_types, policydbp, 1))
3198 goto bad;
3199
3200 ebitmap_for_each_positive_bit(&e_roles, rnode, i) {
3201 ebitmap_for_each_positive_bit(&e_types, tnode, j) {
3202 ebitmap_for_each_positive_bit(&e_classes, cnode, k) {
3203 for (tr = policydbp->role_tr; tr;
3204 tr = tr->next) {
3205 if (tr->role == (i + 1) &&
3206 tr->type == (j + 1) &&
3207 tr->tclass == (k + 1)) {
3208 yyerror2("duplicate role "
3209 "transition for "
3210 "(%s,%s,%s)",
3211 role_val_to_name(i+1),
3212 policydbp->p_type_val_to_name[j],
3213 policydbp->p_class_val_to_name[k]);
3214 goto bad;
3215 }
3216 }
3217
3218 tr = malloc(sizeof(struct role_trans));
3219 if (!tr) {
3220 yyerror("out of memory");
3221 return -1;
3222 }
3223 memset(tr, 0, sizeof(struct role_trans));
3224 tr->role = i + 1;
3225 tr->type = j + 1;
3226 tr->tclass = k + 1;
3227 tr->new_role = role->s.value;
3228 tr->next = policydbp->role_tr;
3229 policydbp->role_tr = tr;
3230 }
3231 }
3232 }
3233 /* Now add the real rule */
3234 rule = malloc(sizeof(struct role_trans_rule));
3235 if (!rule) {
3236 yyerror("out of memory");
3237 return -1;
3238 }
3239 memset(rule, 0, sizeof(struct role_trans_rule));
3240 rule->roles = roles;
3241 rule->types = types;
3242 rule->classes = e_classes;
3243 rule->new_role = role->s.value;
3244
3245 append_role_trans(rule);
3246
3247 ebitmap_destroy(&e_roles);
3248 ebitmap_destroy(&e_types);
3249
3250 return 0;
3251
3252 bad:
3253 return -1;
3254 }
3255
define_role_allow(void)3256 int define_role_allow(void)
3257 {
3258 char *id;
3259 struct role_allow_rule *ra = 0;
3260
3261 if (pass == 1) {
3262 while ((id = queue_remove(id_queue)))
3263 free(id);
3264 while ((id = queue_remove(id_queue)))
3265 free(id);
3266 return 0;
3267 }
3268
3269 ra = malloc(sizeof(role_allow_rule_t));
3270 if (!ra) {
3271 yyerror("out of memory");
3272 return -1;
3273 }
3274 role_allow_rule_init(ra);
3275
3276 while ((id = queue_remove(id_queue))) {
3277 if (set_roles(&ra->roles, id)) {
3278 free(ra);
3279 return -1;
3280 }
3281 }
3282
3283 while ((id = queue_remove(id_queue))) {
3284 if (set_roles(&ra->new_roles, id)) {
3285 free(ra);
3286 return -1;
3287 }
3288 }
3289
3290 append_role_allow(ra);
3291 return 0;
3292 }
3293
define_cond_filename_trans(void)3294 avrule_t *define_cond_filename_trans(void)
3295 {
3296 yyerror("type transitions with a filename not allowed inside "
3297 "conditionals\n");
3298 return COND_ERR;
3299 }
3300
define_filename_trans(void)3301 int define_filename_trans(void)
3302 {
3303 char *id, *name = NULL;
3304 type_set_t stypes, ttypes;
3305 ebitmap_t e_stypes, e_ttypes;
3306 ebitmap_t e_tclasses;
3307 ebitmap_node_t *snode, *tnode, *cnode;
3308 filename_trans_rule_t *ftr;
3309 type_datum_t *typdatum;
3310 uint32_t otype;
3311 unsigned int c, s, t;
3312 int add, self, rc;
3313
3314 if (pass == 1) {
3315 /* stype */
3316 while ((id = queue_remove(id_queue)))
3317 free(id);
3318 /* ttype */
3319 while ((id = queue_remove(id_queue)))
3320 free(id);
3321 /* tclass */
3322 while ((id = queue_remove(id_queue)))
3323 free(id);
3324 /* otype */
3325 id = queue_remove(id_queue);
3326 free(id);
3327 /* name */
3328 id = queue_remove(id_queue);
3329 free(id);
3330 return 0;
3331 }
3332
3333 type_set_init(&stypes);
3334 type_set_init(&ttypes);
3335 ebitmap_init(&e_stypes);
3336 ebitmap_init(&e_ttypes);
3337 ebitmap_init(&e_tclasses);
3338
3339 add = 1;
3340 while ((id = queue_remove(id_queue))) {
3341 if (set_types(&stypes, id, &add, 0))
3342 goto bad;
3343 }
3344
3345 self = 0;
3346 add = 1;
3347 while ((id = queue_remove(id_queue))) {
3348 if (strcmp(id, "self") == 0) {
3349 free(id);
3350 if (add == 0) {
3351 yyerror("-self is not supported");
3352 goto bad;
3353 }
3354 self = 1;
3355 continue;
3356 }
3357 if (set_types(&ttypes, id, &add, 0))
3358 goto bad;
3359 }
3360
3361 if (read_classes(&e_tclasses))
3362 goto bad;
3363
3364 id = (char *)queue_remove(id_queue);
3365 if (!id) {
3366 yyerror("no otype in transition definition?");
3367 goto bad;
3368 }
3369 if (!is_id_in_scope(SYM_TYPES, id)) {
3370 yyerror2("type %s is not within scope", id);
3371 free(id);
3372 goto bad;
3373 }
3374 typdatum = hashtab_search(policydbp->p_types.table, id);
3375 if (!typdatum) {
3376 yyerror2("unknown type %s used in transition definition", id);
3377 free(id);
3378 goto bad;
3379 }
3380 free(id);
3381 otype = typdatum->s.value;
3382
3383 name = queue_remove(id_queue);
3384 if (!name) {
3385 yyerror("no pathname specified in filename_trans definition?");
3386 goto bad;
3387 }
3388
3389 /* We expand the class set into separate rules. We expand the types
3390 * just to make sure there are not duplicates. They will get turned
3391 * into separate rules later */
3392 if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
3393 goto bad;
3394
3395 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
3396 goto bad;
3397
3398 ebitmap_for_each_positive_bit(&e_tclasses, cnode, c) {
3399 ebitmap_for_each_positive_bit(&e_stypes, snode, s) {
3400 ebitmap_for_each_positive_bit(&e_ttypes, tnode, t) {
3401 rc = policydb_filetrans_insert(
3402 policydbp, s+1, t+1, c+1, name,
3403 NULL, otype, NULL
3404 );
3405 if (rc != SEPOL_OK) {
3406 if (rc == SEPOL_EEXIST) {
3407 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
3408 name,
3409 policydbp->p_type_val_to_name[s],
3410 policydbp->p_type_val_to_name[t],
3411 policydbp->p_class_val_to_name[c]);
3412 goto bad;
3413 }
3414 yyerror("out of memory");
3415 goto bad;
3416 }
3417 }
3418 if (self) {
3419 rc = policydb_filetrans_insert(
3420 policydbp, s+1, s+1, c+1, name,
3421 NULL, otype, NULL
3422 );
3423 if (rc != SEPOL_OK) {
3424 if (rc == SEPOL_EEXIST) {
3425 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
3426 name,
3427 policydbp->p_type_val_to_name[s],
3428 policydbp->p_type_val_to_name[s],
3429 policydbp->p_class_val_to_name[c]);
3430 goto bad;
3431 }
3432 yyerror("out of memory");
3433 goto bad;
3434 }
3435 }
3436 }
3437
3438 /* Now add the real rule since we didn't find any duplicates */
3439 ftr = malloc(sizeof(*ftr));
3440 if (!ftr) {
3441 yyerror("out of memory");
3442 goto bad;
3443 }
3444 filename_trans_rule_init(ftr);
3445 append_filename_trans(ftr);
3446
3447 ftr->name = strdup(name);
3448 if (type_set_cpy(&ftr->stypes, &stypes)) {
3449 yyerror("out of memory");
3450 goto bad;
3451 }
3452 if (type_set_cpy(&ftr->ttypes, &ttypes)) {
3453 yyerror("out of memory");
3454 goto bad;
3455 }
3456 ftr->tclass = c + 1;
3457 ftr->otype = otype;
3458 ftr->flags = self ? RULE_SELF : 0;
3459 }
3460
3461 free(name);
3462 ebitmap_destroy(&e_stypes);
3463 ebitmap_destroy(&e_ttypes);
3464 ebitmap_destroy(&e_tclasses);
3465 type_set_destroy(&stypes);
3466 type_set_destroy(&ttypes);
3467
3468 return 0;
3469
3470 bad:
3471 free(name);
3472 ebitmap_destroy(&e_stypes);
3473 ebitmap_destroy(&e_ttypes);
3474 ebitmap_destroy(&e_tclasses);
3475 type_set_destroy(&stypes);
3476 type_set_destroy(&ttypes);
3477 return -1;
3478 }
3479
constraint_expr_clone(const constraint_expr_t * expr)3480 static constraint_expr_t *constraint_expr_clone(const constraint_expr_t * expr)
3481 {
3482 constraint_expr_t *h = NULL, *l = NULL, *newe;
3483 const constraint_expr_t *e;
3484 for (e = expr; e; e = e->next) {
3485 newe = malloc(sizeof(*newe));
3486 if (!newe)
3487 goto oom;
3488 if (constraint_expr_init(newe) == -1) {
3489 free(newe);
3490 goto oom;
3491 }
3492 if (l)
3493 l->next = newe;
3494 else
3495 h = newe;
3496 l = newe;
3497 newe->expr_type = e->expr_type;
3498 newe->attr = e->attr;
3499 newe->op = e->op;
3500 if (newe->expr_type == CEXPR_NAMES) {
3501 if (newe->attr & CEXPR_TYPE) {
3502 if (type_set_cpy
3503 (newe->type_names, e->type_names))
3504 goto oom;
3505 } else {
3506 if (ebitmap_cpy(&newe->names, &e->names))
3507 goto oom;
3508 }
3509 }
3510 }
3511
3512 return h;
3513 oom:
3514 constraint_expr_destroy(h);
3515 return NULL;
3516 }
3517
3518 #define PERMISSION_MASK(nprim) ((nprim) == PERM_SYMTAB_SIZE ? (~UINT32_C(0)) : ((UINT32_C(1) << (nprim)) - 1))
3519
define_constraint(constraint_expr_t * expr)3520 int define_constraint(constraint_expr_t * expr)
3521 {
3522 struct constraint_node *node;
3523 char *id;
3524 class_datum_t *cladatum;
3525 perm_datum_t *perdatum;
3526 ebitmap_t classmap;
3527 ebitmap_node_t *enode;
3528 constraint_expr_t *e;
3529 unsigned int i;
3530 int depth;
3531 unsigned char useexpr = 1;
3532
3533 if (pass == 1) {
3534 while ((id = queue_remove(id_queue)))
3535 free(id);
3536 while ((id = queue_remove(id_queue)))
3537 free(id);
3538 return 0;
3539 }
3540
3541 depth = -1;
3542 for (e = expr; e; e = e->next) {
3543 switch (e->expr_type) {
3544 case CEXPR_NOT:
3545 if (depth < 0) {
3546 yyerror("illegal constraint expression");
3547 return -1;
3548 }
3549 break;
3550 case CEXPR_AND:
3551 case CEXPR_OR:
3552 if (depth < 1) {
3553 yyerror("illegal constraint expression");
3554 return -1;
3555 }
3556 depth--;
3557 break;
3558 case CEXPR_ATTR:
3559 case CEXPR_NAMES:
3560 if (e->attr & CEXPR_XTARGET) {
3561 yyerror("illegal constraint expression");
3562 return -1; /* only for validatetrans rules */
3563 }
3564 if (depth == (CEXPR_MAXDEPTH - 1)) {
3565 yyerror("constraint expression is too deep");
3566 return -1;
3567 }
3568 depth++;
3569 break;
3570 default:
3571 yyerror("illegal constraint expression");
3572 return -1;
3573 }
3574 }
3575 if (depth != 0) {
3576 yyerror("illegal constraint expression");
3577 return -1;
3578 }
3579
3580 ebitmap_init(&classmap);
3581 while ((id = queue_remove(id_queue))) {
3582 if (!is_id_in_scope(SYM_CLASSES, id)) {
3583 yyerror2("class %s is not within scope", id);
3584 free(id);
3585 return -1;
3586 }
3587 cladatum =
3588 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3589 (hashtab_key_t) id);
3590 if (!cladatum) {
3591 yyerror2("class %s is not defined", id);
3592 ebitmap_destroy(&classmap);
3593 free(id);
3594 return -1;
3595 }
3596 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
3597 yyerror("out of memory");
3598 ebitmap_destroy(&classmap);
3599 free(id);
3600 return -1;
3601 }
3602 node = malloc(sizeof(struct constraint_node));
3603 if (!node) {
3604 yyerror("out of memory");
3605 free(node);
3606 return -1;
3607 }
3608 memset(node, 0, sizeof(constraint_node_t));
3609 if (useexpr) {
3610 node->expr = expr;
3611 useexpr = 0;
3612 } else {
3613 node->expr = constraint_expr_clone(expr);
3614 }
3615 if (!node->expr) {
3616 yyerror("out of memory");
3617 free(node);
3618 return -1;
3619 }
3620 node->permissions = 0;
3621
3622 node->next = cladatum->constraints;
3623 cladatum->constraints = node;
3624
3625 free(id);
3626 }
3627
3628 while ((id = queue_remove(id_queue))) {
3629 ebitmap_for_each_positive_bit(&classmap, enode, i) {
3630 cladatum = policydbp->class_val_to_struct[i];
3631 node = cladatum->constraints;
3632
3633 if (strcmp(id, "*") == 0) {
3634 node->permissions = PERMISSION_MASK(cladatum->permissions.nprim);
3635 continue;
3636 }
3637
3638 if (strcmp(id, "~") == 0) {
3639 node->permissions = ~node->permissions & PERMISSION_MASK(cladatum->permissions.nprim);
3640 if (node->permissions == 0) {
3641 yywarn("omitting constraint with no permission set");
3642 cladatum->constraints = node->next;
3643 constraint_expr_destroy(node->expr);
3644 free(node);
3645 }
3646 continue;
3647 }
3648
3649 perdatum =
3650 (perm_datum_t *) hashtab_search(cladatum->
3651 permissions.
3652 table,
3653 (hashtab_key_t)
3654 id);
3655 if (!perdatum) {
3656 if (cladatum->comdatum) {
3657 perdatum =
3658 (perm_datum_t *)
3659 hashtab_search(cladatum->
3660 comdatum->
3661 permissions.
3662 table,
3663 (hashtab_key_t)
3664 id);
3665 }
3666 if (!perdatum) {
3667 yyerror2("permission %s is not"
3668 " defined for class %s", id, policydbp->p_class_val_to_name[i]);
3669 free(id);
3670 ebitmap_destroy(&classmap);
3671 return -1;
3672 }
3673 }
3674 node->permissions |= (UINT32_C(1) << (perdatum->s.value - 1));
3675 }
3676 free(id);
3677 }
3678
3679 ebitmap_destroy(&classmap);
3680
3681 return 0;
3682 }
3683
define_validatetrans(constraint_expr_t * expr)3684 int define_validatetrans(constraint_expr_t * expr)
3685 {
3686 struct constraint_node *node;
3687 char *id;
3688 class_datum_t *cladatum;
3689 ebitmap_t classmap;
3690 constraint_expr_t *e;
3691 int depth;
3692 unsigned char useexpr = 1;
3693
3694 if (pass == 1) {
3695 while ((id = queue_remove(id_queue)))
3696 free(id);
3697 return 0;
3698 }
3699
3700 depth = -1;
3701 for (e = expr; e; e = e->next) {
3702 switch (e->expr_type) {
3703 case CEXPR_NOT:
3704 if (depth < 0) {
3705 yyerror("illegal validatetrans expression");
3706 return -1;
3707 }
3708 break;
3709 case CEXPR_AND:
3710 case CEXPR_OR:
3711 if (depth < 1) {
3712 yyerror("illegal validatetrans expression");
3713 return -1;
3714 }
3715 depth--;
3716 break;
3717 case CEXPR_ATTR:
3718 case CEXPR_NAMES:
3719 if (depth == (CEXPR_MAXDEPTH - 1)) {
3720 yyerror("validatetrans expression is too deep");
3721 return -1;
3722 }
3723 depth++;
3724 break;
3725 default:
3726 yyerror("illegal validatetrans expression");
3727 return -1;
3728 }
3729 }
3730 if (depth != 0) {
3731 yyerror("illegal validatetrans expression");
3732 return -1;
3733 }
3734
3735 ebitmap_init(&classmap);
3736 while ((id = queue_remove(id_queue))) {
3737 if (!is_id_in_scope(SYM_CLASSES, id)) {
3738 yyerror2("class %s is not within scope", id);
3739 free(id);
3740 return -1;
3741 }
3742 cladatum =
3743 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
3744 (hashtab_key_t) id);
3745 if (!cladatum) {
3746 yyerror2("class %s is not defined", id);
3747 ebitmap_destroy(&classmap);
3748 free(id);
3749 return -1;
3750 }
3751 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
3752 yyerror("out of memory");
3753 ebitmap_destroy(&classmap);
3754 free(id);
3755 return -1;
3756 }
3757
3758 node = malloc(sizeof(struct constraint_node));
3759 if (!node) {
3760 yyerror("out of memory");
3761 return -1;
3762 }
3763 memset(node, 0, sizeof(constraint_node_t));
3764 if (useexpr) {
3765 node->expr = expr;
3766 useexpr = 0;
3767 } else {
3768 node->expr = constraint_expr_clone(expr);
3769 }
3770 node->permissions = 0;
3771
3772 node->next = cladatum->validatetrans;
3773 cladatum->validatetrans = node;
3774
3775 free(id);
3776 }
3777
3778 ebitmap_destroy(&classmap);
3779
3780 return 0;
3781 }
3782
define_cexpr(uint32_t expr_type,uintptr_t arg1,uintptr_t arg2)3783 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
3784 {
3785 struct constraint_expr *expr, *e1 = NULL, *e2;
3786 user_datum_t *user;
3787 role_datum_t *role;
3788 ebitmap_t negset;
3789 char *id;
3790 uint32_t val;
3791 int add = 1;
3792
3793 if (pass == 1) {
3794 if (expr_type == CEXPR_NAMES) {
3795 while ((id = queue_remove(id_queue)))
3796 free(id);
3797 }
3798 return 1; /* any non-NULL value */
3799 }
3800
3801 if ((expr = malloc(sizeof(*expr))) == NULL ||
3802 constraint_expr_init(expr) == -1) {
3803 yyerror("out of memory");
3804 free(expr);
3805 return 0;
3806 }
3807 expr->expr_type = expr_type;
3808
3809 switch (expr_type) {
3810 case CEXPR_NOT:
3811 e1 = NULL;
3812 e2 = (struct constraint_expr *)arg1;
3813 while (e2) {
3814 e1 = e2;
3815 e2 = e2->next;
3816 }
3817 if (!e1 || e1->next) {
3818 yyerror("illegal constraint expression");
3819 constraint_expr_destroy(expr);
3820 return 0;
3821 }
3822 e1->next = expr;
3823 return arg1;
3824 case CEXPR_AND:
3825 case CEXPR_OR:
3826 e1 = NULL;
3827 e2 = (struct constraint_expr *)arg1;
3828 while (e2) {
3829 e1 = e2;
3830 e2 = e2->next;
3831 }
3832 if (!e1 || e1->next) {
3833 yyerror("illegal constraint expression");
3834 constraint_expr_destroy(expr);
3835 return 0;
3836 }
3837 e1->next = (struct constraint_expr *)arg2;
3838
3839 e1 = NULL;
3840 e2 = (struct constraint_expr *)arg2;
3841 while (e2) {
3842 e1 = e2;
3843 e2 = e2->next;
3844 }
3845 if (!e1 || e1->next) {
3846 yyerror("illegal constraint expression");
3847 constraint_expr_destroy(expr);
3848 return 0;
3849 }
3850 e1->next = expr;
3851 return arg1;
3852 case CEXPR_ATTR:
3853 expr->attr = arg1;
3854 expr->op = arg2;
3855 return (uintptr_t) expr;
3856 case CEXPR_NAMES:
3857 add = 1;
3858 expr->attr = arg1;
3859 expr->op = arg2;
3860 ebitmap_init(&negset);
3861 while ((id = (char *)queue_remove(id_queue))) {
3862 if (expr->attr & CEXPR_USER) {
3863 if (!is_id_in_scope(SYM_USERS, id)) {
3864 yyerror2("user %s is not within scope",
3865 id);
3866 constraint_expr_destroy(expr);
3867 return 0;
3868 }
3869 user =
3870 (user_datum_t *) hashtab_search(policydbp->
3871 p_users.
3872 table,
3873 (hashtab_key_t)
3874 id);
3875 if (!user) {
3876 yyerror2("unknown user %s", id);
3877 constraint_expr_destroy(expr);
3878 return 0;
3879 }
3880 val = user->s.value;
3881 } else if (expr->attr & CEXPR_ROLE) {
3882 if (!is_id_in_scope(SYM_ROLES, id)) {
3883 yyerror2("role %s is not within scope",
3884 id);
3885 constraint_expr_destroy(expr);
3886 return 0;
3887 }
3888 role =
3889 (role_datum_t *) hashtab_search(policydbp->
3890 p_roles.
3891 table,
3892 (hashtab_key_t)
3893 id);
3894 if (!role) {
3895 yyerror2("unknown role %s", id);
3896 constraint_expr_destroy(expr);
3897 return 0;
3898 }
3899 val = role->s.value;
3900 } else if (expr->attr & CEXPR_TYPE) {
3901 if (set_types(expr->type_names, id, &add, 0)) {
3902 constraint_expr_destroy(expr);
3903 return 0;
3904 }
3905 continue;
3906 } else {
3907 yyerror("invalid constraint expression");
3908 constraint_expr_destroy(expr);
3909 return 0;
3910 }
3911 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3912 yyerror("out of memory");
3913 ebitmap_destroy(&expr->names);
3914 constraint_expr_destroy(expr);
3915 return 0;
3916 }
3917 free(id);
3918 }
3919 ebitmap_destroy(&negset);
3920 return (uintptr_t) expr;
3921 default:
3922 break;
3923 }
3924
3925 yyerror("invalid constraint expression");
3926 constraint_expr_destroy(expr);
3927 return 0;
3928 }
3929
define_conditional(cond_expr_t * expr,avrule_t * t,avrule_t * f)3930 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3931 {
3932 cond_expr_t *e;
3933 int depth;
3934 cond_node_t cn, *cn_old;
3935
3936 /* expression cannot be NULL */
3937 if (!expr) {
3938 yyerror("illegal conditional expression");
3939 return -1;
3940 }
3941 if (!t) {
3942 if (!f) {
3943 /* empty is fine, destroy expression and return */
3944 cond_expr_destroy(expr);
3945 return 0;
3946 }
3947 /* Invert */
3948 t = f;
3949 f = 0;
3950 expr = define_cond_expr(COND_NOT, expr, 0);
3951 if (!expr) {
3952 yyerror("unable to invert");
3953 return -1;
3954 }
3955 }
3956
3957 /* verify expression */
3958 depth = -1;
3959 for (e = expr; e; e = e->next) {
3960 switch (e->expr_type) {
3961 case COND_NOT:
3962 if (depth < 0) {
3963 yyerror
3964 ("illegal conditional expression; Bad NOT");
3965 return -1;
3966 }
3967 break;
3968 case COND_AND:
3969 case COND_OR:
3970 case COND_XOR:
3971 case COND_EQ:
3972 case COND_NEQ:
3973 if (depth < 1) {
3974 yyerror
3975 ("illegal conditional expression; Bad binary op");
3976 return -1;
3977 }
3978 depth--;
3979 break;
3980 case COND_BOOL:
3981 if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3982 yyerror
3983 ("conditional expression is like totally too deep");
3984 return -1;
3985 }
3986 depth++;
3987 break;
3988 default:
3989 yyerror("illegal conditional expression");
3990 return -1;
3991 }
3992 }
3993 if (depth != 0) {
3994 yyerror("illegal conditional expression");
3995 return -1;
3996 }
3997
3998 /* use tmp conditional node to partially build new node */
3999 memset(&cn, 0, sizeof(cn));
4000 cn.expr = expr;
4001 cn.avtrue_list = t;
4002 cn.avfalse_list = f;
4003
4004 /* normalize/precompute expression */
4005 if (cond_normalize_expr(policydbp, &cn) < 0) {
4006 yyerror("problem normalizing conditional expression");
4007 return -1;
4008 }
4009
4010 /* get the existing conditional node, or create a new one */
4011 cn_old = get_current_cond_list(&cn);
4012 if (!cn_old) {
4013 return -1;
4014 }
4015
4016 append_cond_list(&cn);
4017
4018 /* note that there is no check here for duplicate rules, nor
4019 * check that rule already exists in base -- that will be
4020 * handled during conditional expansion, in expand.c */
4021
4022 cn.avtrue_list = NULL;
4023 cn.avfalse_list = NULL;
4024 cond_node_destroy(&cn);
4025
4026 return 0;
4027 }
4028
define_cond_expr(uint32_t expr_type,void * arg1,void * arg2)4029 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
4030 {
4031 struct cond_expr *expr, *e1 = NULL, *e2;
4032 cond_bool_datum_t *bool_var;
4033 char *id;
4034
4035 /* expressions are handled in the second pass */
4036 if (pass == 1) {
4037 if (expr_type == COND_BOOL) {
4038 while ((id = queue_remove(id_queue))) {
4039 free(id);
4040 }
4041 }
4042 return (cond_expr_t *) 1; /* any non-NULL value */
4043 }
4044
4045 /* create a new expression struct */
4046 expr = malloc(sizeof(struct cond_expr));
4047 if (!expr) {
4048 yyerror("out of memory");
4049 return NULL;
4050 }
4051 memset(expr, 0, sizeof(cond_expr_t));
4052 expr->expr_type = expr_type;
4053
4054 /* create the type asked for */
4055 switch (expr_type) {
4056 case COND_NOT:
4057 e1 = NULL;
4058 e2 = (struct cond_expr *)arg1;
4059 while (e2) {
4060 e1 = e2;
4061 e2 = e2->next;
4062 }
4063 if (!e1 || e1->next) {
4064 yyerror("illegal conditional NOT expression");
4065 free(expr);
4066 return NULL;
4067 }
4068 e1->next = expr;
4069 return (struct cond_expr *)arg1;
4070 case COND_AND:
4071 case COND_OR:
4072 case COND_XOR:
4073 case COND_EQ:
4074 case COND_NEQ:
4075 e1 = NULL;
4076 e2 = (struct cond_expr *)arg1;
4077 while (e2) {
4078 e1 = e2;
4079 e2 = e2->next;
4080 }
4081 if (!e1 || e1->next) {
4082 yyerror
4083 ("illegal left side of conditional binary op expression");
4084 free(expr);
4085 return NULL;
4086 }
4087 e1->next = (struct cond_expr *)arg2;
4088
4089 e1 = NULL;
4090 e2 = (struct cond_expr *)arg2;
4091 while (e2) {
4092 e1 = e2;
4093 e2 = e2->next;
4094 }
4095 if (!e1 || e1->next) {
4096 yyerror
4097 ("illegal right side of conditional binary op expression");
4098 free(expr);
4099 return NULL;
4100 }
4101 e1->next = expr;
4102 return (struct cond_expr *)arg1;
4103 case COND_BOOL:
4104 id = (char *)queue_remove(id_queue);
4105 if (!id) {
4106 yyerror("bad conditional; expected boolean id");
4107 free(id);
4108 free(expr);
4109 return NULL;
4110 }
4111 if (!is_id_in_scope(SYM_BOOLS, id)) {
4112 yyerror2("boolean %s is not within scope", id);
4113 free(id);
4114 free(expr);
4115 return NULL;
4116 }
4117 bool_var =
4118 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
4119 table,
4120 (hashtab_key_t) id);
4121 if (!bool_var) {
4122 yyerror2("unknown boolean %s in conditional expression",
4123 id);
4124 free(expr);
4125 free(id);
4126 return NULL;
4127 }
4128 expr->bool = bool_var->s.value;
4129 free(id);
4130 return expr;
4131 default:
4132 yyerror("illegal conditional expression");
4133 free(expr);
4134 return NULL;
4135 }
4136 }
4137
set_user_roles(role_set_t * set,char * id)4138 static int set_user_roles(role_set_t * set, char *id)
4139 {
4140 role_datum_t *r;
4141
4142 if (strcmp(id, "*") == 0) {
4143 free(id);
4144 yyerror("* is not allowed in user declarations");
4145 return -1;
4146 }
4147
4148 if (strcmp(id, "~") == 0) {
4149 free(id);
4150 yyerror("~ is not allowed in user declarations");
4151 return -1;
4152 }
4153
4154 if (!is_id_in_scope(SYM_ROLES, id)) {
4155 yyerror2("role %s is not within scope", id);
4156 free(id);
4157 return -1;
4158 }
4159 r = hashtab_search(policydbp->p_roles.table, id);
4160 if (!r) {
4161 yyerror2("unknown role %s", id);
4162 free(id);
4163 return -1;
4164 }
4165
4166 free(id);
4167 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE))
4168 goto oom;
4169 return 0;
4170 oom:
4171 yyerror("out of memory");
4172 return -1;
4173 }
4174
parse_categories(char * id,level_datum_t * levdatum,ebitmap_t * cats)4175 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
4176 {
4177 cat_datum_t *cdatum;
4178 int range_start, range_end, i;
4179
4180 if (id_has_dot(id)) {
4181 char *id_start = id;
4182 char *id_end = strchr(id, '.');
4183
4184 *(id_end++) = '\0';
4185
4186 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4187 (hashtab_key_t)
4188 id_start);
4189 if (!cdatum) {
4190 yyerror2("unknown category %s", id_start);
4191 return -1;
4192 }
4193 range_start = cdatum->s.value - 1;
4194 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4195 (hashtab_key_t) id_end);
4196 if (!cdatum) {
4197 yyerror2("unknown category %s", id_end);
4198 return -1;
4199 }
4200 range_end = cdatum->s.value - 1;
4201
4202 if (range_end < range_start) {
4203 yyerror2("category range is invalid");
4204 return -1;
4205 }
4206 } else {
4207 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4208 (hashtab_key_t) id);
4209 if (!cdatum) {
4210 yyerror2("unknown category %s", id);
4211 return -1;
4212 }
4213 range_start = range_end = cdatum->s.value - 1;
4214 }
4215
4216 for (i = range_start; i <= range_end; i++) {
4217 if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
4218 uint32_t level_value = levdatum->level->sens - 1;
4219 policydb_index_others(NULL, policydbp, 0);
4220 yyerror2("category %s can not be associated "
4221 "with level %s",
4222 policydbp->p_cat_val_to_name[i],
4223 policydbp->p_sens_val_to_name[level_value]);
4224 return -1;
4225 }
4226 if (ebitmap_set_bit(cats, i, TRUE)) {
4227 yyerror("out of memory");
4228 return -1;
4229 }
4230 }
4231
4232 return 0;
4233 }
4234
parse_semantic_categories(char * id,level_datum_t * levdatum,mls_semantic_cat_t ** cats)4235 static int parse_semantic_categories(char *id, level_datum_t * levdatum __attribute__ ((unused)),
4236 mls_semantic_cat_t ** cats)
4237 {
4238 cat_datum_t *cdatum;
4239 mls_semantic_cat_t *newcat;
4240 unsigned int range_start, range_end;
4241
4242 if (id_has_dot(id)) {
4243 char *id_start = id;
4244 char *id_end = strchr(id, '.');
4245
4246 *(id_end++) = '\0';
4247
4248 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4249 (hashtab_key_t)
4250 id_start);
4251 if (!cdatum) {
4252 yyerror2("unknown category %s", id_start);
4253 return -1;
4254 }
4255 range_start = cdatum->s.value;
4256
4257 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4258 (hashtab_key_t) id_end);
4259 if (!cdatum) {
4260 yyerror2("unknown category %s", id_end);
4261 return -1;
4262 }
4263 range_end = cdatum->s.value;
4264 } else {
4265 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
4266 (hashtab_key_t) id);
4267 if (!cdatum) {
4268 yyerror2("unknown category %s", id);
4269 return -1;
4270 }
4271 range_start = range_end = cdatum->s.value;
4272 }
4273
4274 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
4275 if (!newcat) {
4276 yyerror("out of memory");
4277 return -1;
4278 }
4279
4280 mls_semantic_cat_init(newcat);
4281 newcat->next = *cats;
4282 newcat->low = range_start;
4283 newcat->high = range_end;
4284
4285 *cats = newcat;
4286
4287 return 0;
4288 }
4289
define_user(void)4290 int define_user(void)
4291 {
4292 char *id;
4293 user_datum_t *usrdatum;
4294 level_datum_t *levdatum;
4295 int l;
4296
4297 if (pass == 1) {
4298 while ((id = queue_remove(id_queue)))
4299 free(id);
4300 if (mlspol) {
4301 while ((id = queue_remove(id_queue)))
4302 free(id);
4303 id = queue_remove(id_queue);
4304 free(id);
4305 for (l = 0; l < 2; l++) {
4306 while ((id = queue_remove(id_queue))) {
4307 free(id);
4308 }
4309 id = queue_remove(id_queue);
4310 if (!id)
4311 break;
4312 free(id);
4313 }
4314 }
4315 return 0;
4316 }
4317
4318 if ((usrdatum = declare_user()) == NULL) {
4319 return -1;
4320 }
4321
4322 while ((id = queue_remove(id_queue))) {
4323 if (set_user_roles(&usrdatum->roles, id))
4324 continue;
4325 }
4326
4327 if (mlspol) {
4328 id = queue_remove(id_queue);
4329 if (!id) {
4330 yyerror("no default level specified for user");
4331 return -1;
4332 }
4333
4334 levdatum = (level_datum_t *)
4335 hashtab_search(policydbp->p_levels.table,
4336 (hashtab_key_t) id);
4337 if (!levdatum) {
4338 yyerror2("unknown sensitivity %s used in user"
4339 " level definition", id);
4340 free(id);
4341 return -1;
4342 }
4343 free(id);
4344
4345 usrdatum->dfltlevel.sens = levdatum->level->sens;
4346
4347 while ((id = queue_remove(id_queue))) {
4348 if (parse_semantic_categories(id, levdatum,
4349 &usrdatum->dfltlevel.cat)) {
4350 free(id);
4351 return -1;
4352 }
4353 free(id);
4354 }
4355
4356 id = queue_remove(id_queue);
4357
4358 for (l = 0; l < 2; l++) {
4359 levdatum = (level_datum_t *)
4360 hashtab_search(policydbp->p_levels.table,
4361 (hashtab_key_t) id);
4362 if (!levdatum) {
4363 yyerror2("unknown sensitivity %s used in user"
4364 " range definition", id);
4365 free(id);
4366 return -1;
4367 }
4368 free(id);
4369
4370 usrdatum->range.level[l].sens = levdatum->level->sens;
4371
4372 while ((id = queue_remove(id_queue))) {
4373 if (parse_semantic_categories(id, levdatum,
4374 &usrdatum->range.level[l].cat)) {
4375 free(id);
4376 return -1;
4377 }
4378 free(id);
4379 }
4380
4381 id = queue_remove(id_queue);
4382 if (!id)
4383 break;
4384 }
4385
4386 if (l == 0) {
4387 if (mls_semantic_level_cpy(&usrdatum->range.level[1],
4388 &usrdatum->range.level[0])) {
4389 yyerror("out of memory");
4390 return -1;
4391 }
4392 }
4393 }
4394 return 0;
4395 }
4396
parse_security_context(context_struct_t * c)4397 static int parse_security_context(context_struct_t * c)
4398 {
4399 char *id;
4400 role_datum_t *role;
4401 type_datum_t *typdatum;
4402 user_datum_t *usrdatum;
4403 level_datum_t *levdatum;
4404 int l;
4405
4406 if (pass == 1) {
4407 id = queue_remove(id_queue);
4408 free(id); /* user */
4409 id = queue_remove(id_queue);
4410 free(id); /* role */
4411 id = queue_remove(id_queue);
4412 free(id); /* type */
4413 if (mlspol) {
4414 id = queue_remove(id_queue);
4415 free(id);
4416 for (l = 0; l < 2; l++) {
4417 while ((id = queue_remove(id_queue))) {
4418 free(id);
4419 }
4420 id = queue_remove(id_queue);
4421 if (!id)
4422 break;
4423 free(id);
4424 }
4425 }
4426 return 0;
4427 }
4428
4429 /* check context c to make sure ok to dereference c later */
4430 if (c == NULL) {
4431 yyerror("null context pointer!");
4432 return -1;
4433 }
4434
4435 context_init(c);
4436
4437 /* extract the user */
4438 id = queue_remove(id_queue);
4439 if (!id) {
4440 yyerror("no effective user?");
4441 goto bad;
4442 }
4443 if (!is_id_in_scope(SYM_USERS, id)) {
4444 yyerror2("user %s is not within scope", id);
4445 free(id);
4446 goto bad;
4447 }
4448 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
4449 (hashtab_key_t) id);
4450 if (!usrdatum) {
4451 yyerror2("user %s is not defined", id);
4452 free(id);
4453 goto bad;
4454 }
4455 c->user = usrdatum->s.value;
4456
4457 /* no need to keep the user name */
4458 free(id);
4459
4460 /* extract the role */
4461 id = (char *)queue_remove(id_queue);
4462 if (!id) {
4463 yyerror("no role name for sid context definition?");
4464 return -1;
4465 }
4466 if (!is_id_in_scope(SYM_ROLES, id)) {
4467 yyerror2("role %s is not within scope", id);
4468 free(id);
4469 return -1;
4470 }
4471 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
4472 (hashtab_key_t) id);
4473 if (!role) {
4474 yyerror2("role %s is not defined", id);
4475 free(id);
4476 return -1;
4477 }
4478 c->role = role->s.value;
4479
4480 /* no need to keep the role name */
4481 free(id);
4482
4483 /* extract the type */
4484 id = (char *)queue_remove(id_queue);
4485 if (!id) {
4486 yyerror("no type name for sid context definition?");
4487 return -1;
4488 }
4489 if (!is_id_in_scope(SYM_TYPES, id)) {
4490 yyerror2("type %s is not within scope", id);
4491 free(id);
4492 return -1;
4493 }
4494 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
4495 (hashtab_key_t) id);
4496 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
4497 yyerror2("type %s is not defined or is an attribute", id);
4498 free(id);
4499 return -1;
4500 }
4501 c->type = typdatum->s.value;
4502
4503 /* no need to keep the type name */
4504 free(id);
4505
4506 if (mlspol) {
4507 /* extract the low sensitivity */
4508 id = (char *)queue_head(id_queue);
4509 if (!id) {
4510 yyerror("no sensitivity name for sid context"
4511 " definition?");
4512 return -1;
4513 }
4514
4515 id = (char *)queue_remove(id_queue);
4516 for (l = 0; l < 2; l++) {
4517 levdatum = (level_datum_t *)
4518 hashtab_search(policydbp->p_levels.table,
4519 (hashtab_key_t) id);
4520 if (!levdatum) {
4521 yyerror2("Sensitivity %s is not defined", id);
4522 free(id);
4523 return -1;
4524 }
4525 free(id);
4526 c->range.level[l].sens = levdatum->level->sens;
4527
4528 /* extract low category set */
4529 while ((id = queue_remove(id_queue))) {
4530 if (parse_categories(id, levdatum,
4531 &c->range.level[l].cat)) {
4532 free(id);
4533 return -1;
4534 }
4535 free(id);
4536 }
4537
4538 /* extract high sensitivity */
4539 id = (char *)queue_remove(id_queue);
4540 if (!id)
4541 break;
4542 }
4543
4544 if (l == 0) {
4545 c->range.level[1].sens = c->range.level[0].sens;
4546 if (ebitmap_cpy(&c->range.level[1].cat,
4547 &c->range.level[0].cat)) {
4548
4549 yyerror("out of memory");
4550 goto bad;
4551 }
4552 }
4553 }
4554
4555 if (!policydb_context_isvalid(policydbp, c)) {
4556 yyerror("invalid security context");
4557 goto bad;
4558 }
4559 return 0;
4560
4561 bad:
4562 context_destroy(c);
4563
4564 return -1;
4565 }
4566
define_initial_sid_context(void)4567 int define_initial_sid_context(void)
4568 {
4569 char *id;
4570 ocontext_t *c, *head;
4571
4572 if (pass == 1) {
4573 id = (char *)queue_remove(id_queue);
4574 free(id);
4575 parse_security_context(NULL);
4576 return 0;
4577 }
4578
4579 id = (char *)queue_remove(id_queue);
4580 if (!id) {
4581 yyerror("no sid name for SID context definition?");
4582 return -1;
4583 }
4584 head = policydbp->ocontexts[OCON_ISID];
4585 for (c = head; c; c = c->next) {
4586 if (!strcmp(id, c->u.name))
4587 break;
4588 }
4589
4590 if (!c) {
4591 yyerror2("SID %s is not defined", id);
4592 free(id);
4593 return -1;
4594 }
4595 if (c->context[0].user) {
4596 yyerror2("The context for SID %s is multiply defined", id);
4597 free(id);
4598 return -1;
4599 }
4600 /* no need to keep the sid name */
4601 free(id);
4602
4603 if (parse_security_context(&c->context[0]))
4604 return -1;
4605
4606 return 0;
4607 }
4608
define_fs_context(unsigned int major,unsigned int minor)4609 int define_fs_context(unsigned int major, unsigned int minor)
4610 {
4611 ocontext_t *newc, *c, *head;
4612
4613 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4614 yyerror("fscon not supported for target");
4615 return -1;
4616 }
4617
4618 if (pass == 1) {
4619 parse_security_context(NULL);
4620 parse_security_context(NULL);
4621 return 0;
4622 }
4623
4624 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4625 if (!newc) {
4626 yyerror("out of memory");
4627 return -1;
4628 }
4629 memset(newc, 0, sizeof(ocontext_t));
4630
4631 newc->u.name = (char *)malloc(6);
4632 if (!newc->u.name) {
4633 yyerror("out of memory");
4634 free(newc);
4635 return -1;
4636 }
4637 sprintf(newc->u.name, "%02x:%02x", major, minor);
4638
4639 if (parse_security_context(&newc->context[0])) {
4640 free(newc->u.name);
4641 free(newc);
4642 return -1;
4643 }
4644 if (parse_security_context(&newc->context[1])) {
4645 context_destroy(&newc->context[0]);
4646 free(newc->u.name);
4647 free(newc);
4648 return -1;
4649 }
4650 head = policydbp->ocontexts[OCON_FS];
4651
4652 for (c = head; c; c = c->next) {
4653 if (!strcmp(newc->u.name, c->u.name)) {
4654 yyerror2("duplicate entry for file system %s",
4655 newc->u.name);
4656 context_destroy(&newc->context[0]);
4657 context_destroy(&newc->context[1]);
4658 free(newc->u.name);
4659 free(newc);
4660 return -1;
4661 }
4662 }
4663
4664 newc->next = head;
4665 policydbp->ocontexts[OCON_FS] = newc;
4666
4667 return 0;
4668 }
4669
define_pirq_context(unsigned int pirq)4670 int define_pirq_context(unsigned int pirq)
4671 {
4672 ocontext_t *newc, *c, *l, *head;
4673 char *id;
4674
4675 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4676 yyerror("pirqcon not supported for target");
4677 return -1;
4678 }
4679
4680 if (pass == 1) {
4681 id = (char *) queue_remove(id_queue);
4682 free(id);
4683 parse_security_context(NULL);
4684 return 0;
4685 }
4686
4687 newc = malloc(sizeof(ocontext_t));
4688 if (!newc) {
4689 yyerror("out of memory");
4690 return -1;
4691 }
4692 memset(newc, 0, sizeof(ocontext_t));
4693
4694 newc->u.pirq = pirq;
4695
4696 if (parse_security_context(&newc->context[0])) {
4697 free(newc);
4698 return -1;
4699 }
4700
4701 head = policydbp->ocontexts[OCON_XEN_PIRQ];
4702 for (l = NULL, c = head; c; l = c, c = c->next) {
4703 unsigned int pirq2;
4704
4705 pirq2 = c->u.pirq;
4706 if (pirq == pirq2) {
4707 yyerror2("duplicate pirqcon entry for %d ", pirq);
4708 goto bad;
4709 }
4710 }
4711
4712 if (l)
4713 l->next = newc;
4714 else
4715 policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
4716
4717 return 0;
4718
4719 bad:
4720 free(newc);
4721 return -1;
4722 }
4723
define_iomem_context(uint64_t low,uint64_t high)4724 int define_iomem_context(uint64_t low, uint64_t high)
4725 {
4726 ocontext_t *newc, *c, *l, *head;
4727 char *id;
4728
4729 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4730 yyerror("iomemcon not supported for target");
4731 return -1;
4732 }
4733
4734 if (pass == 1) {
4735 id = (char *)queue_remove(id_queue);
4736 free(id);
4737 parse_security_context(NULL);
4738 return 0;
4739 }
4740
4741 newc = malloc(sizeof(ocontext_t));
4742 if (!newc) {
4743 yyerror("out of memory");
4744 return -1;
4745 }
4746 memset(newc, 0, sizeof(ocontext_t));
4747
4748 newc->u.iomem.low_iomem = low;
4749 newc->u.iomem.high_iomem = high;
4750
4751 if (low > high) {
4752 yyerror2("low memory 0x%"PRIx64" exceeds high memory 0x%"PRIx64"", low, high);
4753 free(newc);
4754 return -1;
4755 }
4756
4757 if (parse_security_context(&newc->context[0])) {
4758 free(newc);
4759 return -1;
4760 }
4761
4762 head = policydbp->ocontexts[OCON_XEN_IOMEM];
4763 for (l = NULL, c = head; c; l = c, c = c->next) {
4764 uint64_t low2, high2;
4765
4766 low2 = c->u.iomem.low_iomem;
4767 high2 = c->u.iomem.high_iomem;
4768 if (low <= high2 && low2 <= high) {
4769 yyerror2("iomemcon entry for 0x%"PRIx64"-0x%"PRIx64" overlaps with "
4770 "earlier entry 0x%"PRIx64"-0x%"PRIx64"", low, high,
4771 low2, high2);
4772 goto bad;
4773 }
4774 }
4775
4776 if (l)
4777 l->next = newc;
4778 else
4779 policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
4780
4781 return 0;
4782
4783 bad:
4784 free(newc);
4785 return -1;
4786 }
4787
define_ioport_context(unsigned long low,unsigned long high)4788 int define_ioport_context(unsigned long low, unsigned long high)
4789 {
4790 ocontext_t *newc, *c, *l, *head;
4791 char *id;
4792
4793 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4794 yyerror("ioportcon not supported for target");
4795 return -1;
4796 }
4797
4798 if (pass == 1) {
4799 id = (char *)queue_remove(id_queue);
4800 free(id);
4801 parse_security_context(NULL);
4802 return 0;
4803 }
4804
4805 newc = malloc(sizeof(ocontext_t));
4806 if (!newc) {
4807 yyerror("out of memory");
4808 return -1;
4809 }
4810 memset(newc, 0, sizeof(ocontext_t));
4811
4812 newc->u.ioport.low_ioport = low;
4813 newc->u.ioport.high_ioport = high;
4814
4815 if (low > high) {
4816 yyerror2("low ioport 0x%lx exceeds high ioport 0x%lx", low, high);
4817 free(newc);
4818 return -1;
4819 }
4820
4821 if (parse_security_context(&newc->context[0])) {
4822 free(newc);
4823 return -1;
4824 }
4825
4826 head = policydbp->ocontexts[OCON_XEN_IOPORT];
4827 for (l = NULL, c = head; c; l = c, c = c->next) {
4828 uint32_t low2, high2;
4829
4830 low2 = c->u.ioport.low_ioport;
4831 high2 = c->u.ioport.high_ioport;
4832 if (low <= high2 && low2 <= high) {
4833 yyerror2("ioportcon entry for 0x%lx-0x%lx overlaps with"
4834 "earlier entry 0x%x-0x%x", low, high,
4835 low2, high2);
4836 goto bad;
4837 }
4838 }
4839
4840 if (l)
4841 l->next = newc;
4842 else
4843 policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
4844
4845 return 0;
4846
4847 bad:
4848 free(newc);
4849 return -1;
4850 }
4851
define_pcidevice_context(unsigned long device)4852 int define_pcidevice_context(unsigned long device)
4853 {
4854 ocontext_t *newc, *c, *l, *head;
4855 char *id;
4856
4857 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4858 yyerror("pcidevicecon not supported for target");
4859 return -1;
4860 }
4861
4862 if (pass == 1) {
4863 id = (char *) queue_remove(id_queue);
4864 free(id);
4865 parse_security_context(NULL);
4866 return 0;
4867 }
4868
4869 newc = malloc(sizeof(ocontext_t));
4870 if (!newc) {
4871 yyerror("out of memory");
4872 return -1;
4873 }
4874 memset(newc, 0, sizeof(ocontext_t));
4875
4876 newc->u.device = device;
4877
4878 if (parse_security_context(&newc->context[0])) {
4879 free(newc);
4880 return -1;
4881 }
4882
4883 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4884 for (l = NULL, c = head; c; l = c, c = c->next) {
4885 unsigned int device2;
4886
4887 device2 = c->u.device;
4888 if (device == device2) {
4889 yyerror2("duplicate pcidevicecon entry for 0x%lx",
4890 device);
4891 goto bad;
4892 }
4893 }
4894
4895 if (l)
4896 l->next = newc;
4897 else
4898 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4899
4900 return 0;
4901
4902 bad:
4903 free(newc);
4904 return -1;
4905 }
4906
define_devicetree_context()4907 int define_devicetree_context()
4908 {
4909 ocontext_t *newc, *c, *l, *head;
4910
4911 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4912 yyerror("devicetreecon not supported for target");
4913 return -1;
4914 }
4915
4916 if (pass == 1) {
4917 free(queue_remove(id_queue));
4918 parse_security_context(NULL);
4919 return 0;
4920 }
4921
4922 newc = malloc(sizeof(ocontext_t));
4923 if (!newc) {
4924 yyerror("out of memory");
4925 return -1;
4926 }
4927 memset(newc, 0, sizeof(ocontext_t));
4928
4929 newc->u.name = (char *)queue_remove(id_queue);
4930 if (!newc->u.name) {
4931 free(newc);
4932 return -1;
4933 }
4934
4935 if (parse_security_context(&newc->context[0])) {
4936 free(newc->u.name);
4937 free(newc);
4938 return -1;
4939 }
4940
4941 head = policydbp->ocontexts[OCON_XEN_DEVICETREE];
4942 for (l = NULL, c = head; c; l = c, c = c->next) {
4943 if (strcmp(newc->u.name, c->u.name) == 0) {
4944 yyerror2("duplicate devicetree entry for '%s'", newc->u.name);
4945 goto bad;
4946 }
4947 }
4948
4949 if (l)
4950 l->next = newc;
4951 else
4952 policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc;
4953
4954 return 0;
4955
4956 bad:
4957 free(newc->u.name);
4958 free(newc);
4959 return -1;
4960 }
4961
define_port_context(unsigned int low,unsigned int high)4962 int define_port_context(unsigned int low, unsigned int high)
4963 {
4964 ocontext_t *newc, *c, *l, *head;
4965 unsigned int protocol;
4966 char *id;
4967
4968 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4969 yyerror("portcon not supported for target");
4970 return -1;
4971 }
4972
4973 if (pass == 1) {
4974 id = (char *)queue_remove(id_queue);
4975 free(id);
4976 parse_security_context(NULL);
4977 return 0;
4978 }
4979
4980 newc = malloc(sizeof(ocontext_t));
4981 if (!newc) {
4982 yyerror("out of memory");
4983 return -1;
4984 }
4985 memset(newc, 0, sizeof(ocontext_t));
4986
4987 id = (char *)queue_remove(id_queue);
4988 if (!id) {
4989 free(newc);
4990 return -1;
4991 }
4992 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4993 protocol = IPPROTO_TCP;
4994 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4995 protocol = IPPROTO_UDP;
4996 } else if ((strcmp(id, "dccp") == 0) || (strcmp(id, "DCCP") == 0)) {
4997 protocol = IPPROTO_DCCP;
4998 } else if ((strcmp(id, "sctp") == 0) || (strcmp(id, "SCTP") == 0)) {
4999 protocol = IPPROTO_SCTP;
5000 } else {
5001 yyerror2("unrecognized protocol %s", id);
5002 goto bad;
5003 }
5004
5005 newc->u.port.protocol = protocol;
5006 newc->u.port.low_port = low;
5007 newc->u.port.high_port = high;
5008
5009 if (low > high) {
5010 yyerror2("low port %d exceeds high port %d", low, high);
5011 goto bad;
5012 }
5013
5014 if (parse_security_context(&newc->context[0])) {
5015 goto bad;
5016 }
5017
5018 /* Preserve the matching order specified in the configuration. */
5019 head = policydbp->ocontexts[OCON_PORT];
5020 for (l = NULL, c = head; c; l = c, c = c->next) {
5021 unsigned int prot2, low2, high2;
5022
5023 prot2 = c->u.port.protocol;
5024 low2 = c->u.port.low_port;
5025 high2 = c->u.port.high_port;
5026 if (protocol != prot2)
5027 continue;
5028 if (low == low2 && high == high2) {
5029 yyerror2("duplicate portcon entry for %s %d-%d ", id,
5030 low, high);
5031 goto bad;
5032 }
5033 if (low2 <= low && high2 >= high) {
5034 yyerror2("portcon entry for %s %d-%d hidden by earlier "
5035 "entry for %d-%d", id, low, high, low2, high2);
5036 goto bad;
5037 }
5038 }
5039
5040 if (l)
5041 l->next = newc;
5042 else
5043 policydbp->ocontexts[OCON_PORT] = newc;
5044
5045 free(id);
5046 return 0;
5047
5048 bad:
5049 free(id);
5050 free(newc);
5051 return -1;
5052 }
5053
define_ibpkey_context(unsigned int low,unsigned int high)5054 int define_ibpkey_context(unsigned int low, unsigned int high)
5055 {
5056 ocontext_t *newc, *c, *l, *head;
5057 struct in6_addr subnet_prefix;
5058 char *id;
5059 int rc = 0;
5060
5061 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5062 yyerror("ibpkeycon not supported for target");
5063 return -1;
5064 }
5065
5066 if (pass == 1) {
5067 id = (char *)queue_remove(id_queue);
5068 free(id);
5069 parse_security_context(NULL);
5070 return 0;
5071 }
5072
5073 newc = malloc(sizeof(*newc));
5074 if (!newc) {
5075 yyerror("out of memory");
5076 return -1;
5077 }
5078 memset(newc, 0, sizeof(*newc));
5079
5080 id = queue_remove(id_queue);
5081 if (!id) {
5082 yyerror("failed to read the subnet prefix");
5083 rc = -1;
5084 goto out;
5085 }
5086
5087 rc = inet_pton(AF_INET6, id, &subnet_prefix);
5088 free(id);
5089 if (rc < 1) {
5090 yyerror("failed to parse the subnet prefix");
5091 if (rc == 0)
5092 rc = -1;
5093 goto out;
5094 }
5095
5096 if (subnet_prefix.s6_addr[2] || subnet_prefix.s6_addr[3]) {
5097 yyerror("subnet prefix should be 0's in the low order 64 bits.");
5098 rc = -1;
5099 goto out;
5100 }
5101
5102 if (low > 0xffff || high > 0xffff) {
5103 yyerror("pkey value too large, pkeys are 16 bits.");
5104 rc = -1;
5105 goto out;
5106 }
5107
5108 memcpy(&newc->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0],
5109 sizeof(newc->u.ibpkey.subnet_prefix));
5110
5111 newc->u.ibpkey.low_pkey = low;
5112 newc->u.ibpkey.high_pkey = high;
5113
5114 if (low > high) {
5115 yyerror2("low pkey %d exceeds high pkey %d", low, high);
5116 rc = -1;
5117 goto out;
5118 }
5119
5120 rc = parse_security_context(&newc->context[0]);
5121 if (rc)
5122 goto out;
5123
5124 /* Preserve the matching order specified in the configuration. */
5125 head = policydbp->ocontexts[OCON_IBPKEY];
5126 for (l = NULL, c = head; c; l = c, c = c->next) {
5127 unsigned int low2, high2;
5128
5129 low2 = c->u.ibpkey.low_pkey;
5130 high2 = c->u.ibpkey.high_pkey;
5131
5132 if (low == low2 && high == high2 &&
5133 c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5134 yyerror2("duplicate ibpkeycon entry for %d-%d ",
5135 low, high);
5136 rc = -1;
5137 goto out;
5138 }
5139 if (low2 <= low && high2 >= high &&
5140 c->u.ibpkey.subnet_prefix == newc->u.ibpkey.subnet_prefix) {
5141 yyerror2("ibpkeycon entry for %d-%d hidden by earlier entry for %d-%d",
5142 low, high, low2, high2);
5143 rc = -1;
5144 goto out;
5145 }
5146 }
5147
5148 if (l)
5149 l->next = newc;
5150 else
5151 policydbp->ocontexts[OCON_IBPKEY] = newc;
5152
5153 return 0;
5154
5155 out:
5156 free(newc);
5157 return rc;
5158 }
5159
define_ibendport_context(unsigned int port)5160 int define_ibendport_context(unsigned int port)
5161 {
5162 ocontext_t *newc, *c, *l, *head;
5163 char *id;
5164 int rc = 0;
5165
5166 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5167 yyerror("ibendportcon not supported for target");
5168 return -1;
5169 }
5170
5171 if (pass == 1) {
5172 id = (char *)queue_remove(id_queue);
5173 free(id);
5174 parse_security_context(NULL);
5175 return 0;
5176 }
5177
5178 if (port > 0xff || port == 0) {
5179 yyerror("Invalid ibendport port number, should be 0 < port < 256");
5180 return -1;
5181 }
5182
5183 newc = malloc(sizeof(*newc));
5184 if (!newc) {
5185 yyerror("out of memory");
5186 return -1;
5187 }
5188 memset(newc, 0, sizeof(*newc));
5189
5190 newc->u.ibendport.dev_name = queue_remove(id_queue);
5191 if (!newc->u.ibendport.dev_name) {
5192 yyerror("failed to read infiniband device name.");
5193 rc = -1;
5194 goto out;
5195 }
5196
5197 if (strlen(newc->u.ibendport.dev_name) > IB_DEVICE_NAME_MAX - 1) {
5198 yyerror("infiniband device name exceeds max length of 63.");
5199 rc = -1;
5200 goto out;
5201 }
5202
5203 newc->u.ibendport.port = port;
5204
5205 if (parse_security_context(&newc->context[0])) {
5206 free(newc);
5207 return -1;
5208 }
5209
5210 /* Preserve the matching order specified in the configuration. */
5211 head = policydbp->ocontexts[OCON_IBENDPORT];
5212 for (l = NULL, c = head; c; l = c, c = c->next) {
5213 unsigned int port2;
5214
5215 port2 = c->u.ibendport.port;
5216
5217 if (port == port2 &&
5218 !strcmp(c->u.ibendport.dev_name,
5219 newc->u.ibendport.dev_name)) {
5220 yyerror2("duplicate ibendportcon entry for %s port %u",
5221 newc->u.ibendport.dev_name, port);
5222 rc = -1;
5223 goto out;
5224 }
5225 }
5226
5227 if (l)
5228 l->next = newc;
5229 else
5230 policydbp->ocontexts[OCON_IBENDPORT] = newc;
5231
5232 return 0;
5233
5234 out:
5235 free(newc->u.ibendport.dev_name);
5236 free(newc);
5237 return rc;
5238 }
5239
define_netif_context(void)5240 int define_netif_context(void)
5241 {
5242 ocontext_t *newc, *c, *head;
5243
5244 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5245 yyerror("netifcon not supported for target");
5246 return -1;
5247 }
5248
5249 if (pass == 1) {
5250 free(queue_remove(id_queue));
5251 parse_security_context(NULL);
5252 parse_security_context(NULL);
5253 return 0;
5254 }
5255
5256 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5257 if (!newc) {
5258 yyerror("out of memory");
5259 return -1;
5260 }
5261 memset(newc, 0, sizeof(ocontext_t));
5262
5263 newc->u.name = (char *)queue_remove(id_queue);
5264 if (!newc->u.name) {
5265 free(newc);
5266 return -1;
5267 }
5268 if (parse_security_context(&newc->context[0])) {
5269 free(newc->u.name);
5270 free(newc);
5271 return -1;
5272 }
5273 if (parse_security_context(&newc->context[1])) {
5274 context_destroy(&newc->context[0]);
5275 free(newc->u.name);
5276 free(newc);
5277 return -1;
5278 }
5279 head = policydbp->ocontexts[OCON_NETIF];
5280
5281 for (c = head; c; c = c->next) {
5282 if (!strcmp(newc->u.name, c->u.name)) {
5283 yyerror2("duplicate entry for network interface %s",
5284 newc->u.name);
5285 context_destroy(&newc->context[0]);
5286 context_destroy(&newc->context[1]);
5287 free(newc->u.name);
5288 free(newc);
5289 return -1;
5290 }
5291 }
5292
5293 newc->next = head;
5294 policydbp->ocontexts[OCON_NETIF] = newc;
5295 return 0;
5296 }
5297
define_ipv4_node_context()5298 int define_ipv4_node_context()
5299 {
5300 char *id;
5301 int rc = 0;
5302 struct in_addr addr, mask;
5303 ocontext_t *newc, *c, *l, *head;
5304
5305 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5306 yyerror("nodecon not supported for target");
5307 return -1;
5308 }
5309
5310 if (pass == 1) {
5311 free(queue_remove(id_queue));
5312 free(queue_remove(id_queue));
5313 parse_security_context(NULL);
5314 goto out;
5315 }
5316
5317 id = queue_remove(id_queue);
5318 if (!id) {
5319 yyerror("failed to read ipv4 address");
5320 rc = -1;
5321 goto out;
5322 }
5323
5324 rc = inet_pton(AF_INET, id, &addr);
5325 free(id);
5326 if (rc < 1) {
5327 yyerror("failed to parse ipv4 address");
5328 if (rc == 0)
5329 rc = -1;
5330 goto out;
5331 }
5332
5333 id = queue_remove(id_queue);
5334 if (!id) {
5335 yyerror("failed to read ipv4 address");
5336 rc = -1;
5337 goto out;
5338 }
5339
5340 rc = inet_pton(AF_INET, id, &mask);
5341 free(id);
5342 if (rc < 1) {
5343 yyerror("failed to parse ipv4 mask");
5344 if (rc == 0)
5345 rc = -1;
5346 goto out;
5347 }
5348
5349 if (mask.s_addr != 0 && ((~mask.s_addr + 1) & ~mask.s_addr) != 0) {
5350 yywarn("ipv4 mask is not contiguous");
5351 }
5352
5353 if ((~mask.s_addr & addr.s_addr) != 0) {
5354 yywarn("host bits in ipv4 address set");
5355 }
5356
5357 newc = malloc(sizeof(ocontext_t));
5358 if (!newc) {
5359 yyerror("out of memory");
5360 rc = -1;
5361 goto out;
5362 }
5363
5364 memset(newc, 0, sizeof(ocontext_t));
5365 newc->u.node.addr = addr.s_addr;
5366 newc->u.node.mask = mask.s_addr;
5367
5368 if (parse_security_context(&newc->context[0])) {
5369 free(newc);
5370 return -1;
5371 }
5372
5373 /* Create order of most specific to least retaining
5374 the order specified in the configuration. */
5375 head = policydbp->ocontexts[OCON_NODE];
5376 for (l = NULL, c = head; c; l = c, c = c->next) {
5377 if (newc->u.node.mask > c->u.node.mask)
5378 break;
5379 }
5380
5381 newc->next = c;
5382
5383 if (l)
5384 l->next = newc;
5385 else
5386 policydbp->ocontexts[OCON_NODE] = newc;
5387 rc = 0;
5388 out:
5389 return rc;
5390 }
5391
ipv6_is_mask_contiguous(const struct in6_addr * mask)5392 static int ipv6_is_mask_contiguous(const struct in6_addr *mask)
5393 {
5394 int filled = 1;
5395 unsigned i;
5396
5397 for (i = 0; i < 16; i++) {
5398 if ((((~mask->s6_addr[i] & 0xFF) + 1) & (~mask->s6_addr[i] & 0xFF)) != 0) {
5399 return 0;
5400 }
5401 if (!filled && mask->s6_addr[i] != 0) {
5402 return 0;
5403 }
5404
5405 if (filled && mask->s6_addr[i] != 0xFF) {
5406 filled = 0;
5407 }
5408 }
5409
5410 return 1;
5411 }
5412
ipv6_has_host_bits_set(const struct in6_addr * addr,const struct in6_addr * mask)5413 static int ipv6_has_host_bits_set(const struct in6_addr *addr, const struct in6_addr *mask)
5414 {
5415 unsigned i;
5416
5417 for (i = 0; i < 16; i++) {
5418 if ((addr->s6_addr[i] & ~mask->s6_addr[i]) != 0) {
5419 return 1;
5420 }
5421 }
5422
5423 return 0;
5424 }
5425
define_ipv6_node_context(void)5426 int define_ipv6_node_context(void)
5427 {
5428 char *id;
5429 int rc = 0;
5430 struct in6_addr addr, mask;
5431 ocontext_t *newc, *c, *l, *head;
5432
5433 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5434 yyerror("nodecon not supported for target");
5435 return -1;
5436 }
5437
5438 if (pass == 1) {
5439 free(queue_remove(id_queue));
5440 free(queue_remove(id_queue));
5441 parse_security_context(NULL);
5442 goto out;
5443 }
5444
5445 id = queue_remove(id_queue);
5446 if (!id) {
5447 yyerror("failed to read ipv6 address");
5448 rc = -1;
5449 goto out;
5450 }
5451
5452 rc = inet_pton(AF_INET6, id, &addr);
5453 free(id);
5454 if (rc < 1) {
5455 yyerror("failed to parse ipv6 address");
5456 if (rc == 0)
5457 rc = -1;
5458 goto out;
5459 }
5460
5461 id = queue_remove(id_queue);
5462 if (!id) {
5463 yyerror("failed to read ipv6 address");
5464 rc = -1;
5465 goto out;
5466 }
5467
5468 rc = inet_pton(AF_INET6, id, &mask);
5469 free(id);
5470 if (rc < 1) {
5471 yyerror("failed to parse ipv6 mask");
5472 if (rc == 0)
5473 rc = -1;
5474 goto out;
5475 }
5476
5477 if (!ipv6_is_mask_contiguous(&mask)) {
5478 yywarn("ipv6 mask is not contiguous");
5479 }
5480
5481 if (ipv6_has_host_bits_set(&addr, &mask)) {
5482 yywarn("host bits in ipv6 address set");
5483 }
5484
5485 newc = malloc(sizeof(ocontext_t));
5486 if (!newc) {
5487 yyerror("out of memory");
5488 rc = -1;
5489 goto out;
5490 }
5491
5492 memset(newc, 0, sizeof(ocontext_t));
5493 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
5494 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
5495
5496 if (parse_security_context(&newc->context[0])) {
5497 free(newc);
5498 rc = -1;
5499 goto out;
5500 }
5501
5502 /* Create order of most specific to least retaining
5503 the order specified in the configuration. */
5504 head = policydbp->ocontexts[OCON_NODE6];
5505 for (l = NULL, c = head; c; l = c, c = c->next) {
5506 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
5507 break;
5508 }
5509
5510 newc->next = c;
5511
5512 if (l)
5513 l->next = newc;
5514 else
5515 policydbp->ocontexts[OCON_NODE6] = newc;
5516
5517 rc = 0;
5518 out:
5519 return rc;
5520 }
5521
define_fs_use(int behavior)5522 int define_fs_use(int behavior)
5523 {
5524 ocontext_t *newc, *c, *head;
5525
5526 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5527 yyerror("fsuse not supported for target");
5528 return -1;
5529 }
5530
5531 if (pass == 1) {
5532 free(queue_remove(id_queue));
5533 parse_security_context(NULL);
5534 return 0;
5535 }
5536
5537 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5538 if (!newc) {
5539 yyerror("out of memory");
5540 return -1;
5541 }
5542 memset(newc, 0, sizeof(ocontext_t));
5543
5544 newc->u.name = (char *)queue_remove(id_queue);
5545 if (!newc->u.name) {
5546 free(newc);
5547 return -1;
5548 }
5549 newc->v.behavior = behavior;
5550 if (parse_security_context(&newc->context[0])) {
5551 free(newc->u.name);
5552 free(newc);
5553 return -1;
5554 }
5555
5556 head = policydbp->ocontexts[OCON_FSUSE];
5557
5558 for (c = head; c; c = c->next) {
5559 if (!strcmp(newc->u.name, c->u.name)) {
5560 yyerror2("duplicate fs_use entry for filesystem type %s",
5561 newc->u.name);
5562 context_destroy(&newc->context[0]);
5563 free(newc->u.name);
5564 free(newc);
5565 return -1;
5566 }
5567 }
5568
5569 newc->next = head;
5570 policydbp->ocontexts[OCON_FSUSE] = newc;
5571 return 0;
5572 }
5573
define_genfs_context_helper(char * fstype,int has_type)5574 static int define_genfs_context_helper(char *fstype, int has_type)
5575 {
5576 struct genfs *genfs_p, *genfs, *newgenfs;
5577 ocontext_t *newc, *c, *head, *p;
5578 class_datum_t *cladatum;
5579 char *type = NULL;
5580 const char *sclass;
5581 int len, len2;
5582
5583 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
5584 yyerror("genfs not supported for target");
5585 return -1;
5586 }
5587
5588 if (pass == 1) {
5589 free(fstype);
5590 free(queue_remove(id_queue));
5591 if (has_type)
5592 free(queue_remove(id_queue));
5593 parse_security_context(NULL);
5594 return 0;
5595 }
5596
5597 for (genfs_p = NULL, genfs = policydbp->genfs;
5598 genfs; genfs_p = genfs, genfs = genfs->next) {
5599 if (strcmp(fstype, genfs->fstype) <= 0)
5600 break;
5601 }
5602
5603 if (!genfs || strcmp(fstype, genfs->fstype)) {
5604 newgenfs = malloc(sizeof(struct genfs));
5605 if (!newgenfs) {
5606 yyerror("out of memory");
5607 return -1;
5608 }
5609 memset(newgenfs, 0, sizeof(struct genfs));
5610 newgenfs->fstype = fstype;
5611 newgenfs->next = genfs;
5612 if (genfs_p)
5613 genfs_p->next = newgenfs;
5614 else
5615 policydbp->genfs = newgenfs;
5616 genfs = newgenfs;
5617 } else {
5618 free(fstype);
5619 fstype = NULL;
5620 }
5621
5622 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
5623 if (!newc) {
5624 yyerror("out of memory");
5625 return -1;
5626 }
5627 memset(newc, 0, sizeof(ocontext_t));
5628
5629 newc->u.name = (char *)queue_remove(id_queue);
5630 if (!newc->u.name)
5631 goto fail;
5632 if (has_type) {
5633 type = (char *)queue_remove(id_queue);
5634 if (!type)
5635 goto fail;
5636 if (type[1] != 0) {
5637 yyerror2("invalid type %s", type);
5638 goto fail;
5639 }
5640 switch (type[0]) {
5641 case 'b':
5642 sclass = "blk_file";
5643 break;
5644 case 'c':
5645 sclass = "chr_file";
5646 break;
5647 case 'd':
5648 sclass = "dir";
5649 break;
5650 case 'p':
5651 sclass = "fifo_file";
5652 break;
5653 case 'l':
5654 sclass = "lnk_file";
5655 break;
5656 case 's':
5657 sclass = "sock_file";
5658 break;
5659 case '-':
5660 sclass = "file";
5661 break;
5662 default:
5663 yyerror2("invalid type %s", type);
5664 goto fail;
5665 }
5666
5667 cladatum = hashtab_search(policydbp->p_classes.table,
5668 sclass);
5669 if (!cladatum) {
5670 yyerror2("could not find class %s for "
5671 "genfscon statement", sclass);
5672 goto fail;
5673 }
5674 newc->v.sclass = cladatum->s.value;
5675 }
5676 if (parse_security_context(&newc->context[0]))
5677 goto fail;
5678
5679 head = genfs->head;
5680
5681 for (p = NULL, c = head; c; p = c, c = c->next) {
5682 if (!strcmp(newc->u.name, c->u.name) &&
5683 (!newc->v.sclass || !c->v.sclass
5684 || newc->v.sclass == c->v.sclass)) {
5685 yyerror2("duplicate entry for genfs entry (%s, %s)",
5686 genfs->fstype, newc->u.name);
5687 goto fail;
5688 }
5689 len = strlen(newc->u.name);
5690 len2 = strlen(c->u.name);
5691 if (len > len2)
5692 break;
5693 }
5694
5695 newc->next = c;
5696 if (p)
5697 p->next = newc;
5698 else
5699 genfs->head = newc;
5700 free(type);
5701 return 0;
5702 fail:
5703 if (type)
5704 free(type);
5705 context_destroy(&newc->context[0]);
5706 if (fstype)
5707 free(fstype);
5708 if (newc->u.name)
5709 free(newc->u.name);
5710 free(newc);
5711 return -1;
5712 }
5713
define_genfs_context(int has_type)5714 int define_genfs_context(int has_type)
5715 {
5716 return define_genfs_context_helper(queue_remove(id_queue), has_type);
5717 }
5718
define_range_trans(int class_specified)5719 int define_range_trans(int class_specified)
5720 {
5721 char *id;
5722 level_datum_t *levdatum = 0;
5723 class_datum_t *cladatum;
5724 range_trans_rule_t *rule;
5725 int l, add = 1;
5726
5727 if (!mlspol) {
5728 yyerror("range_transition rule in non-MLS configuration");
5729 return -1;
5730 }
5731
5732 if (pass == 1) {
5733 while ((id = queue_remove(id_queue)))
5734 free(id);
5735 while ((id = queue_remove(id_queue)))
5736 free(id);
5737 if (class_specified)
5738 while ((id = queue_remove(id_queue)))
5739 free(id);
5740 id = queue_remove(id_queue);
5741 free(id);
5742 for (l = 0; l < 2; l++) {
5743 while ((id = queue_remove(id_queue))) {
5744 free(id);
5745 }
5746 id = queue_remove(id_queue);
5747 if (!id)
5748 break;
5749 free(id);
5750 }
5751 return 0;
5752 }
5753
5754 rule = malloc(sizeof(struct range_trans_rule));
5755 if (!rule) {
5756 yyerror("out of memory");
5757 return -1;
5758 }
5759 range_trans_rule_init(rule);
5760
5761 while ((id = queue_remove(id_queue))) {
5762 if (set_types(&rule->stypes, id, &add, 0))
5763 goto out;
5764 }
5765 add = 1;
5766 while ((id = queue_remove(id_queue))) {
5767 if (set_types(&rule->ttypes, id, &add, 0))
5768 goto out;
5769 }
5770
5771 if (class_specified) {
5772 if (read_classes(&rule->tclasses))
5773 goto out;
5774 } else {
5775 cladatum = hashtab_search(policydbp->p_classes.table,
5776 "process");
5777 if (!cladatum) {
5778 yyerror2("could not find process class for "
5779 "legacy range_transition statement");
5780 goto out;
5781 }
5782
5783 if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) {
5784 yyerror("out of memory");
5785 goto out;
5786 }
5787 }
5788
5789 id = (char *)queue_remove(id_queue);
5790 if (!id) {
5791 yyerror("no range in range_transition definition?");
5792 goto out;
5793 }
5794 for (l = 0; l < 2; l++) {
5795 levdatum = hashtab_search(policydbp->p_levels.table, id);
5796 if (!levdatum) {
5797 yyerror2("unknown level %s used in range_transition "
5798 "definition", id);
5799 free(id);
5800 goto out;
5801 }
5802 free(id);
5803
5804 rule->trange.level[l].sens = levdatum->level->sens;
5805
5806 while ((id = queue_remove(id_queue))) {
5807 if (parse_semantic_categories(id, levdatum,
5808 &rule->trange.level[l].cat)) {
5809 free(id);
5810 goto out;
5811 }
5812 free(id);
5813 }
5814
5815 id = (char *)queue_remove(id_queue);
5816 if (!id)
5817 break;
5818 }
5819 if (l == 0) {
5820 if (mls_semantic_level_cpy(&rule->trange.level[1],
5821 &rule->trange.level[0])) {
5822 yyerror("out of memory");
5823 goto out;
5824 }
5825 }
5826
5827 append_range_trans(rule);
5828 return 0;
5829
5830 out:
5831 range_trans_rule_destroy(rule);
5832 free(rule);
5833 return -1;
5834 }
5835
5836 /* FLASK */
5837