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