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