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