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