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