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