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