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