1 /*
2 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
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 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation, version 2.
26 */
27
28 /* FLASK */
29
30 #include <sys/types.h>
31 #include <assert.h>
32 #include <stdarg.h>
33 #include <stdint.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #include <stdlib.h>
41
42 #include <sepol/policydb/expand.h>
43 #include <sepol/policydb/policydb.h>
44 #include <sepol/policydb/services.h>
45 #include <sepol/policydb/conditional.h>
46 #include <sepol/policydb/flask.h>
47 #include <sepol/policydb/hierarchy.h>
48 #include <sepol/policydb/polcaps.h>
49 #include "queue.h"
50 #include "checkpolicy.h"
51 #include "module_compiler.h"
52 #include "policy_define.h"
53
54 policydb_t *policydbp;
55 queue_t id_queue = 0;
56 unsigned int pass;
57 char *curfile = 0;
58 int mlspol = 0;
59
60 extern unsigned long policydb_lineno;
61 extern unsigned long source_lineno;
62 extern unsigned int policydb_errors;
63
64 extern int yywarn(char *msg);
65 extern int yyerror(char *msg);
66
67 #define ERRORMSG_LEN 255
68 static char errormsg[ERRORMSG_LEN + 1] = {0};
69
70 static int id_has_dot(char *id);
71 static int parse_security_context(context_struct_t *c);
72
73 /* initialize all of the state variables for the scanner/parser */
init_parser(int pass_number)74 void init_parser(int pass_number)
75 {
76 policydb_lineno = 1;
77 source_lineno = 1;
78 policydb_errors = 0;
79 pass = pass_number;
80 }
81
yyerror2(char * fmt,...)82 void yyerror2(char *fmt, ...)
83 {
84 va_list ap;
85 va_start(ap, fmt);
86 vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
87 yyerror(errormsg);
88 va_end(ap);
89 }
90
insert_separator(int push)91 int insert_separator(int push)
92 {
93 int error;
94
95 if (push)
96 error = queue_push(id_queue, 0);
97 else
98 error = queue_insert(id_queue, 0);
99
100 if (error) {
101 yyerror("queue overflow");
102 return -1;
103 }
104 return 0;
105 }
106
insert_id(char * id,int push)107 int insert_id(char *id, int push)
108 {
109 char *newid = 0;
110 int error;
111
112 newid = (char *)malloc(strlen(id) + 1);
113 if (!newid) {
114 yyerror("out of memory");
115 return -1;
116 }
117 strcpy(newid, id);
118 if (push)
119 error = queue_push(id_queue, (queue_element_t) newid);
120 else
121 error = queue_insert(id_queue, (queue_element_t) newid);
122
123 if (error) {
124 yyerror("queue overflow");
125 free(newid);
126 return -1;
127 }
128 return 0;
129 }
130
131 /* If the identifier has a dot within it and that its first character
132 is not a dot then return 1, else return 0. */
id_has_dot(char * id)133 static int id_has_dot(char *id)
134 {
135 if (strchr(id, '.') >= id + 1) {
136 return 1;
137 }
138 return 0;
139 }
140
define_class(void)141 int define_class(void)
142 {
143 char *id = 0;
144 class_datum_t *datum = 0;
145 int ret;
146 uint32_t value;
147
148 if (pass == 2) {
149 id = queue_remove(id_queue);
150 free(id);
151 return 0;
152 }
153
154 id = (char *)queue_remove(id_queue);
155 if (!id) {
156 yyerror("no class name for class definition?");
157 return -1;
158 }
159 datum = (class_datum_t *) malloc(sizeof(class_datum_t));
160 if (!datum) {
161 yyerror("out of memory");
162 goto bad;
163 }
164 memset(datum, 0, sizeof(class_datum_t));
165 ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
166 switch (ret) {
167 case -3:{
168 yyerror("Out of memory!");
169 goto bad;
170 }
171 case -2:{
172 yyerror2("duplicate declaration of class %s", id);
173 goto bad;
174 }
175 case -1:{
176 yyerror("could not declare class here");
177 goto bad;
178 }
179 case 0:
180 case 1:{
181 break;
182 }
183 default:{
184 assert(0); /* should never get here */
185 }
186 }
187 datum->s.value = value;
188 return 0;
189
190 bad:
191 if (id)
192 free(id);
193 if (datum)
194 free(datum);
195 return -1;
196 }
197
define_permissive(void)198 int define_permissive(void)
199 {
200 char *type = NULL;
201 struct type_datum *t;
202 int rc = 0;
203
204 type = queue_remove(id_queue);
205
206 if (!type) {
207 yyerror2("forgot to include type in permissive definition?");
208 rc = -1;
209 goto out;
210 }
211
212 if (pass == 1)
213 goto out;
214
215 if (!is_id_in_scope(SYM_TYPES, type)) {
216 yyerror2("type %s is not within scope", type);
217 rc = -1;
218 goto out;
219 }
220
221 t = hashtab_search(policydbp->p_types.table, type);
222 if (!t) {
223 yyerror2("type is not defined: %s", type);
224 rc = -1;
225 goto out;
226 }
227
228 if (t->flavor == TYPE_ATTRIB) {
229 yyerror2("attributes may not be permissive: %s\n", type);
230 rc = -1;
231 goto out;
232 }
233
234 t->flags |= TYPE_FLAGS_PERMISSIVE;
235
236 out:
237 free(type);
238 return rc;
239 }
240
define_polcap(void)241 int define_polcap(void)
242 {
243 char *id = 0;
244 int capnum;
245
246 if (pass == 2) {
247 id = queue_remove(id_queue);
248 free(id);
249 return 0;
250 }
251
252 id = (char *)queue_remove(id_queue);
253 if (!id) {
254 yyerror("no capability name for policycap definition?");
255 goto bad;
256 }
257
258 /* Check for valid cap name -> number mapping */
259 capnum = sepol_polcap_getnum(id);
260 if (capnum < 0) {
261 yyerror2("invalid policy capability name %s", id);
262 goto bad;
263 }
264
265 /* Store it */
266 if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
267 yyerror("out of memory");
268 goto bad;
269 }
270
271 free(id);
272 return 0;
273
274 bad:
275 free(id);
276 return -1;
277 }
278
define_initial_sid(void)279 int define_initial_sid(void)
280 {
281 char *id = 0;
282 ocontext_t *newc = 0, *c, *head;
283
284 if (pass == 2) {
285 id = queue_remove(id_queue);
286 free(id);
287 return 0;
288 }
289
290 id = (char *)queue_remove(id_queue);
291 if (!id) {
292 yyerror("no sid name for SID definition?");
293 return -1;
294 }
295 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
296 if (!newc) {
297 yyerror("out of memory");
298 goto bad;
299 }
300 memset(newc, 0, sizeof(ocontext_t));
301 newc->u.name = id;
302 context_init(&newc->context[0]);
303 head = policydbp->ocontexts[OCON_ISID];
304
305 for (c = head; c; c = c->next) {
306 if (!strcmp(newc->u.name, c->u.name)) {
307 yyerror2("duplicate initial SID %s", id);
308 goto bad;
309 }
310 }
311
312 if (head) {
313 newc->sid[0] = head->sid[0] + 1;
314 } else {
315 newc->sid[0] = 1;
316 }
317 newc->next = head;
318 policydbp->ocontexts[OCON_ISID] = newc;
319
320 return 0;
321
322 bad:
323 if (id)
324 free(id);
325 if (newc)
326 free(newc);
327 return -1;
328 }
329
read_classes(ebitmap_t * e_classes)330 static int read_classes(ebitmap_t *e_classes)
331 {
332 char *id;
333 class_datum_t *cladatum;
334
335 while ((id = queue_remove(id_queue))) {
336 if (!is_id_in_scope(SYM_CLASSES, id)) {
337 yyerror2("class %s is not within scope", id);
338 return -1;
339 }
340 cladatum = hashtab_search(policydbp->p_classes.table, id);
341 if (!cladatum) {
342 yyerror2("unknown class %s", id);
343 return -1;
344 }
345 if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
346 yyerror("Out of memory");
347 return -1;
348 }
349 free(id);
350 }
351 return 0;
352 }
353
define_common_perms(void)354 int define_common_perms(void)
355 {
356 char *id = 0, *perm = 0;
357 common_datum_t *comdatum = 0;
358 perm_datum_t *perdatum = 0;
359 int ret;
360
361 if (pass == 2) {
362 while ((id = queue_remove(id_queue)))
363 free(id);
364 return 0;
365 }
366
367 id = (char *)queue_remove(id_queue);
368 if (!id) {
369 yyerror("no common name for common perm definition?");
370 return -1;
371 }
372 comdatum = hashtab_search(policydbp->p_commons.table, id);
373 if (comdatum) {
374 yyerror2("duplicate declaration for common %s\n", id);
375 return -1;
376 }
377 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
378 if (!comdatum) {
379 yyerror("out of memory");
380 goto bad;
381 }
382 memset(comdatum, 0, sizeof(common_datum_t));
383 ret = hashtab_insert(policydbp->p_commons.table,
384 (hashtab_key_t) id, (hashtab_datum_t) comdatum);
385
386 if (ret == SEPOL_EEXIST) {
387 yyerror("duplicate common definition");
388 goto bad;
389 }
390 if (ret == SEPOL_ENOMEM) {
391 yyerror("hash table overflow");
392 goto bad;
393 }
394 comdatum->s.value = policydbp->p_commons.nprim + 1;
395 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
396 yyerror("out of memory");
397 goto bad;
398 }
399 policydbp->p_commons.nprim++;
400 while ((perm = queue_remove(id_queue))) {
401 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
402 if (!perdatum) {
403 yyerror("out of memory");
404 goto bad_perm;
405 }
406 memset(perdatum, 0, sizeof(perm_datum_t));
407 perdatum->s.value = comdatum->permissions.nprim + 1;
408
409 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
410 yyerror
411 ("too many permissions to fit in an access vector");
412 goto bad_perm;
413 }
414 ret = hashtab_insert(comdatum->permissions.table,
415 (hashtab_key_t) perm,
416 (hashtab_datum_t) perdatum);
417
418 if (ret == SEPOL_EEXIST) {
419 yyerror2("duplicate permission %s in common %s", perm,
420 id);
421 goto bad_perm;
422 }
423 if (ret == SEPOL_ENOMEM) {
424 yyerror("hash table overflow");
425 goto bad_perm;
426 }
427 comdatum->permissions.nprim++;
428 }
429
430 return 0;
431
432 bad:
433 if (id)
434 free(id);
435 if (comdatum)
436 free(comdatum);
437 return -1;
438
439 bad_perm:
440 if (perm)
441 free(perm);
442 if (perdatum)
443 free(perdatum);
444 return -1;
445 }
446
define_av_perms(int inherits)447 int define_av_perms(int inherits)
448 {
449 char *id;
450 class_datum_t *cladatum;
451 common_datum_t *comdatum;
452 perm_datum_t *perdatum = 0, *perdatum2 = 0;
453 int ret;
454
455 if (pass == 2) {
456 while ((id = queue_remove(id_queue)))
457 free(id);
458 return 0;
459 }
460
461 id = (char *)queue_remove(id_queue);
462 if (!id) {
463 yyerror("no tclass name for av perm definition?");
464 return -1;
465 }
466 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
467 (hashtab_key_t) id);
468 if (!cladatum) {
469 yyerror2("class %s is not defined", id);
470 goto bad;
471 }
472 free(id);
473
474 if (cladatum->comdatum || cladatum->permissions.nprim) {
475 yyerror("duplicate access vector definition");
476 return -1;
477 }
478 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
479 yyerror("out of memory");
480 return -1;
481 }
482 if (inherits) {
483 id = (char *)queue_remove(id_queue);
484 if (!id) {
485 yyerror
486 ("no inherits name for access vector definition?");
487 return -1;
488 }
489 comdatum =
490 (common_datum_t *) hashtab_search(policydbp->p_commons.
491 table,
492 (hashtab_key_t) id);
493
494 if (!comdatum) {
495 yyerror2("common %s is not defined", id);
496 goto bad;
497 }
498 cladatum->comkey = id;
499 cladatum->comdatum = comdatum;
500
501 /*
502 * Class-specific permissions start with values
503 * after the last common permission.
504 */
505 cladatum->permissions.nprim += comdatum->permissions.nprim;
506 }
507 while ((id = queue_remove(id_queue))) {
508 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
509 if (!perdatum) {
510 yyerror("out of memory");
511 goto bad;
512 }
513 memset(perdatum, 0, sizeof(perm_datum_t));
514 perdatum->s.value = ++cladatum->permissions.nprim;
515
516 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
517 yyerror
518 ("too many permissions to fit in an access vector");
519 goto bad;
520 }
521 if (inherits) {
522 /*
523 * Class-specific permissions and
524 * common permissions exist in the same
525 * name space.
526 */
527 perdatum2 =
528 (perm_datum_t *) hashtab_search(cladatum->comdatum->
529 permissions.table,
530 (hashtab_key_t) id);
531 if (perdatum2) {
532 yyerror2("permission %s conflicts with an "
533 "inherited permission", id);
534 goto bad;
535 }
536 }
537 ret = hashtab_insert(cladatum->permissions.table,
538 (hashtab_key_t) id,
539 (hashtab_datum_t) perdatum);
540
541 if (ret == SEPOL_EEXIST) {
542 yyerror2("duplicate permission %s", id);
543 goto bad;
544 }
545 if (ret == SEPOL_ENOMEM) {
546 yyerror("hash table overflow");
547 goto bad;
548 }
549 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
550 yyerror("out of memory");
551 goto bad;
552 }
553 }
554
555 return 0;
556
557 bad:
558 if (id)
559 free(id);
560 if (perdatum)
561 free(perdatum);
562 return -1;
563 }
564
define_sens(void)565 int define_sens(void)
566 {
567 char *id;
568 mls_level_t *level = 0;
569 level_datum_t *datum = 0, *aliasdatum = 0;
570 int ret;
571 uint32_t value; /* dummy variable -- its value is never used */
572
573 if (!mlspol) {
574 yyerror("sensitivity definition in non-MLS configuration");
575 return -1;
576 }
577
578 if (pass == 2) {
579 while ((id = queue_remove(id_queue)))
580 free(id);
581 return 0;
582 }
583
584 id = (char *)queue_remove(id_queue);
585 if (!id) {
586 yyerror("no sensitivity name for sensitivity definition?");
587 return -1;
588 }
589 if (id_has_dot(id)) {
590 yyerror("sensitivity identifiers may not contain periods");
591 goto bad;
592 }
593 level = (mls_level_t *) malloc(sizeof(mls_level_t));
594 if (!level) {
595 yyerror("out of memory");
596 goto bad;
597 }
598 mls_level_init(level);
599 level->sens = 0; /* actual value set in define_dominance */
600 ebitmap_init(&level->cat); /* actual value set in define_level */
601
602 datum = (level_datum_t *) malloc(sizeof(level_datum_t));
603 if (!datum) {
604 yyerror("out of memory");
605 goto bad;
606 }
607 level_datum_init(datum);
608 datum->isalias = FALSE;
609 datum->level = level;
610
611 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
612 switch (ret) {
613 case -3:{
614 yyerror("Out of memory!");
615 goto bad;
616 }
617 case -2:{
618 yyerror("duplicate declaration of sensitivity level");
619 goto bad;
620 }
621 case -1:{
622 yyerror("could not declare sensitivity level here");
623 goto bad;
624 }
625 case 0:
626 case 1:{
627 break;
628 }
629 default:{
630 assert(0); /* should never get here */
631 }
632 }
633
634 while ((id = queue_remove(id_queue))) {
635 if (id_has_dot(id)) {
636 yyerror("sensitivity aliases may not contain periods");
637 goto bad_alias;
638 }
639 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
640 if (!aliasdatum) {
641 yyerror("out of memory");
642 goto bad_alias;
643 }
644 level_datum_init(aliasdatum);
645 aliasdatum->isalias = TRUE;
646 aliasdatum->level = level;
647
648 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
649 switch (ret) {
650 case -3:{
651 yyerror("Out of memory!");
652 goto bad_alias;
653 }
654 case -2:{
655 yyerror
656 ("duplicate declaration of sensitivity alias");
657 goto bad_alias;
658 }
659 case -1:{
660 yyerror
661 ("could not declare sensitivity alias here");
662 goto bad_alias;
663 }
664 case 0:
665 case 1:{
666 break;
667 }
668 default:{
669 assert(0); /* should never get here */
670 }
671 }
672 }
673
674 return 0;
675
676 bad:
677 if (id)
678 free(id);
679 if (level)
680 free(level);
681 if (datum) {
682 level_datum_destroy(datum);
683 free(datum);
684 }
685 return -1;
686
687 bad_alias:
688 if (id)
689 free(id);
690 if (aliasdatum) {
691 level_datum_destroy(aliasdatum);
692 free(aliasdatum);
693 }
694 return -1;
695 }
696
define_dominance(void)697 int define_dominance(void)
698 {
699 level_datum_t *datum;
700 int order;
701 char *id;
702
703 if (!mlspol) {
704 yyerror("dominance definition in non-MLS configuration");
705 return -1;
706 }
707
708 if (pass == 2) {
709 while ((id = queue_remove(id_queue)))
710 free(id);
711 return 0;
712 }
713
714 order = 0;
715 while ((id = (char *)queue_remove(id_queue))) {
716 datum =
717 (level_datum_t *) hashtab_search(policydbp->p_levels.table,
718 (hashtab_key_t) id);
719 if (!datum) {
720 yyerror2("unknown sensitivity %s used in dominance "
721 "definition", id);
722 free(id);
723 return -1;
724 }
725 if (datum->level->sens != 0) {
726 yyerror2("sensitivity %s occurs multiply in dominance "
727 "definition", id);
728 free(id);
729 return -1;
730 }
731 datum->level->sens = ++order;
732
733 /* no need to keep sensitivity name */
734 free(id);
735 }
736
737 if (order != policydbp->p_levels.nprim) {
738 yyerror
739 ("all sensitivities must be specified in dominance definition");
740 return -1;
741 }
742 return 0;
743 }
744
define_category(void)745 int define_category(void)
746 {
747 char *id;
748 cat_datum_t *datum = 0, *aliasdatum = 0;
749 int ret;
750 uint32_t value;
751
752 if (!mlspol) {
753 yyerror("category definition in non-MLS configuration");
754 return -1;
755 }
756
757 if (pass == 2) {
758 while ((id = queue_remove(id_queue)))
759 free(id);
760 return 0;
761 }
762
763 id = (char *)queue_remove(id_queue);
764 if (!id) {
765 yyerror("no category name for category definition?");
766 return -1;
767 }
768 if (id_has_dot(id)) {
769 yyerror("category identifiers may not contain periods");
770 goto bad;
771 }
772 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
773 if (!datum) {
774 yyerror("out of memory");
775 goto bad;
776 }
777 cat_datum_init(datum);
778 datum->isalias = FALSE;
779
780 ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
781 switch (ret) {
782 case -3:{
783 yyerror("Out of memory!");
784 goto bad;
785 }
786 case -2:{
787 yyerror("duplicate declaration of category");
788 goto bad;
789 }
790 case -1:{
791 yyerror("could not declare category here");
792 goto bad;
793 }
794 case 0:
795 case 1:{
796 break;
797 }
798 default:{
799 assert(0); /* should never get here */
800 }
801 }
802 datum->s.value = value;
803
804 while ((id = queue_remove(id_queue))) {
805 if (id_has_dot(id)) {
806 yyerror("category aliases may not contain periods");
807 goto bad_alias;
808 }
809 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
810 if (!aliasdatum) {
811 yyerror("out of memory");
812 goto bad_alias;
813 }
814 cat_datum_init(aliasdatum);
815 aliasdatum->isalias = TRUE;
816 aliasdatum->s.value = datum->s.value;
817
818 ret =
819 declare_symbol(SYM_CATS, id, aliasdatum, NULL,
820 &datum->s.value);
821 switch (ret) {
822 case -3:{
823 yyerror("Out of memory!");
824 goto bad_alias;
825 }
826 case -2:{
827 yyerror
828 ("duplicate declaration of category aliases");
829 goto bad_alias;
830 }
831 case -1:{
832 yyerror
833 ("could not declare category aliases here");
834 goto bad_alias;
835 }
836 case 0:
837 case 1:{
838 break;
839 }
840 default:{
841 assert(0); /* should never get here */
842 }
843 }
844 }
845
846 return 0;
847
848 bad:
849 if (id)
850 free(id);
851 if (datum) {
852 cat_datum_destroy(datum);
853 free(datum);
854 }
855 return -1;
856
857 bad_alias:
858 if (id)
859 free(id);
860 if (aliasdatum) {
861 cat_datum_destroy(aliasdatum);
862 free(aliasdatum);
863 }
864 return -1;
865 }
866
clone_level(hashtab_key_t key,hashtab_datum_t datum,void * arg)867 static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
868 {
869 level_datum_t *levdatum = (level_datum_t *) datum;
870 mls_level_t *level = (mls_level_t *) arg, *newlevel;
871
872 if (levdatum->level == level) {
873 levdatum->defined = 1;
874 if (!levdatum->isalias)
875 return 0;
876 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
877 if (!newlevel)
878 return -1;
879 if (mls_level_cpy(newlevel, level)) {
880 free(newlevel);
881 return -1;
882 }
883 levdatum->level = newlevel;
884 }
885 return 0;
886 }
887
define_level(void)888 int define_level(void)
889 {
890 char *id;
891 level_datum_t *levdatum;
892
893 if (!mlspol) {
894 yyerror("level definition in non-MLS configuration");
895 return -1;
896 }
897
898 if (pass == 2) {
899 while ((id = queue_remove(id_queue)))
900 free(id);
901 return 0;
902 }
903
904 id = (char *)queue_remove(id_queue);
905 if (!id) {
906 yyerror("no level name for level definition?");
907 return -1;
908 }
909 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
910 (hashtab_key_t) id);
911 if (!levdatum) {
912 yyerror2("unknown sensitivity %s used in level definition", id);
913 free(id);
914 return -1;
915 }
916 if (ebitmap_length(&levdatum->level->cat)) {
917 yyerror2("sensitivity %s used in multiple level definitions",
918 id);
919 free(id);
920 return -1;
921 }
922 free(id);
923
924 levdatum->defined = 1;
925
926 while ((id = queue_remove(id_queue))) {
927 cat_datum_t *cdatum;
928 int range_start, range_end, i;
929
930 if (id_has_dot(id)) {
931 char *id_start = id;
932 char *id_end = strchr(id, '.');
933
934 *(id_end++) = '\0';
935
936 cdatum =
937 (cat_datum_t *) hashtab_search(policydbp->p_cats.
938 table,
939 (hashtab_key_t)
940 id_start);
941 if (!cdatum) {
942 yyerror2("unknown category %s", id_start);
943 free(id);
944 return -1;
945 }
946 range_start = cdatum->s.value - 1;
947 cdatum =
948 (cat_datum_t *) hashtab_search(policydbp->p_cats.
949 table,
950 (hashtab_key_t)
951 id_end);
952 if (!cdatum) {
953 yyerror2("unknown category %s", id_end);
954 free(id);
955 return -1;
956 }
957 range_end = cdatum->s.value - 1;
958
959 if (range_end < range_start) {
960 yyerror2("category range is invalid");
961 free(id);
962 return -1;
963 }
964 } else {
965 cdatum =
966 (cat_datum_t *) hashtab_search(policydbp->p_cats.
967 table,
968 (hashtab_key_t) id);
969 range_start = range_end = cdatum->s.value - 1;
970 }
971
972 for (i = range_start; i <= range_end; i++) {
973 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
974 yyerror("out of memory");
975 free(id);
976 return -1;
977 }
978 }
979
980 free(id);
981 }
982
983 if (hashtab_map
984 (policydbp->p_levels.table, clone_level, levdatum->level)) {
985 yyerror("out of memory");
986 return -1;
987 }
988
989 return 0;
990 }
991
define_attrib(void)992 int define_attrib(void)
993 {
994 if (pass == 2) {
995 free(queue_remove(id_queue));
996 return 0;
997 }
998
999 if (declare_type(TRUE, TRUE) == NULL) {
1000 return -1;
1001 }
1002 return 0;
1003 }
1004
add_aliases_to_type(type_datum_t * type)1005 static int add_aliases_to_type(type_datum_t * type)
1006 {
1007 char *id;
1008 type_datum_t *aliasdatum = NULL;
1009 int ret;
1010 while ((id = queue_remove(id_queue))) {
1011 if (id_has_dot(id)) {
1012 free(id);
1013 yyerror
1014 ("type alias identifiers may not contain periods");
1015 return -1;
1016 }
1017 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1018 if (!aliasdatum) {
1019 free(id);
1020 yyerror("Out of memory!");
1021 return -1;
1022 }
1023 memset(aliasdatum, 0, sizeof(type_datum_t));
1024 aliasdatum->s.value = type->s.value;
1025
1026 ret = declare_symbol(SYM_TYPES, id, aliasdatum,
1027 NULL, &aliasdatum->s.value);
1028 switch (ret) {
1029 case -3:{
1030 yyerror("Out of memory!");
1031 goto cleanup;
1032 }
1033 case -2:{
1034 yyerror2("duplicate declaration of alias %s",
1035 id);
1036 goto cleanup;
1037 }
1038 case -1:{
1039 yyerror("could not declare alias here");
1040 goto cleanup;
1041 }
1042 case 0: break;
1043 case 1:{
1044 /* ret == 1 means the alias was required and therefore already
1045 * has a value. Set it up as an alias with a different primary. */
1046 type_datum_destroy(aliasdatum);
1047 free(aliasdatum);
1048
1049 aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
1050 assert(aliasdatum);
1051
1052 aliasdatum->primary = type->s.value;
1053 aliasdatum->flavor = TYPE_ALIAS;
1054
1055 break;
1056 }
1057 default:{
1058 assert(0); /* should never get here */
1059 }
1060 }
1061 }
1062 return 0;
1063 cleanup:
1064 free(id);
1065 type_datum_destroy(aliasdatum);
1066 free(aliasdatum);
1067 return -1;
1068 }
1069
define_typealias(void)1070 int define_typealias(void)
1071 {
1072 char *id;
1073 type_datum_t *t;
1074
1075 if (pass == 2) {
1076 while ((id = queue_remove(id_queue)))
1077 free(id);
1078 return 0;
1079 }
1080
1081 id = (char *)queue_remove(id_queue);
1082 if (!id) {
1083 yyerror("no type name for typealias definition?");
1084 return -1;
1085 }
1086
1087 if (!is_id_in_scope(SYM_TYPES, id)) {
1088 yyerror2("type %s is not within scope", id);
1089 free(id);
1090 return -1;
1091 }
1092 t = hashtab_search(policydbp->p_types.table, id);
1093 if (!t || t->flavor == TYPE_ATTRIB) {
1094 yyerror2("unknown type %s, or it was already declared as an "
1095 "attribute", id);
1096 free(id);
1097 return -1;
1098 }
1099 return add_aliases_to_type(t);
1100 }
1101
define_typeattribute(void)1102 int define_typeattribute(void)
1103 {
1104 char *id;
1105 type_datum_t *t, *attr;
1106
1107 if (pass == 2) {
1108 while ((id = queue_remove(id_queue)))
1109 free(id);
1110 return 0;
1111 }
1112
1113 id = (char *)queue_remove(id_queue);
1114 if (!id) {
1115 yyerror("no type name for typeattribute definition?");
1116 return -1;
1117 }
1118
1119 if (!is_id_in_scope(SYM_TYPES, id)) {
1120 yyerror2("type %s is not within scope", id);
1121 free(id);
1122 return -1;
1123 }
1124 t = hashtab_search(policydbp->p_types.table, id);
1125 if (!t || t->flavor == TYPE_ATTRIB) {
1126 yyerror2("unknown type %s", id);
1127 free(id);
1128 return -1;
1129 }
1130
1131 while ((id = queue_remove(id_queue))) {
1132 if (!is_id_in_scope(SYM_TYPES, id)) {
1133 yyerror2("attribute %s is not within scope", id);
1134 free(id);
1135 return -1;
1136 }
1137 attr = hashtab_search(policydbp->p_types.table, id);
1138 if (!attr) {
1139 /* treat it as a fatal error */
1140 yyerror2("attribute %s is not declared", id);
1141 free(id);
1142 return -1;
1143 }
1144
1145 if (attr->flavor != TYPE_ATTRIB) {
1146 yyerror2("%s is a type, not an attribute", id);
1147 free(id);
1148 return -1;
1149 }
1150
1151 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1152 yyerror("Out of memory!");
1153 return -1;
1154 }
1155
1156 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1157 yyerror("out of memory");
1158 return -1;
1159 }
1160 }
1161
1162 return 0;
1163 }
1164
define_typebounds_helper(char * bounds_id,char * type_id)1165 static int define_typebounds_helper(char *bounds_id, char *type_id)
1166 {
1167 type_datum_t *bounds, *type;
1168
1169 if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
1170 yyerror2("type %s is not within scope", bounds_id);
1171 return -1;
1172 }
1173
1174 bounds = hashtab_search(policydbp->p_types.table, bounds_id);
1175 if (!bounds || bounds->flavor == TYPE_ATTRIB) {
1176 yyerror2("hoge unknown type %s", bounds_id);
1177 return -1;
1178 }
1179
1180 if (!is_id_in_scope(SYM_TYPES, type_id)) {
1181 yyerror2("type %s is not within scope", type_id);
1182 return -1;
1183 }
1184
1185 type = hashtab_search(policydbp->p_types.table, type_id);
1186 if (!type || type->flavor == TYPE_ATTRIB) {
1187 yyerror2("type %s is not declared", type_id);
1188 return -1;
1189 }
1190
1191 if (type->flavor == TYPE_TYPE && !type->primary) {
1192 type = policydbp->type_val_to_struct[type->s.value - 1];
1193 } else if (type->flavor == TYPE_ALIAS) {
1194 type = policydbp->type_val_to_struct[type->primary - 1];
1195 }
1196
1197 if (!type->bounds)
1198 type->bounds = bounds->s.value;
1199 else if (type->bounds != bounds->s.value) {
1200 yyerror2("type %s has inconsistent master {%s,%s}",
1201 type_id,
1202 policydbp->p_type_val_to_name[type->bounds - 1],
1203 policydbp->p_type_val_to_name[bounds->s.value - 1]);
1204 return -1;
1205 }
1206
1207 return 0;
1208 }
1209
define_typebounds(void)1210 int define_typebounds(void)
1211 {
1212 char *bounds, *id;
1213
1214 if (pass == 1) {
1215 while ((id = queue_remove(id_queue)))
1216 free(id);
1217 return 0;
1218 }
1219
1220 bounds = (char *) queue_remove(id_queue);
1221 if (!bounds) {
1222 yyerror("no type name for typebounds definition?");
1223 return -1;
1224 }
1225
1226 while ((id = queue_remove(id_queue))) {
1227 if (define_typebounds_helper(bounds, id))
1228 return -1;
1229 free(id);
1230 }
1231 free(bounds);
1232
1233 return 0;
1234 }
1235
define_type(int alias)1236 int define_type(int alias)
1237 {
1238 char *id;
1239 type_datum_t *datum, *attr;
1240
1241 if (pass == 2) {
1242 /*
1243 * If type name contains ".", we have to define boundary
1244 * relationship implicitly to keep compatibility with
1245 * old name based hierarchy.
1246 */
1247 if ((id = queue_remove(id_queue))) {
1248 char *bounds, *delim;
1249
1250 if ((delim = strrchr(id, '.'))
1251 && (bounds = strdup(id))) {
1252 bounds[(size_t)(delim - id)] = '\0';
1253
1254 if (define_typebounds_helper(bounds, id))
1255 return -1;
1256 free(bounds);
1257 }
1258 free(id);
1259 }
1260
1261 if (alias) {
1262 while ((id = queue_remove(id_queue)))
1263 free(id);
1264 }
1265
1266 while ((id = queue_remove(id_queue)))
1267 free(id);
1268 return 0;
1269 }
1270
1271 if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1272 return -1;
1273 }
1274
1275 if (alias) {
1276 if (add_aliases_to_type(datum) == -1) {
1277 return -1;
1278 }
1279 }
1280
1281 while ((id = queue_remove(id_queue))) {
1282 if (!is_id_in_scope(SYM_TYPES, id)) {
1283 yyerror2("attribute %s is not within scope", id);
1284 free(id);
1285 return -1;
1286 }
1287 attr = hashtab_search(policydbp->p_types.table, id);
1288 if (!attr) {
1289 /* treat it as a fatal error */
1290 yyerror2("attribute %s is not declared", id);
1291 return -1;
1292 }
1293
1294 if (attr->flavor != TYPE_ATTRIB) {
1295 yyerror2("%s is a type, not an attribute", id);
1296 return -1;
1297 }
1298
1299 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1300 yyerror("Out of memory!");
1301 return -1;
1302 }
1303
1304 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1305 yyerror("Out of memory");
1306 return -1;
1307 }
1308 }
1309
1310 return 0;
1311 }
1312
1313 struct val_to_name {
1314 unsigned int val;
1315 char *name;
1316 };
1317
1318 /* Adds a type, given by its textual name, to a typeset. If *add is
1319 0, then add the type to the negative set; otherwise if *add is 1
1320 then add it to the positive side. */
set_types(type_set_t * set,char * id,int * add,char starallowed)1321 static int set_types(type_set_t * set, char *id, int *add, char starallowed)
1322 {
1323 type_datum_t *t;
1324
1325 if (strcmp(id, "*") == 0) {
1326 if (!starallowed) {
1327 yyerror("* not allowed in this type of rule");
1328 return -1;
1329 }
1330 /* set TYPE_STAR flag */
1331 set->flags = TYPE_STAR;
1332 free(id);
1333 *add = 1;
1334 return 0;
1335 }
1336
1337 if (strcmp(id, "~") == 0) {
1338 if (!starallowed) {
1339 yyerror("~ not allowed in this type of rule");
1340 return -1;
1341 }
1342 /* complement the set */
1343 set->flags = TYPE_COMP;
1344 free(id);
1345 *add = 1;
1346 return 0;
1347 }
1348
1349 if (strcmp(id, "-") == 0) {
1350 *add = 0;
1351 free(id);
1352 return 0;
1353 }
1354
1355 if (!is_id_in_scope(SYM_TYPES, id)) {
1356 yyerror2("type %s is not within scope", id);
1357 free(id);
1358 return -1;
1359 }
1360 t = hashtab_search(policydbp->p_types.table, id);
1361 if (!t) {
1362 yyerror2("unknown type %s", id);
1363 free(id);
1364 return -1;
1365 }
1366
1367 if (*add == 0) {
1368 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
1369 goto oom;
1370 } else {
1371 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
1372 goto oom;
1373 }
1374 free(id);
1375 *add = 1;
1376 return 0;
1377 oom:
1378 yyerror("Out of memory");
1379 free(id);
1380 return -1;
1381 }
1382
define_compute_type_helper(int which,avrule_t ** rule)1383 int define_compute_type_helper(int which, avrule_t ** rule)
1384 {
1385 char *id;
1386 type_datum_t *datum;
1387 ebitmap_t tclasses;
1388 ebitmap_node_t *node;
1389 avrule_t *avrule;
1390 class_perm_node_t *perm;
1391 int i, add = 1;
1392
1393 avrule = malloc(sizeof(avrule_t));
1394 if (!avrule) {
1395 yyerror("out of memory");
1396 return -1;
1397 }
1398 avrule_init(avrule);
1399 avrule->specified = which;
1400 avrule->line = policydb_lineno;
1401
1402 while ((id = queue_remove(id_queue))) {
1403 if (set_types(&avrule->stypes, id, &add, 0))
1404 return -1;
1405 }
1406 add = 1;
1407 while ((id = queue_remove(id_queue))) {
1408 if (set_types(&avrule->ttypes, id, &add, 0))
1409 return -1;
1410 }
1411
1412 ebitmap_init(&tclasses);
1413 if (read_classes(&tclasses))
1414 goto bad;
1415
1416 id = (char *)queue_remove(id_queue);
1417 if (!id) {
1418 yyerror("no newtype?");
1419 goto bad;
1420 }
1421 if (!is_id_in_scope(SYM_TYPES, id)) {
1422 yyerror2("type %s is not within scope", id);
1423 free(id);
1424 goto bad;
1425 }
1426 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1427 (hashtab_key_t) id);
1428 if (!datum || datum->flavor == TYPE_ATTRIB) {
1429 yyerror2("unknown type %s", id);
1430 goto bad;
1431 }
1432
1433 ebitmap_for_each_bit(&tclasses, node, i) {
1434 if (ebitmap_node_get_bit(node, i)) {
1435 perm = malloc(sizeof(class_perm_node_t));
1436 if (!perm) {
1437 yyerror("out of memory");
1438 return -1;
1439 }
1440 class_perm_node_init(perm);
1441 perm->class = i + 1;
1442 perm->data = datum->s.value;
1443 perm->next = avrule->perms;
1444 avrule->perms = perm;
1445 }
1446 }
1447 ebitmap_destroy(&tclasses);
1448
1449 *rule = avrule;
1450 return 0;
1451
1452 bad:
1453 avrule_destroy(avrule);
1454 free(avrule);
1455 return -1;
1456 }
1457
define_compute_type(int which)1458 int define_compute_type(int which)
1459 {
1460 char *id;
1461 avrule_t *avrule;
1462
1463 if (pass == 1) {
1464 while ((id = queue_remove(id_queue)))
1465 free(id);
1466 while ((id = queue_remove(id_queue)))
1467 free(id);
1468 while ((id = queue_remove(id_queue)))
1469 free(id);
1470 id = queue_remove(id_queue);
1471 free(id);
1472 return 0;
1473 }
1474
1475 if (define_compute_type_helper(which, &avrule))
1476 return -1;
1477
1478 append_avrule(avrule);
1479 return 0;
1480 }
1481
define_cond_compute_type(int which)1482 avrule_t *define_cond_compute_type(int which)
1483 {
1484 char *id;
1485 avrule_t *avrule;
1486
1487 if (pass == 1) {
1488 while ((id = queue_remove(id_queue)))
1489 free(id);
1490 while ((id = queue_remove(id_queue)))
1491 free(id);
1492 while ((id = queue_remove(id_queue)))
1493 free(id);
1494 id = queue_remove(id_queue);
1495 free(id);
1496 return (avrule_t *) 1;
1497 }
1498
1499 if (define_compute_type_helper(which, &avrule))
1500 return COND_ERR;
1501
1502 return avrule;
1503 }
1504
define_bool_tunable(int is_tunable)1505 int define_bool_tunable(int is_tunable)
1506 {
1507 char *id, *bool_value;
1508 cond_bool_datum_t *datum;
1509 int ret;
1510 uint32_t value;
1511
1512 if (pass == 2) {
1513 while ((id = queue_remove(id_queue)))
1514 free(id);
1515 return 0;
1516 }
1517
1518 id = (char *)queue_remove(id_queue);
1519 if (!id) {
1520 yyerror("no identifier for bool definition?");
1521 return -1;
1522 }
1523 if (id_has_dot(id)) {
1524 free(id);
1525 yyerror("boolean identifiers may not contain periods");
1526 return -1;
1527 }
1528 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1529 if (!datum) {
1530 yyerror("out of memory");
1531 free(id);
1532 return -1;
1533 }
1534 memset(datum, 0, sizeof(cond_bool_datum_t));
1535 if (is_tunable)
1536 datum->flags |= COND_BOOL_FLAGS_TUNABLE;
1537 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1538 switch (ret) {
1539 case -3:{
1540 yyerror("Out of memory!");
1541 goto cleanup;
1542 }
1543 case -2:{
1544 yyerror2("duplicate declaration of boolean %s", id);
1545 goto cleanup;
1546 }
1547 case -1:{
1548 yyerror("could not declare boolean here");
1549 goto cleanup;
1550 }
1551 case 0:
1552 case 1:{
1553 break;
1554 }
1555 default:{
1556 assert(0); /* should never get here */
1557 }
1558 }
1559 datum->s.value = value;
1560
1561 bool_value = (char *)queue_remove(id_queue);
1562 if (!bool_value) {
1563 yyerror("no default value for bool definition?");
1564 free(id);
1565 return -1;
1566 }
1567
1568 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
1569 return 0;
1570 cleanup:
1571 cond_destroy_bool(id, datum, NULL);
1572 return -1;
1573 }
1574
define_cond_pol_list(avrule_t * avlist,avrule_t * sl)1575 avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1576 {
1577 if (pass == 1) {
1578 /* return something so we get through pass 1 */
1579 return (avrule_t *) 1;
1580 }
1581
1582 if (sl == NULL) {
1583 /* This is a require block, return previous list */
1584 return avlist;
1585 }
1586
1587 /* prepend the new avlist to the pre-existing one */
1588 sl->next = avlist;
1589 return sl;
1590 }
1591
define_te_avtab_helper(int which,avrule_t ** rule)1592 int define_te_avtab_helper(int which, avrule_t ** rule)
1593 {
1594 char *id;
1595 class_datum_t *cladatum;
1596 perm_datum_t *perdatum = NULL;
1597 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
1598 ebitmap_t tclasses;
1599 ebitmap_node_t *node;
1600 avrule_t *avrule;
1601 unsigned int i;
1602 int add = 1, ret = 0;
1603 int suppress = 0;
1604
1605 avrule = (avrule_t *) malloc(sizeof(avrule_t));
1606 if (!avrule) {
1607 yyerror("memory error");
1608 ret = -1;
1609 goto out;
1610 }
1611 avrule_init(avrule);
1612 avrule->specified = which;
1613 avrule->line = policydb_lineno;
1614
1615 while ((id = queue_remove(id_queue))) {
1616 if (set_types
1617 (&avrule->stypes, id, &add,
1618 which == AVRULE_NEVERALLOW ? 1 : 0)) {
1619 ret = -1;
1620 goto out;
1621 }
1622 }
1623 add = 1;
1624 while ((id = queue_remove(id_queue))) {
1625 if (strcmp(id, "self") == 0) {
1626 free(id);
1627 avrule->flags |= RULE_SELF;
1628 continue;
1629 }
1630 if (set_types
1631 (&avrule->ttypes, id, &add,
1632 which == AVRULE_NEVERALLOW ? 1 : 0)) {
1633 ret = -1;
1634 goto out;
1635 }
1636 }
1637
1638 ebitmap_init(&tclasses);
1639 ret = read_classes(&tclasses);
1640 if (ret)
1641 goto out;
1642
1643 perms = NULL;
1644 ebitmap_for_each_bit(&tclasses, node, i) {
1645 if (!ebitmap_node_get_bit(node, i))
1646 continue;
1647 cur_perms =
1648 (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
1649 if (!cur_perms) {
1650 yyerror("out of memory");
1651 ret = -1;
1652 goto out;
1653 }
1654 class_perm_node_init(cur_perms);
1655 cur_perms->class = i + 1;
1656 if (!perms)
1657 perms = cur_perms;
1658 if (tail)
1659 tail->next = cur_perms;
1660 tail = cur_perms;
1661 }
1662
1663 while ((id = queue_remove(id_queue))) {
1664 cur_perms = perms;
1665 ebitmap_for_each_bit(&tclasses, node, i) {
1666 if (!ebitmap_node_get_bit(node, i))
1667 continue;
1668 cladatum = policydbp->class_val_to_struct[i];
1669
1670 if (strcmp(id, "*") == 0) {
1671 /* set all permissions in the class */
1672 cur_perms->data = ~0U;
1673 goto next;
1674 }
1675
1676 if (strcmp(id, "~") == 0) {
1677 /* complement the set */
1678 if (which == AVRULE_DONTAUDIT)
1679 yywarn("dontaudit rule with a ~?");
1680 cur_perms->data = ~cur_perms->data;
1681 goto next;
1682 }
1683
1684 perdatum =
1685 hashtab_search(cladatum->permissions.table, id);
1686 if (!perdatum) {
1687 if (cladatum->comdatum) {
1688 perdatum =
1689 hashtab_search(cladatum->comdatum->
1690 permissions.table,
1691 id);
1692 }
1693 }
1694 if (!perdatum) {
1695 if (!suppress)
1696 yyerror2("permission %s is not defined"
1697 " for class %s", id,
1698 policydbp->p_class_val_to_name[i]);
1699 continue;
1700 } else
1701 if (!is_perm_in_scope
1702 (id, policydbp->p_class_val_to_name[i])) {
1703 if (!suppress) {
1704 yyerror2("permission %s of class %s is"
1705 " not within scope", id,
1706 policydbp->p_class_val_to_name[i]);
1707 }
1708 continue;
1709 } else {
1710 cur_perms->data |= 1U << (perdatum->s.value - 1);
1711 }
1712 next:
1713 cur_perms = cur_perms->next;
1714 }
1715
1716 free(id);
1717 }
1718
1719 ebitmap_destroy(&tclasses);
1720
1721 avrule->perms = perms;
1722 *rule = avrule;
1723
1724 out:
1725 return ret;
1726
1727 }
1728
define_cond_te_avtab(int which)1729 avrule_t *define_cond_te_avtab(int which)
1730 {
1731 char *id;
1732 avrule_t *avrule;
1733 int i;
1734
1735 if (pass == 1) {
1736 for (i = 0; i < 4; i++) {
1737 while ((id = queue_remove(id_queue)))
1738 free(id);
1739 }
1740 return (avrule_t *) 1; /* any non-NULL value */
1741 }
1742
1743 if (define_te_avtab_helper(which, &avrule))
1744 return COND_ERR;
1745
1746 return avrule;
1747 }
1748
define_te_avtab(int which)1749 int define_te_avtab(int which)
1750 {
1751 char *id;
1752 avrule_t *avrule;
1753 int i;
1754
1755 if (pass == 1) {
1756 for (i = 0; i < 4; i++) {
1757 while ((id = queue_remove(id_queue)))
1758 free(id);
1759 }
1760 return 0;
1761 }
1762
1763 if (define_te_avtab_helper(which, &avrule))
1764 return -1;
1765
1766 /* append this avrule to the end of the current rules list */
1767 append_avrule(avrule);
1768 return 0;
1769 }
1770
1771 /* The role-types rule is no longer used to declare regular role or
1772 * role attribute, but solely aimed for declaring role-types associations.
1773 */
define_role_types(void)1774 int define_role_types(void)
1775 {
1776 role_datum_t *role;
1777 char *id;
1778 int add = 1;
1779
1780 if (pass == 1) {
1781 while ((id = queue_remove(id_queue)))
1782 free(id);
1783 return 0;
1784 }
1785
1786 id = (char *)queue_remove(id_queue);
1787 if (!id) {
1788 yyerror("no role name for role-types rule?");
1789 return -1;
1790 }
1791
1792 if (!is_id_in_scope(SYM_ROLES, id)) {
1793 yyerror2("role %s is not within scope", id);
1794 free(id);
1795 return -1;
1796 }
1797
1798 role = hashtab_search(policydbp->p_roles.table, id);
1799 if (!role) {
1800 yyerror2("unknown role %s", id);
1801 free(id);
1802 return -1;
1803 }
1804
1805 while ((id = queue_remove(id_queue))) {
1806 if (set_types(&role->types, id, &add, 0))
1807 return -1;
1808 }
1809
1810 return 0;
1811 }
1812
define_attrib_role(void)1813 int define_attrib_role(void)
1814 {
1815 if (pass == 2) {
1816 free(queue_remove(id_queue));
1817 return 0;
1818 }
1819
1820 /* Declare a role attribute */
1821 if (declare_role(TRUE) == NULL)
1822 return -1;
1823
1824 return 0;
1825 }
1826
define_role_attr(void)1827 int define_role_attr(void)
1828 {
1829 char *id;
1830 role_datum_t *r, *attr;
1831
1832 if (pass == 2) {
1833 while ((id = queue_remove(id_queue)))
1834 free(id);
1835 return 0;
1836 }
1837
1838 /* Declare a regular role */
1839 if ((r = declare_role(FALSE)) == NULL)
1840 return -1;
1841
1842 while ((id = queue_remove(id_queue))) {
1843 if (!is_id_in_scope(SYM_ROLES, id)) {
1844 yyerror2("attribute %s is not within scope", id);
1845 free(id);
1846 return -1;
1847 }
1848 attr = hashtab_search(policydbp->p_roles.table, id);
1849 if (!attr) {
1850 /* treat it as a fatal error */
1851 yyerror2("role attribute %s is not declared", id);
1852 free(id);
1853 return -1;
1854 }
1855
1856 if (attr->flavor != ROLE_ATTRIB) {
1857 yyerror2("%s is a regular role, not an attribute", id);
1858 free(id);
1859 return -1;
1860 }
1861
1862 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
1863 yyerror("Out of memory!");
1864 return -1;
1865 }
1866
1867 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
1868 yyerror("out of memory");
1869 return -1;
1870 }
1871 }
1872
1873 return 0;
1874 }
1875
define_roleattribute(void)1876 int define_roleattribute(void)
1877 {
1878 char *id;
1879 role_datum_t *r, *attr;
1880
1881 if (pass == 2) {
1882 while ((id = queue_remove(id_queue)))
1883 free(id);
1884 return 0;
1885 }
1886
1887 id = (char *)queue_remove(id_queue);
1888 if (!id) {
1889 yyerror("no role name for roleattribute definition?");
1890 return -1;
1891 }
1892
1893 if (!is_id_in_scope(SYM_ROLES, id)) {
1894 yyerror2("role %s is not within scope", id);
1895 free(id);
1896 return -1;
1897 }
1898 r = hashtab_search(policydbp->p_roles.table, id);
1899 /* We support adding one role attribute into another */
1900 if (!r) {
1901 yyerror2("unknown role %s", id);
1902 free(id);
1903 return -1;
1904 }
1905
1906 while ((id = queue_remove(id_queue))) {
1907 if (!is_id_in_scope(SYM_ROLES, id)) {
1908 yyerror2("attribute %s is not within scope", id);
1909 free(id);
1910 return -1;
1911 }
1912 attr = hashtab_search(policydbp->p_roles.table, id);
1913 if (!attr) {
1914 /* treat it as a fatal error */
1915 yyerror2("role attribute %s is not declared", id);
1916 free(id);
1917 return -1;
1918 }
1919
1920 if (attr->flavor != ROLE_ATTRIB) {
1921 yyerror2("%s is a regular role, not an attribute", id);
1922 free(id);
1923 return -1;
1924 }
1925
1926 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
1927 yyerror("Out of memory!");
1928 return -1;
1929 }
1930
1931 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
1932 yyerror("out of memory");
1933 return -1;
1934 }
1935 }
1936
1937 return 0;
1938 }
1939
merge_roles_dom(role_datum_t * r1,role_datum_t * r2)1940 role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
1941 {
1942 role_datum_t *new;
1943
1944 if (pass == 1) {
1945 return (role_datum_t *) 1; /* any non-NULL value */
1946 }
1947
1948 new = malloc(sizeof(role_datum_t));
1949 if (!new) {
1950 yyerror("out of memory");
1951 return NULL;
1952 }
1953 memset(new, 0, sizeof(role_datum_t));
1954 new->s.value = 0; /* temporary role */
1955 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
1956 yyerror("out of memory");
1957 return NULL;
1958 }
1959 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
1960 yyerror("out of memory");
1961 return NULL;
1962 }
1963 if (!r1->s.value) {
1964 /* free intermediate result */
1965 type_set_destroy(&r1->types);
1966 ebitmap_destroy(&r1->dominates);
1967 free(r1);
1968 }
1969 if (!r2->s.value) {
1970 /* free intermediate result */
1971 yyerror("right hand role is temporary?");
1972 type_set_destroy(&r2->types);
1973 ebitmap_destroy(&r2->dominates);
1974 free(r2);
1975 }
1976 return new;
1977 }
1978
1979 /* This function eliminates the ordering dependency of role dominance rule */
dominate_role_recheck(hashtab_key_t key,hashtab_datum_t datum,void * arg)1980 static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
1981 void *arg)
1982 {
1983 role_datum_t *rdp = (role_datum_t *) arg;
1984 role_datum_t *rdatum = (role_datum_t *) datum;
1985 ebitmap_node_t *node;
1986 int i;
1987
1988 /* Don't bother to process against self role */
1989 if (rdatum->s.value == rdp->s.value)
1990 return 0;
1991
1992 /* If a dominating role found */
1993 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
1994 ebitmap_t types;
1995 ebitmap_init(&types);
1996 if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
1997 ebitmap_destroy(&types);
1998 return -1;
1999 }
2000 /* raise types and dominates from dominated role */
2001 ebitmap_for_each_bit(&rdp->dominates, node, i) {
2002 if (ebitmap_node_get_bit(node, i))
2003 if (ebitmap_set_bit
2004 (&rdatum->dominates, i, TRUE))
2005 goto oom;
2006 }
2007 ebitmap_for_each_bit(&types, node, i) {
2008 if (ebitmap_node_get_bit(node, i))
2009 if (ebitmap_set_bit
2010 (&rdatum->types.types, i, TRUE))
2011 goto oom;
2012 }
2013 ebitmap_destroy(&types);
2014 }
2015
2016 /* go through all the roles */
2017 return 0;
2018 oom:
2019 yyerror("Out of memory");
2020 return -1;
2021 }
2022
define_role_dom(role_datum_t * r)2023 role_datum_t *define_role_dom(role_datum_t * r)
2024 {
2025 role_datum_t *role;
2026 char *role_id;
2027 ebitmap_node_t *node;
2028 unsigned int i;
2029 int ret;
2030
2031 if (pass == 1) {
2032 role_id = queue_remove(id_queue);
2033 free(role_id);
2034 return (role_datum_t *) 1; /* any non-NULL value */
2035 }
2036
2037 yywarn("Role dominance has been deprecated");
2038
2039 role_id = queue_remove(id_queue);
2040 if (!is_id_in_scope(SYM_ROLES, role_id)) {
2041 yyerror2("role %s is not within scope", role_id);
2042 free(role_id);
2043 return NULL;
2044 }
2045 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2046 role_id);
2047 if (!role) {
2048 role = (role_datum_t *) malloc(sizeof(role_datum_t));
2049 if (!role) {
2050 yyerror("out of memory");
2051 free(role_id);
2052 return NULL;
2053 }
2054 memset(role, 0, sizeof(role_datum_t));
2055 ret =
2056 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2057 (hashtab_datum_t) role, &role->s.value,
2058 &role->s.value);
2059 switch (ret) {
2060 case -3:{
2061 yyerror("Out of memory!");
2062 goto cleanup;
2063 }
2064 case -2:{
2065 yyerror2("duplicate declaration of role %s",
2066 role_id);
2067 goto cleanup;
2068 }
2069 case -1:{
2070 yyerror("could not declare role here");
2071 goto cleanup;
2072 }
2073 case 0:
2074 case 1:{
2075 break;
2076 }
2077 default:{
2078 assert(0); /* should never get here */
2079 }
2080 }
2081 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
2082 yyerror("Out of memory!");
2083 goto cleanup;
2084 }
2085 }
2086 if (r) {
2087 ebitmap_t types;
2088 ebitmap_init(&types);
2089 ebitmap_for_each_bit(&r->dominates, node, i) {
2090 if (ebitmap_node_get_bit(node, i))
2091 if (ebitmap_set_bit(&role->dominates, i, TRUE))
2092 goto oom;
2093 }
2094 if (type_set_expand(&r->types, &types, policydbp, 1)) {
2095 ebitmap_destroy(&types);
2096 return NULL;
2097 }
2098 ebitmap_for_each_bit(&types, node, i) {
2099 if (ebitmap_node_get_bit(node, i))
2100 if (ebitmap_set_bit
2101 (&role->types.types, i, TRUE))
2102 goto oom;
2103 }
2104 ebitmap_destroy(&types);
2105 if (!r->s.value) {
2106 /* free intermediate result */
2107 type_set_destroy(&r->types);
2108 ebitmap_destroy(&r->dominates);
2109 free(r);
2110 }
2111 /*
2112 * Now go through all the roles and escalate this role's
2113 * dominates and types if a role dominates this role.
2114 */
2115 hashtab_map(policydbp->p_roles.table,
2116 dominate_role_recheck, role);
2117 }
2118 return role;
2119 cleanup:
2120 free(role_id);
2121 role_datum_destroy(role);
2122 free(role);
2123 return NULL;
2124 oom:
2125 yyerror("Out of memory");
2126 goto cleanup;
2127 }
2128
role_val_to_name_helper(hashtab_key_t key,hashtab_datum_t datum,void * p)2129 static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2130 void *p)
2131 {
2132 struct val_to_name *v = p;
2133 role_datum_t *roldatum;
2134
2135 roldatum = (role_datum_t *) datum;
2136
2137 if (v->val == roldatum->s.value) {
2138 v->name = key;
2139 return 1;
2140 }
2141
2142 return 0;
2143 }
2144
role_val_to_name(unsigned int val)2145 static char *role_val_to_name(unsigned int val)
2146 {
2147 struct val_to_name v;
2148 int rc;
2149
2150 v.val = val;
2151 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2152 if (rc)
2153 return v.name;
2154 return NULL;
2155 }
2156
set_roles(role_set_t * set,char * id)2157 static int set_roles(role_set_t * set, char *id)
2158 {
2159 role_datum_t *r;
2160
2161 if (strcmp(id, "*") == 0) {
2162 free(id);
2163 yyerror("* is not allowed for role sets");
2164 return -1;
2165 }
2166
2167 if (strcmp(id, "~") == 0) {
2168 free(id);
2169 yyerror("~ is not allowed for role sets");
2170 return -1;
2171 }
2172 if (!is_id_in_scope(SYM_ROLES, id)) {
2173 yyerror2("role %s is not within scope", id);
2174 free(id);
2175 return -1;
2176 }
2177 r = hashtab_search(policydbp->p_roles.table, id);
2178 if (!r) {
2179 yyerror2("unknown role %s", id);
2180 free(id);
2181 return -1;
2182 }
2183
2184 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2185 yyerror("out of memory");
2186 free(id);
2187 return -1;
2188 }
2189 free(id);
2190 return 0;
2191 }
2192
define_role_trans(int class_specified)2193 int define_role_trans(int class_specified)
2194 {
2195 char *id;
2196 role_datum_t *role;
2197 role_set_t roles;
2198 type_set_t types;
2199 class_datum_t *cladatum;
2200 ebitmap_t e_types, e_roles, e_classes;
2201 ebitmap_node_t *tnode, *rnode, *cnode;
2202 struct role_trans *tr = NULL;
2203 struct role_trans_rule *rule = NULL;
2204 unsigned int i, j, k;
2205 int add = 1;
2206
2207 if (pass == 1) {
2208 while ((id = queue_remove(id_queue)))
2209 free(id);
2210 while ((id = queue_remove(id_queue)))
2211 free(id);
2212 if (class_specified)
2213 while ((id = queue_remove(id_queue)))
2214 free(id);
2215 id = queue_remove(id_queue);
2216 free(id);
2217 return 0;
2218 }
2219
2220 role_set_init(&roles);
2221 ebitmap_init(&e_roles);
2222 type_set_init(&types);
2223 ebitmap_init(&e_types);
2224 ebitmap_init(&e_classes);
2225
2226 while ((id = queue_remove(id_queue))) {
2227 if (set_roles(&roles, id))
2228 return -1;
2229 }
2230 add = 1;
2231 while ((id = queue_remove(id_queue))) {
2232 if (set_types(&types, id, &add, 0))
2233 return -1;
2234 }
2235
2236 if (class_specified) {
2237 if (read_classes(&e_classes))
2238 return -1;
2239 } else {
2240 cladatum = hashtab_search(policydbp->p_classes.table,
2241 "process");
2242 if (!cladatum) {
2243 yyerror2("could not find process class for "
2244 "legacy role_transition statement");
2245 return -1;
2246 }
2247
2248 ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE);
2249 }
2250
2251 id = (char *)queue_remove(id_queue);
2252 if (!id) {
2253 yyerror("no new role in transition definition?");
2254 goto bad;
2255 }
2256 if (!is_id_in_scope(SYM_ROLES, id)) {
2257 yyerror2("role %s is not within scope", id);
2258 free(id);
2259 goto bad;
2260 }
2261 role = hashtab_search(policydbp->p_roles.table, id);
2262 if (!role) {
2263 yyerror2("unknown role %s used in transition definition", id);
2264 goto bad;
2265 }
2266
2267 if (role->flavor != ROLE_ROLE) {
2268 yyerror2("the new role %s must be a regular role", id);
2269 goto bad;
2270 }
2271
2272 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
2273 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
2274 goto bad;
2275
2276 if (type_set_expand(&types, &e_types, policydbp, 1))
2277 goto bad;
2278
2279 ebitmap_for_each_bit(&e_roles, rnode, i) {
2280 if (!ebitmap_node_get_bit(rnode, i))
2281 continue;
2282 ebitmap_for_each_bit(&e_types, tnode, j) {
2283 if (!ebitmap_node_get_bit(tnode, j))
2284 continue;
2285 ebitmap_for_each_bit(&e_classes, cnode, k) {
2286 if (!ebitmap_node_get_bit(cnode, k))
2287 continue;
2288 for (tr = policydbp->role_tr; tr;
2289 tr = tr->next) {
2290 if (tr->role == (i + 1) &&
2291 tr->type == (j + 1) &&
2292 tr->tclass == (k + 1)) {
2293 yyerror2("duplicate role "
2294 "transition for "
2295 "(%s,%s,%s)",
2296 role_val_to_name(i+1),
2297 policydbp->p_type_val_to_name[j],
2298 policydbp->p_class_val_to_name[k]);
2299 goto bad;
2300 }
2301 }
2302
2303 tr = malloc(sizeof(struct role_trans));
2304 if (!tr) {
2305 yyerror("out of memory");
2306 return -1;
2307 }
2308 memset(tr, 0, sizeof(struct role_trans));
2309 tr->role = i + 1;
2310 tr->type = j + 1;
2311 tr->tclass = k + 1;
2312 tr->new_role = role->s.value;
2313 tr->next = policydbp->role_tr;
2314 policydbp->role_tr = tr;
2315 }
2316 }
2317 }
2318 /* Now add the real rule */
2319 rule = malloc(sizeof(struct role_trans_rule));
2320 if (!rule) {
2321 yyerror("out of memory");
2322 return -1;
2323 }
2324 memset(rule, 0, sizeof(struct role_trans_rule));
2325 rule->roles = roles;
2326 rule->types = types;
2327 rule->classes = e_classes;
2328 rule->new_role = role->s.value;
2329
2330 append_role_trans(rule);
2331
2332 ebitmap_destroy(&e_roles);
2333 ebitmap_destroy(&e_types);
2334
2335 return 0;
2336
2337 bad:
2338 return -1;
2339 }
2340
define_role_allow(void)2341 int define_role_allow(void)
2342 {
2343 char *id;
2344 struct role_allow_rule *ra = 0;
2345
2346 if (pass == 1) {
2347 while ((id = queue_remove(id_queue)))
2348 free(id);
2349 while ((id = queue_remove(id_queue)))
2350 free(id);
2351 return 0;
2352 }
2353
2354 ra = malloc(sizeof(role_allow_rule_t));
2355 if (!ra) {
2356 yyerror("out of memory");
2357 return -1;
2358 }
2359 role_allow_rule_init(ra);
2360
2361 while ((id = queue_remove(id_queue))) {
2362 if (set_roles(&ra->roles, id))
2363 return -1;
2364 }
2365
2366 while ((id = queue_remove(id_queue))) {
2367 if (set_roles(&ra->new_roles, id))
2368 return -1;
2369 }
2370
2371 append_role_allow(ra);
2372 return 0;
2373 }
2374
define_cond_filename_trans(void)2375 avrule_t *define_cond_filename_trans(void)
2376 {
2377 yyerror("type transitions with a filename not allowed inside "
2378 "conditionals\n");
2379 return COND_ERR;
2380 }
2381
define_filename_trans(void)2382 int define_filename_trans(void)
2383 {
2384 char *id, *name = NULL;
2385 type_set_t stypes, ttypes;
2386 ebitmap_t e_stypes, e_ttypes;
2387 ebitmap_t e_tclasses;
2388 ebitmap_node_t *snode, *tnode, *cnode;
2389 filename_trans_t *ft;
2390 filename_trans_rule_t *ftr;
2391 type_datum_t *typdatum;
2392 uint32_t otype;
2393 unsigned int c, s, t;
2394 int add;
2395
2396 if (pass == 1) {
2397 /* stype */
2398 while ((id = queue_remove(id_queue)))
2399 free(id);
2400 /* ttype */
2401 while ((id = queue_remove(id_queue)))
2402 free(id);
2403 /* tclass */
2404 while ((id = queue_remove(id_queue)))
2405 free(id);
2406 /* otype */
2407 id = queue_remove(id_queue);
2408 free(id);
2409 /* name */
2410 id = queue_remove(id_queue);
2411 free(id);
2412 return 0;
2413 }
2414
2415
2416 add = 1;
2417 type_set_init(&stypes);
2418 while ((id = queue_remove(id_queue))) {
2419 if (set_types(&stypes, id, &add, 0))
2420 goto bad;
2421 }
2422
2423 add =1;
2424 type_set_init(&ttypes);
2425 while ((id = queue_remove(id_queue))) {
2426 if (set_types(&ttypes, id, &add, 0))
2427 goto bad;
2428 }
2429
2430 ebitmap_init(&e_tclasses);
2431 if (read_classes(&e_tclasses))
2432 goto bad;
2433
2434 id = (char *)queue_remove(id_queue);
2435 if (!id) {
2436 yyerror("no otype in transition definition?");
2437 goto bad;
2438 }
2439 if (!is_id_in_scope(SYM_TYPES, id)) {
2440 yyerror2("type %s is not within scope", id);
2441 free(id);
2442 goto bad;
2443 }
2444 typdatum = hashtab_search(policydbp->p_types.table, id);
2445 if (!typdatum) {
2446 yyerror2("unknown type %s used in transition definition", id);
2447 goto bad;
2448 }
2449 free(id);
2450 otype = typdatum->s.value;
2451
2452 name = queue_remove(id_queue);
2453 if (!name) {
2454 yyerror("no pathname specified in filename_trans definition?");
2455 goto bad;
2456 }
2457
2458 /* We expand the class set into seperate rules. We expand the types
2459 * just to make sure there are not duplicates. They will get turned
2460 * into seperate rules later */
2461 ebitmap_init(&e_stypes);
2462 if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
2463 goto bad;
2464
2465 ebitmap_init(&e_ttypes);
2466 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
2467 goto bad;
2468
2469 ebitmap_for_each_bit(&e_tclasses, cnode, c) {
2470 if (!ebitmap_node_get_bit(cnode, c))
2471 continue;
2472 ebitmap_for_each_bit(&e_stypes, snode, s) {
2473 if (!ebitmap_node_get_bit(snode, s))
2474 continue;
2475 ebitmap_for_each_bit(&e_ttypes, tnode, t) {
2476 if (!ebitmap_node_get_bit(tnode, t))
2477 continue;
2478
2479 for (ft = policydbp->filename_trans; ft; ft = ft->next) {
2480 if (ft->stype == (s + 1) &&
2481 ft->ttype == (t + 1) &&
2482 ft->tclass == (c + 1) &&
2483 !strcmp(ft->name, name)) {
2484 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
2485 name,
2486 policydbp->p_type_val_to_name[s],
2487 policydbp->p_type_val_to_name[t],
2488 policydbp->p_class_val_to_name[c]);
2489 goto bad;
2490 }
2491 }
2492
2493 ft = malloc(sizeof(*ft));
2494 if (!ft) {
2495 yyerror("out of memory");
2496 goto bad;
2497 }
2498 memset(ft, 0, sizeof(*ft));
2499
2500 ft->next = policydbp->filename_trans;
2501 policydbp->filename_trans = ft;
2502
2503 ft->name = strdup(name);
2504 if (!ft->name) {
2505 yyerror("out of memory");
2506 goto bad;
2507 }
2508 ft->stype = s + 1;
2509 ft->ttype = t + 1;
2510 ft->tclass = c + 1;
2511 ft->otype = otype;
2512 }
2513 }
2514
2515 /* Now add the real rule since we didn't find any duplicates */
2516 ftr = malloc(sizeof(*ftr));
2517 if (!ftr) {
2518 yyerror("out of memory");
2519 goto bad;
2520 }
2521 filename_trans_rule_init(ftr);
2522 append_filename_trans(ftr);
2523
2524 ftr->name = strdup(name);
2525 ftr->stypes = stypes;
2526 ftr->ttypes = ttypes;
2527 ftr->tclass = c + 1;
2528 ftr->otype = otype;
2529 }
2530
2531 free(name);
2532 ebitmap_destroy(&e_stypes);
2533 ebitmap_destroy(&e_ttypes);
2534 ebitmap_destroy(&e_tclasses);
2535
2536 return 0;
2537
2538 bad:
2539 free(name);
2540 return -1;
2541 }
2542
constraint_expr_clone(constraint_expr_t * expr)2543 static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
2544 {
2545 constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
2546 for (e = expr; e; e = e->next) {
2547 newe = malloc(sizeof(*newe));
2548 if (!newe)
2549 goto oom;
2550 if (constraint_expr_init(newe) == -1) {
2551 free(newe);
2552 goto oom;
2553 }
2554 if (l)
2555 l->next = newe;
2556 else
2557 h = newe;
2558 l = newe;
2559 newe->expr_type = e->expr_type;
2560 newe->attr = e->attr;
2561 newe->op = e->op;
2562 if (newe->expr_type == CEXPR_NAMES) {
2563 if (newe->attr & CEXPR_TYPE) {
2564 if (type_set_cpy
2565 (newe->type_names, e->type_names))
2566 goto oom;
2567 } else {
2568 if (ebitmap_cpy(&newe->names, &e->names))
2569 goto oom;
2570 }
2571 }
2572 }
2573
2574 return h;
2575 oom:
2576 e = h;
2577 while (e) {
2578 l = e;
2579 e = e->next;
2580 constraint_expr_destroy(l);
2581 }
2582 return NULL;
2583 }
2584
define_constraint(constraint_expr_t * expr)2585 int define_constraint(constraint_expr_t * expr)
2586 {
2587 struct constraint_node *node;
2588 char *id;
2589 class_datum_t *cladatum;
2590 perm_datum_t *perdatum;
2591 ebitmap_t classmap;
2592 ebitmap_node_t *enode;
2593 constraint_expr_t *e;
2594 unsigned int i;
2595 int depth;
2596 unsigned char useexpr = 1;
2597
2598 if (pass == 1) {
2599 while ((id = queue_remove(id_queue)))
2600 free(id);
2601 while ((id = queue_remove(id_queue)))
2602 free(id);
2603 return 0;
2604 }
2605
2606 depth = -1;
2607 for (e = expr; e; e = e->next) {
2608 switch (e->expr_type) {
2609 case CEXPR_NOT:
2610 if (depth < 0) {
2611 yyerror("illegal constraint expression");
2612 return -1;
2613 }
2614 break;
2615 case CEXPR_AND:
2616 case CEXPR_OR:
2617 if (depth < 1) {
2618 yyerror("illegal constraint expression");
2619 return -1;
2620 }
2621 depth--;
2622 break;
2623 case CEXPR_ATTR:
2624 case CEXPR_NAMES:
2625 if (e->attr & CEXPR_XTARGET) {
2626 yyerror("illegal constraint expression");
2627 return -1; /* only for validatetrans rules */
2628 }
2629 if (depth == (CEXPR_MAXDEPTH - 1)) {
2630 yyerror("constraint expression is too deep");
2631 return -1;
2632 }
2633 depth++;
2634 break;
2635 default:
2636 yyerror("illegal constraint expression");
2637 return -1;
2638 }
2639 }
2640 if (depth != 0) {
2641 yyerror("illegal constraint expression");
2642 return -1;
2643 }
2644
2645 ebitmap_init(&classmap);
2646 while ((id = queue_remove(id_queue))) {
2647 if (!is_id_in_scope(SYM_CLASSES, id)) {
2648 yyerror2("class %s is not within scope", id);
2649 free(id);
2650 return -1;
2651 }
2652 cladatum =
2653 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2654 (hashtab_key_t) id);
2655 if (!cladatum) {
2656 yyerror2("class %s is not defined", id);
2657 ebitmap_destroy(&classmap);
2658 free(id);
2659 return -1;
2660 }
2661 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
2662 yyerror("out of memory");
2663 ebitmap_destroy(&classmap);
2664 free(id);
2665 return -1;
2666 }
2667 node = malloc(sizeof(struct constraint_node));
2668 if (!node) {
2669 yyerror("out of memory");
2670 return -1;
2671 }
2672 memset(node, 0, sizeof(constraint_node_t));
2673 if (useexpr) {
2674 node->expr = expr;
2675 useexpr = 0;
2676 } else {
2677 node->expr = constraint_expr_clone(expr);
2678 }
2679 if (!node->expr) {
2680 yyerror("out of memory");
2681 return -1;
2682 }
2683 node->permissions = 0;
2684
2685 node->next = cladatum->constraints;
2686 cladatum->constraints = node;
2687
2688 free(id);
2689 }
2690
2691 while ((id = queue_remove(id_queue))) {
2692 ebitmap_for_each_bit(&classmap, enode, i) {
2693 if (ebitmap_node_get_bit(enode, i)) {
2694 cladatum = policydbp->class_val_to_struct[i];
2695 node = cladatum->constraints;
2696
2697 perdatum =
2698 (perm_datum_t *) hashtab_search(cladatum->
2699 permissions.
2700 table,
2701 (hashtab_key_t)
2702 id);
2703 if (!perdatum) {
2704 if (cladatum->comdatum) {
2705 perdatum =
2706 (perm_datum_t *)
2707 hashtab_search(cladatum->
2708 comdatum->
2709 permissions.
2710 table,
2711 (hashtab_key_t)
2712 id);
2713 }
2714 if (!perdatum) {
2715 yyerror2("permission %s is not"
2716 " defined", id);
2717 free(id);
2718 ebitmap_destroy(&classmap);
2719 return -1;
2720 }
2721 }
2722 node->permissions |=
2723 (1 << (perdatum->s.value - 1));
2724 }
2725 }
2726 free(id);
2727 }
2728
2729 ebitmap_destroy(&classmap);
2730
2731 return 0;
2732 }
2733
define_validatetrans(constraint_expr_t * expr)2734 int define_validatetrans(constraint_expr_t * expr)
2735 {
2736 struct constraint_node *node;
2737 char *id;
2738 class_datum_t *cladatum;
2739 ebitmap_t classmap;
2740 constraint_expr_t *e;
2741 int depth;
2742 unsigned char useexpr = 1;
2743
2744 if (pass == 1) {
2745 while ((id = queue_remove(id_queue)))
2746 free(id);
2747 return 0;
2748 }
2749
2750 depth = -1;
2751 for (e = expr; e; e = e->next) {
2752 switch (e->expr_type) {
2753 case CEXPR_NOT:
2754 if (depth < 0) {
2755 yyerror("illegal validatetrans expression");
2756 return -1;
2757 }
2758 break;
2759 case CEXPR_AND:
2760 case CEXPR_OR:
2761 if (depth < 1) {
2762 yyerror("illegal validatetrans expression");
2763 return -1;
2764 }
2765 depth--;
2766 break;
2767 case CEXPR_ATTR:
2768 case CEXPR_NAMES:
2769 if (depth == (CEXPR_MAXDEPTH - 1)) {
2770 yyerror("validatetrans expression is too deep");
2771 return -1;
2772 }
2773 depth++;
2774 break;
2775 default:
2776 yyerror("illegal validatetrans expression");
2777 return -1;
2778 }
2779 }
2780 if (depth != 0) {
2781 yyerror("illegal validatetrans expression");
2782 return -1;
2783 }
2784
2785 ebitmap_init(&classmap);
2786 while ((id = queue_remove(id_queue))) {
2787 if (!is_id_in_scope(SYM_CLASSES, id)) {
2788 yyerror2("class %s is not within scope", id);
2789 free(id);
2790 return -1;
2791 }
2792 cladatum =
2793 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2794 (hashtab_key_t) id);
2795 if (!cladatum) {
2796 yyerror2("class %s is not defined", id);
2797 ebitmap_destroy(&classmap);
2798 free(id);
2799 return -1;
2800 }
2801 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
2802 yyerror("out of memory");
2803 ebitmap_destroy(&classmap);
2804 free(id);
2805 return -1;
2806 }
2807
2808 node = malloc(sizeof(struct constraint_node));
2809 if (!node) {
2810 yyerror("out of memory");
2811 return -1;
2812 }
2813 memset(node, 0, sizeof(constraint_node_t));
2814 if (useexpr) {
2815 node->expr = expr;
2816 useexpr = 0;
2817 } else {
2818 node->expr = constraint_expr_clone(expr);
2819 }
2820 node->permissions = 0;
2821
2822 node->next = cladatum->validatetrans;
2823 cladatum->validatetrans = node;
2824
2825 free(id);
2826 }
2827
2828 ebitmap_destroy(&classmap);
2829
2830 return 0;
2831 }
2832
define_cexpr(uint32_t expr_type,uintptr_t arg1,uintptr_t arg2)2833 uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
2834 {
2835 struct constraint_expr *expr, *e1 = NULL, *e2;
2836 user_datum_t *user;
2837 role_datum_t *role;
2838 ebitmap_t negset;
2839 char *id;
2840 uint32_t val;
2841 int add = 1;
2842
2843 if (pass == 1) {
2844 if (expr_type == CEXPR_NAMES) {
2845 while ((id = queue_remove(id_queue)))
2846 free(id);
2847 }
2848 return 1; /* any non-NULL value */
2849 }
2850
2851 if ((expr = malloc(sizeof(*expr))) == NULL ||
2852 constraint_expr_init(expr) == -1) {
2853 yyerror("out of memory");
2854 free(expr);
2855 return 0;
2856 }
2857 expr->expr_type = expr_type;
2858
2859 switch (expr_type) {
2860 case CEXPR_NOT:
2861 e1 = NULL;
2862 e2 = (struct constraint_expr *)arg1;
2863 while (e2) {
2864 e1 = e2;
2865 e2 = e2->next;
2866 }
2867 if (!e1 || e1->next) {
2868 yyerror("illegal constraint expression");
2869 constraint_expr_destroy(expr);
2870 return 0;
2871 }
2872 e1->next = expr;
2873 return arg1;
2874 case CEXPR_AND:
2875 case CEXPR_OR:
2876 e1 = NULL;
2877 e2 = (struct constraint_expr *)arg1;
2878 while (e2) {
2879 e1 = e2;
2880 e2 = e2->next;
2881 }
2882 if (!e1 || e1->next) {
2883 yyerror("illegal constraint expression");
2884 constraint_expr_destroy(expr);
2885 return 0;
2886 }
2887 e1->next = (struct constraint_expr *)arg2;
2888
2889 e1 = NULL;
2890 e2 = (struct constraint_expr *)arg2;
2891 while (e2) {
2892 e1 = e2;
2893 e2 = e2->next;
2894 }
2895 if (!e1 || e1->next) {
2896 yyerror("illegal constraint expression");
2897 constraint_expr_destroy(expr);
2898 return 0;
2899 }
2900 e1->next = expr;
2901 return arg1;
2902 case CEXPR_ATTR:
2903 expr->attr = arg1;
2904 expr->op = arg2;
2905 return (uintptr_t) expr;
2906 case CEXPR_NAMES:
2907 add = 1;
2908 expr->attr = arg1;
2909 expr->op = arg2;
2910 ebitmap_init(&negset);
2911 while ((id = (char *)queue_remove(id_queue))) {
2912 if (expr->attr & CEXPR_USER) {
2913 if (!is_id_in_scope(SYM_USERS, id)) {
2914 yyerror2("user %s is not within scope",
2915 id);
2916 constraint_expr_destroy(expr);
2917 return 0;
2918 }
2919 user =
2920 (user_datum_t *) hashtab_search(policydbp->
2921 p_users.
2922 table,
2923 (hashtab_key_t)
2924 id);
2925 if (!user) {
2926 yyerror2("unknown user %s", id);
2927 constraint_expr_destroy(expr);
2928 return 0;
2929 }
2930 val = user->s.value;
2931 } else if (expr->attr & CEXPR_ROLE) {
2932 if (!is_id_in_scope(SYM_ROLES, id)) {
2933 yyerror2("role %s is not within scope",
2934 id);
2935 constraint_expr_destroy(expr);
2936 return 0;
2937 }
2938 role =
2939 (role_datum_t *) hashtab_search(policydbp->
2940 p_roles.
2941 table,
2942 (hashtab_key_t)
2943 id);
2944 if (!role) {
2945 yyerror2("unknown role %s", id);
2946 constraint_expr_destroy(expr);
2947 return 0;
2948 }
2949 val = role->s.value;
2950 } else if (expr->attr & CEXPR_TYPE) {
2951 if (set_types(expr->type_names, id, &add, 0)) {
2952 constraint_expr_destroy(expr);
2953 return 0;
2954 }
2955 continue;
2956 } else {
2957 yyerror("invalid constraint expression");
2958 constraint_expr_destroy(expr);
2959 return 0;
2960 }
2961 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
2962 yyerror("out of memory");
2963 ebitmap_destroy(&expr->names);
2964 constraint_expr_destroy(expr);
2965 return 0;
2966 }
2967 free(id);
2968 }
2969 ebitmap_destroy(&negset);
2970 return (uintptr_t) expr;
2971 default:
2972 yyerror("invalid constraint expression");
2973 constraint_expr_destroy(expr);
2974 return 0;
2975 }
2976
2977 yyerror("invalid constraint expression");
2978 free(expr);
2979 return 0;
2980 }
2981
define_conditional(cond_expr_t * expr,avrule_t * t,avrule_t * f)2982 int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
2983 {
2984 cond_expr_t *e;
2985 int depth;
2986 cond_node_t cn, *cn_old;
2987
2988 /* expression cannot be NULL */
2989 if (!expr) {
2990 yyerror("illegal conditional expression");
2991 return -1;
2992 }
2993 if (!t) {
2994 if (!f) {
2995 /* empty is fine, destroy expression and return */
2996 cond_expr_destroy(expr);
2997 return 0;
2998 }
2999 /* Invert */
3000 t = f;
3001 f = 0;
3002 expr = define_cond_expr(COND_NOT, expr, 0);
3003 if (!expr) {
3004 yyerror("unable to invert");
3005 return -1;
3006 }
3007 }
3008
3009 /* verify expression */
3010 depth = -1;
3011 for (e = expr; e; e = e->next) {
3012 switch (e->expr_type) {
3013 case COND_NOT:
3014 if (depth < 0) {
3015 yyerror
3016 ("illegal conditional expression; Bad NOT");
3017 return -1;
3018 }
3019 break;
3020 case COND_AND:
3021 case COND_OR:
3022 case COND_XOR:
3023 case COND_EQ:
3024 case COND_NEQ:
3025 if (depth < 1) {
3026 yyerror
3027 ("illegal conditional expression; Bad binary op");
3028 return -1;
3029 }
3030 depth--;
3031 break;
3032 case COND_BOOL:
3033 if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3034 yyerror
3035 ("conditional expression is like totally too deep");
3036 return -1;
3037 }
3038 depth++;
3039 break;
3040 default:
3041 yyerror("illegal conditional expression");
3042 return -1;
3043 }
3044 }
3045 if (depth != 0) {
3046 yyerror("illegal conditional expression");
3047 return -1;
3048 }
3049
3050 /* use tmp conditional node to partially build new node */
3051 memset(&cn, 0, sizeof(cn));
3052 cn.expr = expr;
3053 cn.avtrue_list = t;
3054 cn.avfalse_list = f;
3055
3056 /* normalize/precompute expression */
3057 if (cond_normalize_expr(policydbp, &cn) < 0) {
3058 yyerror("problem normalizing conditional expression");
3059 return -1;
3060 }
3061
3062 /* get the existing conditional node, or create a new one */
3063 cn_old = get_current_cond_list(&cn);
3064 if (!cn_old) {
3065 return -1;
3066 }
3067
3068 append_cond_list(&cn);
3069
3070 /* note that there is no check here for duplicate rules, nor
3071 * check that rule already exists in base -- that will be
3072 * handled during conditional expansion, in expand.c */
3073
3074 cn.avtrue_list = NULL;
3075 cn.avfalse_list = NULL;
3076 cond_node_destroy(&cn);
3077
3078 return 0;
3079 }
3080
define_cond_expr(uint32_t expr_type,void * arg1,void * arg2)3081 cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3082 {
3083 struct cond_expr *expr, *e1 = NULL, *e2;
3084 cond_bool_datum_t *bool_var;
3085 char *id;
3086
3087 /* expressions are handled in the second pass */
3088 if (pass == 1) {
3089 if (expr_type == COND_BOOL) {
3090 while ((id = queue_remove(id_queue))) {
3091 free(id);
3092 }
3093 }
3094 return (cond_expr_t *) 1; /* any non-NULL value */
3095 }
3096
3097 /* create a new expression struct */
3098 expr = malloc(sizeof(struct cond_expr));
3099 if (!expr) {
3100 yyerror("out of memory");
3101 return NULL;
3102 }
3103 memset(expr, 0, sizeof(cond_expr_t));
3104 expr->expr_type = expr_type;
3105
3106 /* create the type asked for */
3107 switch (expr_type) {
3108 case COND_NOT:
3109 e1 = NULL;
3110 e2 = (struct cond_expr *)arg1;
3111 while (e2) {
3112 e1 = e2;
3113 e2 = e2->next;
3114 }
3115 if (!e1 || e1->next) {
3116 yyerror("illegal conditional NOT expression");
3117 free(expr);
3118 return NULL;
3119 }
3120 e1->next = expr;
3121 return (struct cond_expr *)arg1;
3122 case COND_AND:
3123 case COND_OR:
3124 case COND_XOR:
3125 case COND_EQ:
3126 case COND_NEQ:
3127 e1 = NULL;
3128 e2 = (struct cond_expr *)arg1;
3129 while (e2) {
3130 e1 = e2;
3131 e2 = e2->next;
3132 }
3133 if (!e1 || e1->next) {
3134 yyerror
3135 ("illegal left side of conditional binary op expression");
3136 free(expr);
3137 return NULL;
3138 }
3139 e1->next = (struct cond_expr *)arg2;
3140
3141 e1 = NULL;
3142 e2 = (struct cond_expr *)arg2;
3143 while (e2) {
3144 e1 = e2;
3145 e2 = e2->next;
3146 }
3147 if (!e1 || e1->next) {
3148 yyerror
3149 ("illegal right side of conditional binary op expression");
3150 free(expr);
3151 return NULL;
3152 }
3153 e1->next = expr;
3154 return (struct cond_expr *)arg1;
3155 case COND_BOOL:
3156 id = (char *)queue_remove(id_queue);
3157 if (!id) {
3158 yyerror("bad conditional; expected boolean id");
3159 free(id);
3160 free(expr);
3161 return NULL;
3162 }
3163 if (!is_id_in_scope(SYM_BOOLS, id)) {
3164 yyerror2("boolean %s is not within scope", id);
3165 free(id);
3166 free(expr);
3167 return NULL;
3168 }
3169 bool_var =
3170 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
3171 table,
3172 (hashtab_key_t) id);
3173 if (!bool_var) {
3174 yyerror2("unknown boolean %s in conditional expression",
3175 id);
3176 free(expr);
3177 free(id);
3178 return NULL;
3179 }
3180 expr->bool = bool_var->s.value;
3181 free(id);
3182 return expr;
3183 default:
3184 yyerror("illegal conditional expression");
3185 return NULL;
3186 }
3187 }
3188
set_user_roles(role_set_t * set,char * id)3189 static int set_user_roles(role_set_t * set, char *id)
3190 {
3191 role_datum_t *r;
3192 unsigned int i;
3193 ebitmap_node_t *node;
3194
3195 if (strcmp(id, "*") == 0) {
3196 free(id);
3197 yyerror("* is not allowed in user declarations");
3198 return -1;
3199 }
3200
3201 if (strcmp(id, "~") == 0) {
3202 free(id);
3203 yyerror("~ is not allowed in user declarations");
3204 return -1;
3205 }
3206
3207 if (!is_id_in_scope(SYM_ROLES, id)) {
3208 yyerror2("role %s is not within scope", id);
3209 free(id);
3210 return -1;
3211 }
3212 r = hashtab_search(policydbp->p_roles.table, id);
3213 if (!r) {
3214 yyerror2("unknown role %s", id);
3215 free(id);
3216 return -1;
3217 }
3218
3219 /* set the role and every role it dominates */
3220 ebitmap_for_each_bit(&r->dominates, node, i) {
3221 if (ebitmap_node_get_bit(node, i))
3222 if (ebitmap_set_bit(&set->roles, i, TRUE))
3223 goto oom;
3224 }
3225 free(id);
3226 return 0;
3227 oom:
3228 yyerror("out of memory");
3229 return -1;
3230 }
3231
parse_categories(char * id,level_datum_t * levdatum,ebitmap_t * cats)3232 static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
3233 {
3234 cat_datum_t *cdatum;
3235 int range_start, range_end, i;
3236
3237 if (id_has_dot(id)) {
3238 char *id_start = id;
3239 char *id_end = strchr(id, '.');
3240
3241 *(id_end++) = '\0';
3242
3243 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3244 (hashtab_key_t)
3245 id_start);
3246 if (!cdatum) {
3247 yyerror2("unknown category %s", id_start);
3248 return -1;
3249 }
3250 range_start = cdatum->s.value - 1;
3251 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3252 (hashtab_key_t) id_end);
3253 if (!cdatum) {
3254 yyerror2("unknown category %s", id_end);
3255 return -1;
3256 }
3257 range_end = cdatum->s.value - 1;
3258
3259 if (range_end < range_start) {
3260 yyerror2("category range is invalid");
3261 return -1;
3262 }
3263 } else {
3264 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3265 (hashtab_key_t) id);
3266 if (!cdatum) {
3267 yyerror2("unknown category %s", id);
3268 return -1;
3269 }
3270 range_start = range_end = cdatum->s.value - 1;
3271 }
3272
3273 for (i = range_start; i <= range_end; i++) {
3274 if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
3275 uint32_t level_value = levdatum->level->sens - 1;
3276 policydb_index_others(NULL, policydbp, 0);
3277 yyerror2("category %s can not be associated "
3278 "with level %s",
3279 policydbp->p_cat_val_to_name[i],
3280 policydbp->p_sens_val_to_name[level_value]);
3281 return -1;
3282 }
3283 if (ebitmap_set_bit(cats, i, TRUE)) {
3284 yyerror("out of memory");
3285 return -1;
3286 }
3287 }
3288
3289 return 0;
3290 }
3291
parse_semantic_categories(char * id,level_datum_t * levdatum,mls_semantic_cat_t ** cats)3292 static int parse_semantic_categories(char *id, level_datum_t * levdatum,
3293 mls_semantic_cat_t ** cats)
3294 {
3295 cat_datum_t *cdatum;
3296 mls_semantic_cat_t *newcat;
3297 unsigned int range_start, range_end;
3298
3299 if (id_has_dot(id)) {
3300 char *id_start = id;
3301 char *id_end = strchr(id, '.');
3302
3303 *(id_end++) = '\0';
3304
3305 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3306 (hashtab_key_t)
3307 id_start);
3308 if (!cdatum) {
3309 yyerror2("unknown category %s", id_start);
3310 return -1;
3311 }
3312 range_start = cdatum->s.value;
3313
3314 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3315 (hashtab_key_t) id_end);
3316 if (!cdatum) {
3317 yyerror2("unknown category %s", id_end);
3318 return -1;
3319 }
3320 range_end = cdatum->s.value;
3321 } else {
3322 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3323 (hashtab_key_t) id);
3324 if (!cdatum) {
3325 yyerror2("unknown category %s", id);
3326 return -1;
3327 }
3328 range_start = range_end = cdatum->s.value;
3329 }
3330
3331 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
3332 if (!newcat) {
3333 yyerror("out of memory");
3334 return -1;
3335 }
3336
3337 mls_semantic_cat_init(newcat);
3338 newcat->next = *cats;
3339 newcat->low = range_start;
3340 newcat->high = range_end;
3341
3342 *cats = newcat;
3343
3344 return 0;
3345 }
3346
define_user(void)3347 int define_user(void)
3348 {
3349 char *id;
3350 user_datum_t *usrdatum;
3351 level_datum_t *levdatum;
3352 int l;
3353
3354 if (pass == 1) {
3355 while ((id = queue_remove(id_queue)))
3356 free(id);
3357 if (mlspol) {
3358 while ((id = queue_remove(id_queue)))
3359 free(id);
3360 id = queue_remove(id_queue);
3361 free(id);
3362 for (l = 0; l < 2; l++) {
3363 while ((id = queue_remove(id_queue))) {
3364 free(id);
3365 }
3366 id = queue_remove(id_queue);
3367 if (!id)
3368 break;
3369 free(id);
3370 }
3371 }
3372 return 0;
3373 }
3374
3375 if ((usrdatum = declare_user()) == NULL) {
3376 return -1;
3377 }
3378
3379 while ((id = queue_remove(id_queue))) {
3380 if (set_user_roles(&usrdatum->roles, id))
3381 continue;
3382 }
3383
3384 if (mlspol) {
3385 id = queue_remove(id_queue);
3386 if (!id) {
3387 yyerror("no default level specified for user");
3388 return -1;
3389 }
3390
3391 levdatum = (level_datum_t *)
3392 hashtab_search(policydbp->p_levels.table,
3393 (hashtab_key_t) id);
3394 if (!levdatum) {
3395 yyerror2("unknown sensitivity %s used in user"
3396 " level definition", id);
3397 free(id);
3398 return -1;
3399 }
3400 free(id);
3401
3402 usrdatum->dfltlevel.sens = levdatum->level->sens;
3403
3404 while ((id = queue_remove(id_queue))) {
3405 if (parse_semantic_categories(id, levdatum,
3406 &usrdatum->dfltlevel.cat)) {
3407 free(id);
3408 return -1;
3409 }
3410 free(id);
3411 }
3412
3413 id = queue_remove(id_queue);
3414
3415 for (l = 0; l < 2; l++) {
3416 levdatum = (level_datum_t *)
3417 hashtab_search(policydbp->p_levels.table,
3418 (hashtab_key_t) id);
3419 if (!levdatum) {
3420 yyerror2("unknown sensitivity %s used in user"
3421 " range definition", id);
3422 free(id);
3423 return -1;
3424 }
3425 free(id);
3426
3427 usrdatum->range.level[l].sens = levdatum->level->sens;
3428
3429 while ((id = queue_remove(id_queue))) {
3430 if (parse_semantic_categories(id, levdatum,
3431 &usrdatum->range.level[l].cat)) {
3432 free(id);
3433 return -1;
3434 }
3435 free(id);
3436 }
3437
3438 id = queue_remove(id_queue);
3439 if (!id)
3440 break;
3441 }
3442
3443 if (l == 0) {
3444 if (mls_semantic_level_cpy(&usrdatum->range.level[1],
3445 &usrdatum->range.level[0])) {
3446 yyerror("out of memory");
3447 return -1;
3448 }
3449 }
3450 }
3451 return 0;
3452 }
3453
parse_security_context(context_struct_t * c)3454 static int parse_security_context(context_struct_t * c)
3455 {
3456 char *id;
3457 role_datum_t *role;
3458 type_datum_t *typdatum;
3459 user_datum_t *usrdatum;
3460 level_datum_t *levdatum;
3461 int l;
3462
3463 if (pass == 1) {
3464 id = queue_remove(id_queue);
3465 free(id); /* user */
3466 id = queue_remove(id_queue);
3467 free(id); /* role */
3468 id = queue_remove(id_queue);
3469 free(id); /* type */
3470 if (mlspol) {
3471 id = queue_remove(id_queue);
3472 free(id);
3473 for (l = 0; l < 2; l++) {
3474 while ((id = queue_remove(id_queue))) {
3475 free(id);
3476 }
3477 id = queue_remove(id_queue);
3478 if (!id)
3479 break;
3480 free(id);
3481 }
3482 }
3483 return 0;
3484 }
3485
3486 context_init(c);
3487
3488 /* extract the user */
3489 id = queue_remove(id_queue);
3490 if (!id) {
3491 yyerror("no effective user?");
3492 goto bad;
3493 }
3494 if (!is_id_in_scope(SYM_USERS, id)) {
3495 yyerror2("user %s is not within scope", id);
3496 free(id);
3497 goto bad;
3498 }
3499 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3500 (hashtab_key_t) id);
3501 if (!usrdatum) {
3502 yyerror2("user %s is not defined", id);
3503 free(id);
3504 goto bad;
3505 }
3506 c->user = usrdatum->s.value;
3507
3508 /* no need to keep the user name */
3509 free(id);
3510
3511 /* extract the role */
3512 id = (char *)queue_remove(id_queue);
3513 if (!id) {
3514 yyerror("no role name for sid context definition?");
3515 return -1;
3516 }
3517 if (!is_id_in_scope(SYM_ROLES, id)) {
3518 yyerror2("role %s is not within scope", id);
3519 free(id);
3520 return -1;
3521 }
3522 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3523 (hashtab_key_t) id);
3524 if (!role) {
3525 yyerror2("role %s is not defined", id);
3526 free(id);
3527 return -1;
3528 }
3529 c->role = role->s.value;
3530
3531 /* no need to keep the role name */
3532 free(id);
3533
3534 /* extract the type */
3535 id = (char *)queue_remove(id_queue);
3536 if (!id) {
3537 yyerror("no type name for sid context definition?");
3538 return -1;
3539 }
3540 if (!is_id_in_scope(SYM_TYPES, id)) {
3541 yyerror2("type %s is not within scope", id);
3542 free(id);
3543 return -1;
3544 }
3545 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
3546 (hashtab_key_t) id);
3547 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
3548 yyerror2("type %s is not defined or is an attribute", id);
3549 free(id);
3550 return -1;
3551 }
3552 c->type = typdatum->s.value;
3553
3554 /* no need to keep the type name */
3555 free(id);
3556
3557 if (mlspol) {
3558 /* extract the low sensitivity */
3559 id = (char *)queue_head(id_queue);
3560 if (!id) {
3561 yyerror("no sensitivity name for sid context"
3562 " definition?");
3563 return -1;
3564 }
3565
3566 id = (char *)queue_remove(id_queue);
3567 for (l = 0; l < 2; l++) {
3568 levdatum = (level_datum_t *)
3569 hashtab_search(policydbp->p_levels.table,
3570 (hashtab_key_t) id);
3571 if (!levdatum) {
3572 yyerror2("Sensitivity %s is not defined", id);
3573 free(id);
3574 return -1;
3575 }
3576 free(id);
3577 c->range.level[l].sens = levdatum->level->sens;
3578
3579 /* extract low category set */
3580 while ((id = queue_remove(id_queue))) {
3581 if (parse_categories(id, levdatum,
3582 &c->range.level[l].cat)) {
3583 free(id);
3584 return -1;
3585 }
3586 free(id);
3587 }
3588
3589 /* extract high sensitivity */
3590 id = (char *)queue_remove(id_queue);
3591 if (!id)
3592 break;
3593 }
3594
3595 if (l == 0) {
3596 c->range.level[1].sens = c->range.level[0].sens;
3597 if (ebitmap_cpy(&c->range.level[1].cat,
3598 &c->range.level[0].cat)) {
3599
3600 yyerror("out of memory");
3601 goto bad;
3602 }
3603 }
3604 }
3605
3606 if (!policydb_context_isvalid(policydbp, c)) {
3607 yyerror("invalid security context");
3608 goto bad;
3609 }
3610 return 0;
3611
3612 bad:
3613 context_destroy(c);
3614
3615 return -1;
3616 }
3617
define_initial_sid_context(void)3618 int define_initial_sid_context(void)
3619 {
3620 char *id;
3621 ocontext_t *c, *head;
3622
3623 if (pass == 1) {
3624 id = (char *)queue_remove(id_queue);
3625 free(id);
3626 parse_security_context(NULL);
3627 return 0;
3628 }
3629
3630 id = (char *)queue_remove(id_queue);
3631 if (!id) {
3632 yyerror("no sid name for SID context definition?");
3633 return -1;
3634 }
3635 head = policydbp->ocontexts[OCON_ISID];
3636 for (c = head; c; c = c->next) {
3637 if (!strcmp(id, c->u.name))
3638 break;
3639 }
3640
3641 if (!c) {
3642 yyerror2("SID %s is not defined", id);
3643 free(id);
3644 return -1;
3645 }
3646 if (c->context[0].user) {
3647 yyerror2("The context for SID %s is multiply defined", id);
3648 free(id);
3649 return -1;
3650 }
3651 /* no need to keep the sid name */
3652 free(id);
3653
3654 if (parse_security_context(&c->context[0]))
3655 return -1;
3656
3657 return 0;
3658 }
3659
define_fs_context(unsigned int major,unsigned int minor)3660 int define_fs_context(unsigned int major, unsigned int minor)
3661 {
3662 ocontext_t *newc, *c, *head;
3663
3664 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
3665 yyerror("fscon not supported for target");
3666 return -1;
3667 }
3668
3669 if (pass == 1) {
3670 parse_security_context(NULL);
3671 parse_security_context(NULL);
3672 return 0;
3673 }
3674
3675 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3676 if (!newc) {
3677 yyerror("out of memory");
3678 return -1;
3679 }
3680 memset(newc, 0, sizeof(ocontext_t));
3681
3682 newc->u.name = (char *)malloc(6);
3683 if (!newc->u.name) {
3684 yyerror("out of memory");
3685 free(newc);
3686 return -1;
3687 }
3688 sprintf(newc->u.name, "%02x:%02x", major, minor);
3689
3690 if (parse_security_context(&newc->context[0])) {
3691 free(newc->u.name);
3692 free(newc);
3693 return -1;
3694 }
3695 if (parse_security_context(&newc->context[1])) {
3696 context_destroy(&newc->context[0]);
3697 free(newc->u.name);
3698 free(newc);
3699 return -1;
3700 }
3701 head = policydbp->ocontexts[OCON_FS];
3702
3703 for (c = head; c; c = c->next) {
3704 if (!strcmp(newc->u.name, c->u.name)) {
3705 yyerror2("duplicate entry for file system %s",
3706 newc->u.name);
3707 context_destroy(&newc->context[0]);
3708 context_destroy(&newc->context[1]);
3709 free(newc->u.name);
3710 free(newc);
3711 return -1;
3712 }
3713 }
3714
3715 newc->next = head;
3716 policydbp->ocontexts[OCON_FS] = newc;
3717
3718 return 0;
3719 }
3720
define_pirq_context(unsigned int pirq)3721 int define_pirq_context(unsigned int pirq)
3722 {
3723 ocontext_t *newc, *c, *l, *head;
3724 char *id;
3725
3726 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3727 yyerror("pirqcon not supported for target");
3728 return -1;
3729 }
3730
3731 if (pass == 1) {
3732 id = (char *) queue_remove(id_queue);
3733 free(id);
3734 parse_security_context(NULL);
3735 return 0;
3736 }
3737
3738 newc = malloc(sizeof(ocontext_t));
3739 if (!newc) {
3740 yyerror("out of memory");
3741 return -1;
3742 }
3743 memset(newc, 0, sizeof(ocontext_t));
3744
3745 newc->u.pirq = pirq;
3746
3747 if (parse_security_context(&newc->context[0])) {
3748 free(newc);
3749 return -1;
3750 }
3751
3752 head = policydbp->ocontexts[OCON_XEN_PIRQ];
3753 for (l = NULL, c = head; c; l = c, c = c->next) {
3754 unsigned int pirq2;
3755
3756 pirq2 = c->u.pirq;
3757 if (pirq == pirq2) {
3758 yyerror2("duplicate pirqcon entry for %d ", pirq);
3759 goto bad;
3760 }
3761 }
3762
3763 if (l)
3764 l->next = newc;
3765 else
3766 policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
3767
3768 return 0;
3769
3770 bad:
3771 free(newc);
3772 return -1;
3773 }
3774
define_iomem_context(unsigned long low,unsigned long high)3775 int define_iomem_context(unsigned long low, unsigned long high)
3776 {
3777 ocontext_t *newc, *c, *l, *head;
3778 char *id;
3779
3780 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3781 yyerror("iomemcon not supported for target");
3782 return -1;
3783 }
3784
3785 if (pass == 1) {
3786 id = (char *)queue_remove(id_queue);
3787 free(id);
3788 parse_security_context(NULL);
3789 return 0;
3790 }
3791
3792 newc = malloc(sizeof(ocontext_t));
3793 if (!newc) {
3794 yyerror("out of memory");
3795 return -1;
3796 }
3797 memset(newc, 0, sizeof(ocontext_t));
3798
3799 newc->u.iomem.low_iomem = low;
3800 newc->u.iomem.high_iomem = high;
3801
3802 if (low > high) {
3803 yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
3804 free(newc);
3805 return -1;
3806 }
3807
3808 if (parse_security_context(&newc->context[0])) {
3809 free(newc);
3810 return -1;
3811 }
3812
3813 head = policydbp->ocontexts[OCON_XEN_IOMEM];
3814 for (l = NULL, c = head; c; l = c, c = c->next) {
3815 unsigned int low2, high2;
3816
3817 low2 = c->u.iomem.low_iomem;
3818 high2 = c->u.iomem.high_iomem;
3819 if (low <= high2 && low2 <= high) {
3820 yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
3821 "earlier entry 0x%x-0x%x", low, high,
3822 low2, high2);
3823 goto bad;
3824 }
3825 }
3826
3827 if (l)
3828 l->next = newc;
3829 else
3830 policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
3831
3832 return 0;
3833
3834 bad:
3835 free(newc);
3836 return -1;
3837 }
3838
define_ioport_context(unsigned long low,unsigned long high)3839 int define_ioport_context(unsigned long low, unsigned long high)
3840 {
3841 ocontext_t *newc, *c, *l, *head;
3842 char *id;
3843
3844 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3845 yyerror("ioportcon not supported for target");
3846 return -1;
3847 }
3848
3849 if (pass == 1) {
3850 id = (char *)queue_remove(id_queue);
3851 free(id);
3852 parse_security_context(NULL);
3853 return 0;
3854 }
3855
3856 newc = malloc(sizeof(ocontext_t));
3857 if (!newc) {
3858 yyerror("out of memory");
3859 return -1;
3860 }
3861 memset(newc, 0, sizeof(ocontext_t));
3862
3863 newc->u.ioport.low_ioport = low;
3864 newc->u.ioport.high_ioport = high;
3865
3866 if (low > high) {
3867 yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
3868 free(newc);
3869 return -1;
3870 }
3871
3872 if (parse_security_context(&newc->context[0])) {
3873 free(newc);
3874 return -1;
3875 }
3876
3877 head = policydbp->ocontexts[OCON_XEN_IOPORT];
3878 for (l = NULL, c = head; c; l = c, c = c->next) {
3879 unsigned int low2, high2;
3880
3881 low2 = c->u.ioport.low_ioport;
3882 high2 = c->u.ioport.high_ioport;
3883 if (low <= high2 && low2 <= high) {
3884 yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
3885 "earlier entry 0x%x-0x%x", low, high,
3886 low2, high2);
3887 goto bad;
3888 }
3889 }
3890
3891 if (l)
3892 l->next = newc;
3893 else
3894 policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
3895
3896 return 0;
3897
3898 bad:
3899 free(newc);
3900 return -1;
3901 }
3902
define_pcidevice_context(unsigned long device)3903 int define_pcidevice_context(unsigned long device)
3904 {
3905 ocontext_t *newc, *c, *l, *head;
3906 char *id;
3907
3908 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3909 yyerror("pcidevicecon not supported for target");
3910 return -1;
3911 }
3912
3913 if (pass == 1) {
3914 id = (char *) queue_remove(id_queue);
3915 free(id);
3916 parse_security_context(NULL);
3917 return 0;
3918 }
3919
3920 newc = malloc(sizeof(ocontext_t));
3921 if (!newc) {
3922 yyerror("out of memory");
3923 return -1;
3924 }
3925 memset(newc, 0, sizeof(ocontext_t));
3926
3927 newc->u.device = device;
3928
3929 if (parse_security_context(&newc->context[0])) {
3930 free(newc);
3931 return -1;
3932 }
3933
3934 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
3935 for (l = NULL, c = head; c; l = c, c = c->next) {
3936 unsigned int device2;
3937
3938 device2 = c->u.device;
3939 if (device == device2) {
3940 yyerror2("duplicate pcidevicecon entry for 0x%x ",
3941 device);
3942 goto bad;
3943 }
3944 }
3945
3946 if (l)
3947 l->next = newc;
3948 else
3949 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
3950
3951 return 0;
3952
3953 bad:
3954 free(newc);
3955 return -1;
3956 }
3957
define_port_context(unsigned int low,unsigned int high)3958 int define_port_context(unsigned int low, unsigned int high)
3959 {
3960 ocontext_t *newc, *c, *l, *head;
3961 unsigned int protocol;
3962 char *id;
3963
3964 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
3965 yyerror("portcon not supported for target");
3966 return -1;
3967 }
3968
3969 if (pass == 1) {
3970 id = (char *)queue_remove(id_queue);
3971 free(id);
3972 parse_security_context(NULL);
3973 return 0;
3974 }
3975
3976 newc = malloc(sizeof(ocontext_t));
3977 if (!newc) {
3978 yyerror("out of memory");
3979 return -1;
3980 }
3981 memset(newc, 0, sizeof(ocontext_t));
3982
3983 id = (char *)queue_remove(id_queue);
3984 if (!id) {
3985 free(newc);
3986 return -1;
3987 }
3988 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
3989 protocol = IPPROTO_TCP;
3990 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
3991 protocol = IPPROTO_UDP;
3992 } else {
3993 yyerror2("unrecognized protocol %s", id);
3994 free(newc);
3995 return -1;
3996 }
3997
3998 newc->u.port.protocol = protocol;
3999 newc->u.port.low_port = low;
4000 newc->u.port.high_port = high;
4001
4002 if (low > high) {
4003 yyerror2("low port %d exceeds high port %d", low, high);
4004 free(newc);
4005 return -1;
4006 }
4007
4008 if (parse_security_context(&newc->context[0])) {
4009 free(newc);
4010 return -1;
4011 }
4012
4013 /* Preserve the matching order specified in the configuration. */
4014 head = policydbp->ocontexts[OCON_PORT];
4015 for (l = NULL, c = head; c; l = c, c = c->next) {
4016 unsigned int prot2, low2, high2;
4017
4018 prot2 = c->u.port.protocol;
4019 low2 = c->u.port.low_port;
4020 high2 = c->u.port.high_port;
4021 if (protocol != prot2)
4022 continue;
4023 if (low == low2 && high == high2) {
4024 yyerror2("duplicate portcon entry for %s %d-%d ", id,
4025 low, high);
4026 goto bad;
4027 }
4028 if (low2 <= low && high2 >= high) {
4029 yyerror2("portcon entry for %s %d-%d hidden by earlier "
4030 "entry for %d-%d", id, low, high, low2, high2);
4031 goto bad;
4032 }
4033 }
4034
4035 if (l)
4036 l->next = newc;
4037 else
4038 policydbp->ocontexts[OCON_PORT] = newc;
4039
4040 return 0;
4041
4042 bad:
4043 free(newc);
4044 return -1;
4045 }
4046
define_netif_context(void)4047 int define_netif_context(void)
4048 {
4049 ocontext_t *newc, *c, *head;
4050
4051 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4052 yyerror("netifcon not supported for target");
4053 return -1;
4054 }
4055
4056 if (pass == 1) {
4057 free(queue_remove(id_queue));
4058 parse_security_context(NULL);
4059 parse_security_context(NULL);
4060 return 0;
4061 }
4062
4063 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4064 if (!newc) {
4065 yyerror("out of memory");
4066 return -1;
4067 }
4068 memset(newc, 0, sizeof(ocontext_t));
4069
4070 newc->u.name = (char *)queue_remove(id_queue);
4071 if (!newc->u.name) {
4072 free(newc);
4073 return -1;
4074 }
4075 if (parse_security_context(&newc->context[0])) {
4076 free(newc->u.name);
4077 free(newc);
4078 return -1;
4079 }
4080 if (parse_security_context(&newc->context[1])) {
4081 context_destroy(&newc->context[0]);
4082 free(newc->u.name);
4083 free(newc);
4084 return -1;
4085 }
4086 head = policydbp->ocontexts[OCON_NETIF];
4087
4088 for (c = head; c; c = c->next) {
4089 if (!strcmp(newc->u.name, c->u.name)) {
4090 yyerror2("duplicate entry for network interface %s",
4091 newc->u.name);
4092 context_destroy(&newc->context[0]);
4093 context_destroy(&newc->context[1]);
4094 free(newc->u.name);
4095 free(newc);
4096 return -1;
4097 }
4098 }
4099
4100 newc->next = head;
4101 policydbp->ocontexts[OCON_NETIF] = newc;
4102 return 0;
4103 }
4104
define_ipv4_node_context()4105 int define_ipv4_node_context()
4106 {
4107 char *id;
4108 int rc = 0;
4109 struct in_addr addr, mask;
4110 ocontext_t *newc, *c, *l, *head;
4111
4112 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4113 yyerror("nodecon not supported for target");
4114 return -1;
4115 }
4116
4117 if (pass == 1) {
4118 free(queue_remove(id_queue));
4119 free(queue_remove(id_queue));
4120 parse_security_context(NULL);
4121 goto out;
4122 }
4123
4124 id = queue_remove(id_queue);
4125 if (!id) {
4126 yyerror("failed to read ipv4 address");
4127 rc = -1;
4128 goto out;
4129 }
4130
4131 rc = inet_pton(AF_INET, id, &addr);
4132 free(id);
4133 if (rc < 1) {
4134 yyerror("failed to parse ipv4 address");
4135 if (rc == 0)
4136 rc = -1;
4137 goto out;
4138 }
4139
4140 id = queue_remove(id_queue);
4141 if (!id) {
4142 yyerror("failed to read ipv4 address");
4143 rc = -1;
4144 goto out;
4145 }
4146
4147 rc = inet_pton(AF_INET, id, &mask);
4148 free(id);
4149 if (rc < 1) {
4150 yyerror("failed to parse ipv4 mask");
4151 if (rc == 0)
4152 rc = -1;
4153 goto out;
4154 }
4155
4156 newc = malloc(sizeof(ocontext_t));
4157 if (!newc) {
4158 yyerror("out of memory");
4159 rc = -1;
4160 goto out;
4161 }
4162
4163 memset(newc, 0, sizeof(ocontext_t));
4164 newc->u.node.addr = addr.s_addr;
4165 newc->u.node.mask = mask.s_addr;
4166
4167 if (parse_security_context(&newc->context[0])) {
4168 free(newc);
4169 return -1;
4170 }
4171
4172 /* Create order of most specific to least retaining
4173 the order specified in the configuration. */
4174 head = policydbp->ocontexts[OCON_NODE];
4175 for (l = NULL, c = head; c; l = c, c = c->next) {
4176 if (newc->u.node.mask > c->u.node.mask)
4177 break;
4178 }
4179
4180 newc->next = c;
4181
4182 if (l)
4183 l->next = newc;
4184 else
4185 policydbp->ocontexts[OCON_NODE] = newc;
4186 rc = 0;
4187 out:
4188 return rc;
4189 }
4190
define_ipv6_node_context(void)4191 int define_ipv6_node_context(void)
4192 {
4193 char *id;
4194 int rc = 0;
4195 struct in6_addr addr, mask;
4196 ocontext_t *newc, *c, *l, *head;
4197
4198 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4199 yyerror("nodecon not supported for target");
4200 return -1;
4201 }
4202
4203 if (pass == 1) {
4204 free(queue_remove(id_queue));
4205 free(queue_remove(id_queue));
4206 parse_security_context(NULL);
4207 goto out;
4208 }
4209
4210 id = queue_remove(id_queue);
4211 if (!id) {
4212 yyerror("failed to read ipv6 address");
4213 rc = -1;
4214 goto out;
4215 }
4216
4217 rc = inet_pton(AF_INET6, id, &addr);
4218 free(id);
4219 if (rc < 1) {
4220 yyerror("failed to parse ipv6 address");
4221 if (rc == 0)
4222 rc = -1;
4223 goto out;
4224 }
4225
4226 id = queue_remove(id_queue);
4227 if (!id) {
4228 yyerror("failed to read ipv6 address");
4229 rc = -1;
4230 goto out;
4231 }
4232
4233 rc = inet_pton(AF_INET6, id, &mask);
4234 free(id);
4235 if (rc < 1) {
4236 yyerror("failed to parse ipv6 mask");
4237 if (rc == 0)
4238 rc = -1;
4239 goto out;
4240 }
4241
4242 newc = malloc(sizeof(ocontext_t));
4243 if (!newc) {
4244 yyerror("out of memory");
4245 rc = -1;
4246 goto out;
4247 }
4248
4249 memset(newc, 0, sizeof(ocontext_t));
4250
4251 #ifdef DARWIN
4252 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
4253 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
4254 #else
4255 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
4256 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
4257 #endif
4258
4259 if (parse_security_context(&newc->context[0])) {
4260 free(newc);
4261 rc = -1;
4262 goto out;
4263 }
4264
4265 /* Create order of most specific to least retaining
4266 the order specified in the configuration. */
4267 head = policydbp->ocontexts[OCON_NODE6];
4268 for (l = NULL, c = head; c; l = c, c = c->next) {
4269 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
4270 break;
4271 }
4272
4273 newc->next = c;
4274
4275 if (l)
4276 l->next = newc;
4277 else
4278 policydbp->ocontexts[OCON_NODE6] = newc;
4279
4280 rc = 0;
4281 out:
4282 return rc;
4283 }
4284
define_fs_use(int behavior)4285 int define_fs_use(int behavior)
4286 {
4287 ocontext_t *newc, *c, *head;
4288
4289 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4290 yyerror("fsuse not supported for target");
4291 return -1;
4292 }
4293
4294 if (pass == 1) {
4295 free(queue_remove(id_queue));
4296 parse_security_context(NULL);
4297 return 0;
4298 }
4299
4300 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4301 if (!newc) {
4302 yyerror("out of memory");
4303 return -1;
4304 }
4305 memset(newc, 0, sizeof(ocontext_t));
4306
4307 newc->u.name = (char *)queue_remove(id_queue);
4308 if (!newc->u.name) {
4309 free(newc);
4310 return -1;
4311 }
4312 newc->v.behavior = behavior;
4313 if (parse_security_context(&newc->context[0])) {
4314 free(newc->u.name);
4315 free(newc);
4316 return -1;
4317 }
4318
4319 head = policydbp->ocontexts[OCON_FSUSE];
4320
4321 for (c = head; c; c = c->next) {
4322 if (!strcmp(newc->u.name, c->u.name)) {
4323 yyerror2("duplicate fs_use entry for filesystem type %s",
4324 newc->u.name);
4325 context_destroy(&newc->context[0]);
4326 free(newc->u.name);
4327 free(newc);
4328 return -1;
4329 }
4330 }
4331
4332 newc->next = head;
4333 policydbp->ocontexts[OCON_FSUSE] = newc;
4334 return 0;
4335 }
4336
define_genfs_context_helper(char * fstype,int has_type)4337 int define_genfs_context_helper(char *fstype, int has_type)
4338 {
4339 struct genfs *genfs_p, *genfs, *newgenfs;
4340 ocontext_t *newc, *c, *head, *p;
4341 char *type = NULL;
4342 int len, len2;
4343
4344 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4345 yyerror("genfs not supported for target");
4346 return -1;
4347 }
4348
4349 if (pass == 1) {
4350 free(fstype);
4351 free(queue_remove(id_queue));
4352 if (has_type)
4353 free(queue_remove(id_queue));
4354 parse_security_context(NULL);
4355 return 0;
4356 }
4357
4358 for (genfs_p = NULL, genfs = policydbp->genfs;
4359 genfs; genfs_p = genfs, genfs = genfs->next) {
4360 if (strcmp(fstype, genfs->fstype) <= 0)
4361 break;
4362 }
4363
4364 if (!genfs || strcmp(fstype, genfs->fstype)) {
4365 newgenfs = malloc(sizeof(struct genfs));
4366 if (!newgenfs) {
4367 yyerror("out of memory");
4368 return -1;
4369 }
4370 memset(newgenfs, 0, sizeof(struct genfs));
4371 newgenfs->fstype = fstype;
4372 newgenfs->next = genfs;
4373 if (genfs_p)
4374 genfs_p->next = newgenfs;
4375 else
4376 policydbp->genfs = newgenfs;
4377 genfs = newgenfs;
4378 }
4379
4380 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4381 if (!newc) {
4382 yyerror("out of memory");
4383 return -1;
4384 }
4385 memset(newc, 0, sizeof(ocontext_t));
4386
4387 newc->u.name = (char *)queue_remove(id_queue);
4388 if (!newc->u.name)
4389 goto fail;
4390 if (has_type) {
4391 type = (char *)queue_remove(id_queue);
4392 if (!type)
4393 goto fail;
4394 if (type[1] != 0) {
4395 yyerror2("invalid type %s", type);
4396 goto fail;
4397 }
4398 switch (type[0]) {
4399 case 'b':
4400 newc->v.sclass = SECCLASS_BLK_FILE;
4401 break;
4402 case 'c':
4403 newc->v.sclass = SECCLASS_CHR_FILE;
4404 break;
4405 case 'd':
4406 newc->v.sclass = SECCLASS_DIR;
4407 break;
4408 case 'p':
4409 newc->v.sclass = SECCLASS_FIFO_FILE;
4410 break;
4411 case 'l':
4412 newc->v.sclass = SECCLASS_LNK_FILE;
4413 break;
4414 case 's':
4415 newc->v.sclass = SECCLASS_SOCK_FILE;
4416 break;
4417 case '-':
4418 newc->v.sclass = SECCLASS_FILE;
4419 break;
4420 default:
4421 yyerror2("invalid type %s", type);
4422 goto fail;
4423 }
4424 }
4425 if (parse_security_context(&newc->context[0]))
4426 goto fail;
4427
4428 head = genfs->head;
4429
4430 for (p = NULL, c = head; c; p = c, c = c->next) {
4431 if (!strcmp(newc->u.name, c->u.name) &&
4432 (!newc->v.sclass || !c->v.sclass
4433 || newc->v.sclass == c->v.sclass)) {
4434 yyerror2("duplicate entry for genfs entry (%s, %s)",
4435 fstype, newc->u.name);
4436 goto fail;
4437 }
4438 len = strlen(newc->u.name);
4439 len2 = strlen(c->u.name);
4440 if (len > len2)
4441 break;
4442 }
4443
4444 newc->next = c;
4445 if (p)
4446 p->next = newc;
4447 else
4448 genfs->head = newc;
4449 return 0;
4450 fail:
4451 if (type)
4452 free(type);
4453 context_destroy(&newc->context[0]);
4454 if (fstype)
4455 free(fstype);
4456 if (newc->u.name)
4457 free(newc->u.name);
4458 free(newc);
4459 return -1;
4460 }
4461
define_genfs_context(int has_type)4462 int define_genfs_context(int has_type)
4463 {
4464 return define_genfs_context_helper(queue_remove(id_queue), has_type);
4465 }
4466
define_range_trans(int class_specified)4467 int define_range_trans(int class_specified)
4468 {
4469 char *id;
4470 level_datum_t *levdatum = 0;
4471 class_datum_t *cladatum;
4472 range_trans_rule_t *rule;
4473 int l, add = 1;
4474
4475 if (!mlspol) {
4476 yyerror("range_transition rule in non-MLS configuration");
4477 return -1;
4478 }
4479
4480 if (pass == 1) {
4481 while ((id = queue_remove(id_queue)))
4482 free(id);
4483 while ((id = queue_remove(id_queue)))
4484 free(id);
4485 if (class_specified)
4486 while ((id = queue_remove(id_queue)))
4487 free(id);
4488 id = queue_remove(id_queue);
4489 free(id);
4490 for (l = 0; l < 2; l++) {
4491 while ((id = queue_remove(id_queue))) {
4492 free(id);
4493 }
4494 id = queue_remove(id_queue);
4495 if (!id)
4496 break;
4497 free(id);
4498 }
4499 return 0;
4500 }
4501
4502 rule = malloc(sizeof(struct range_trans_rule));
4503 if (!rule) {
4504 yyerror("out of memory");
4505 return -1;
4506 }
4507 range_trans_rule_init(rule);
4508
4509 while ((id = queue_remove(id_queue))) {
4510 if (set_types(&rule->stypes, id, &add, 0))
4511 goto out;
4512 }
4513 add = 1;
4514 while ((id = queue_remove(id_queue))) {
4515 if (set_types(&rule->ttypes, id, &add, 0))
4516 goto out;
4517 }
4518
4519 if (class_specified) {
4520 if (read_classes(&rule->tclasses))
4521 goto out;
4522 } else {
4523 cladatum = hashtab_search(policydbp->p_classes.table,
4524 "process");
4525 if (!cladatum) {
4526 yyerror2("could not find process class for "
4527 "legacy range_transition statement");
4528 goto out;
4529 }
4530
4531 ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE);
4532 }
4533
4534 id = (char *)queue_remove(id_queue);
4535 if (!id) {
4536 yyerror("no range in range_transition definition?");
4537 goto out;
4538 }
4539 for (l = 0; l < 2; l++) {
4540 levdatum = hashtab_search(policydbp->p_levels.table, id);
4541 if (!levdatum) {
4542 yyerror2("unknown level %s used in range_transition "
4543 "definition", id);
4544 free(id);
4545 goto out;
4546 }
4547 free(id);
4548
4549 rule->trange.level[l].sens = levdatum->level->sens;
4550
4551 while ((id = queue_remove(id_queue))) {
4552 if (parse_semantic_categories(id, levdatum,
4553 &rule->trange.level[l].cat)) {
4554 free(id);
4555 goto out;
4556 }
4557 free(id);
4558 }
4559
4560 id = (char *)queue_remove(id_queue);
4561 if (!id)
4562 break;
4563 }
4564 if (l == 0) {
4565 if (mls_semantic_level_cpy(&rule->trange.level[1],
4566 &rule->trange.level[0])) {
4567 yyerror("out of memory");
4568 goto out;
4569 }
4570 }
4571
4572 append_range_trans(rule);
4573 return 0;
4574
4575 out:
4576 range_trans_rule_destroy(rule);
4577 return -1;
4578 }
4579
4580 /* FLASK */
4581