blob: c292eae85d93635db46956640cace0637d44cb6f [file] [log] [blame]
SE Android8c48de12012-01-24 05:27:18 -08001/*
2 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
3 */
4
5/*
6 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
7 *
8 * Support for enhanced MLS infrastructure.
9 *
10 * Updated: David Caplan, <dac@tresys.com>
11 *
12 * Added conditional policy language extensions
13 *
14 * Updated: Joshua Brindle <jbrindle@tresys.com>
15 * Karl MacMillan <kmacmillan@mentalrootkit.com>
16 * Jason Tang <jtang@tresys.com>
17 *
18 * Added support for binary policy modules
19 *
20 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
21 * Copyright (C) 2003 - 2008 Tresys Technology, LLC
22 * Copyright (C) 2007 Red Hat Inc.
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation, version 2.
26 */
27
28/* FLASK */
29
30#include <sys/types.h>
31#include <assert.h>
32#include <stdarg.h>
33#include <stdint.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37#include <sys/socket.h>
38#include <netinet/in.h>
39#include <arpa/inet.h>
40#include <stdlib.h>
Nick Kralevichb656e022014-03-11 15:29:38 -070041#include <limits.h>
SE Android8c48de12012-01-24 05:27:18 -080042
43#include <sepol/policydb/expand.h>
44#include <sepol/policydb/policydb.h>
45#include <sepol/policydb/services.h>
46#include <sepol/policydb/conditional.h>
47#include <sepol/policydb/flask.h>
48#include <sepol/policydb/hierarchy.h>
49#include <sepol/policydb/polcaps.h>
50#include "queue.h"
51#include "checkpolicy.h"
52#include "module_compiler.h"
53#include "policy_define.h"
54
55policydb_t *policydbp;
56queue_t id_queue = 0;
57unsigned int pass;
58char *curfile = 0;
59int mlspol = 0;
60
61extern unsigned long policydb_lineno;
62extern unsigned long source_lineno;
63extern unsigned int policydb_errors;
Stephen Smalleya5e505c2014-03-05 16:06:42 -050064extern char source_file[PATH_MAX];
SE Android8c48de12012-01-24 05:27:18 -080065
66extern int yywarn(char *msg);
67extern int yyerror(char *msg);
68
69#define ERRORMSG_LEN 255
70static char errormsg[ERRORMSG_LEN + 1] = {0};
71
72static int id_has_dot(char *id);
73static int parse_security_context(context_struct_t *c);
74
75/* initialize all of the state variables for the scanner/parser */
76void init_parser(int pass_number)
77{
78 policydb_lineno = 1;
79 source_lineno = 1;
80 policydb_errors = 0;
81 pass = pass_number;
82}
83
84void yyerror2(char *fmt, ...)
85{
86 va_list ap;
87 va_start(ap, fmt);
88 vsnprintf(errormsg, ERRORMSG_LEN, fmt, ap);
89 yyerror(errormsg);
90 va_end(ap);
91}
92
93int insert_separator(int push)
94{
95 int error;
96
97 if (push)
98 error = queue_push(id_queue, 0);
99 else
100 error = queue_insert(id_queue, 0);
101
102 if (error) {
103 yyerror("queue overflow");
104 return -1;
105 }
106 return 0;
107}
108
109int insert_id(char *id, int push)
110{
111 char *newid = 0;
112 int error;
113
114 newid = (char *)malloc(strlen(id) + 1);
115 if (!newid) {
116 yyerror("out of memory");
117 return -1;
118 }
119 strcpy(newid, id);
120 if (push)
121 error = queue_push(id_queue, (queue_element_t) newid);
122 else
123 error = queue_insert(id_queue, (queue_element_t) newid);
124
125 if (error) {
126 yyerror("queue overflow");
127 free(newid);
128 return -1;
129 }
130 return 0;
131}
132
133/* If the identifier has a dot within it and that its first character
134 is not a dot then return 1, else return 0. */
135static int id_has_dot(char *id)
136{
137 if (strchr(id, '.') >= id + 1) {
138 return 1;
139 }
140 return 0;
141}
142
143int define_class(void)
144{
145 char *id = 0;
146 class_datum_t *datum = 0;
147 int ret;
148 uint32_t value;
149
150 if (pass == 2) {
151 id = queue_remove(id_queue);
152 free(id);
153 return 0;
154 }
155
156 id = (char *)queue_remove(id_queue);
157 if (!id) {
158 yyerror("no class name for class definition?");
159 return -1;
160 }
161 datum = (class_datum_t *) malloc(sizeof(class_datum_t));
162 if (!datum) {
163 yyerror("out of memory");
164 goto bad;
165 }
166 memset(datum, 0, sizeof(class_datum_t));
167 ret = declare_symbol(SYM_CLASSES, id, datum, &value, &value);
168 switch (ret) {
169 case -3:{
170 yyerror("Out of memory!");
171 goto bad;
172 }
173 case -2:{
174 yyerror2("duplicate declaration of class %s", id);
175 goto bad;
176 }
177 case -1:{
178 yyerror("could not declare class here");
179 goto bad;
180 }
181 case 0:
182 case 1:{
183 break;
184 }
185 default:{
186 assert(0); /* should never get here */
187 }
188 }
189 datum->s.value = value;
190 return 0;
191
192 bad:
193 if (id)
194 free(id);
195 if (datum)
196 free(datum);
197 return -1;
198}
199
200int define_permissive(void)
201{
202 char *type = NULL;
203 struct type_datum *t;
204 int rc = 0;
205
206 type = queue_remove(id_queue);
207
208 if (!type) {
209 yyerror2("forgot to include type in permissive definition?");
210 rc = -1;
211 goto out;
212 }
213
214 if (pass == 1)
215 goto out;
216
217 if (!is_id_in_scope(SYM_TYPES, type)) {
218 yyerror2("type %s is not within scope", type);
219 rc = -1;
220 goto out;
221 }
222
223 t = hashtab_search(policydbp->p_types.table, type);
224 if (!t) {
225 yyerror2("type is not defined: %s", type);
226 rc = -1;
227 goto out;
228 }
229
230 if (t->flavor == TYPE_ATTRIB) {
231 yyerror2("attributes may not be permissive: %s\n", type);
232 rc = -1;
233 goto out;
234 }
235
236 t->flags |= TYPE_FLAGS_PERMISSIVE;
237
238out:
239 free(type);
240 return rc;
241}
242
243int define_polcap(void)
244{
245 char *id = 0;
246 int capnum;
247
248 if (pass == 2) {
249 id = queue_remove(id_queue);
250 free(id);
251 return 0;
252 }
253
254 id = (char *)queue_remove(id_queue);
255 if (!id) {
256 yyerror("no capability name for policycap definition?");
257 goto bad;
258 }
259
260 /* Check for valid cap name -> number mapping */
261 capnum = sepol_polcap_getnum(id);
262 if (capnum < 0) {
263 yyerror2("invalid policy capability name %s", id);
264 goto bad;
265 }
266
267 /* Store it */
268 if (ebitmap_set_bit(&policydbp->policycaps, capnum, TRUE)) {
269 yyerror("out of memory");
270 goto bad;
271 }
272
273 free(id);
274 return 0;
275
276 bad:
277 free(id);
278 return -1;
279}
280
281int define_initial_sid(void)
282{
283 char *id = 0;
284 ocontext_t *newc = 0, *c, *head;
285
286 if (pass == 2) {
287 id = queue_remove(id_queue);
288 free(id);
289 return 0;
290 }
291
292 id = (char *)queue_remove(id_queue);
293 if (!id) {
294 yyerror("no sid name for SID definition?");
295 return -1;
296 }
297 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
298 if (!newc) {
299 yyerror("out of memory");
300 goto bad;
301 }
302 memset(newc, 0, sizeof(ocontext_t));
303 newc->u.name = id;
304 context_init(&newc->context[0]);
305 head = policydbp->ocontexts[OCON_ISID];
306
307 for (c = head; c; c = c->next) {
308 if (!strcmp(newc->u.name, c->u.name)) {
309 yyerror2("duplicate initial SID %s", id);
310 goto bad;
311 }
312 }
313
314 if (head) {
315 newc->sid[0] = head->sid[0] + 1;
316 } else {
317 newc->sid[0] = 1;
318 }
319 newc->next = head;
320 policydbp->ocontexts[OCON_ISID] = newc;
321
322 return 0;
323
324 bad:
325 if (id)
326 free(id);
327 if (newc)
328 free(newc);
329 return -1;
330}
331
Stephen Smalleycd88c5c2012-02-21 14:27:00 -0500332static int read_classes(ebitmap_t *e_classes)
333{
334 char *id;
335 class_datum_t *cladatum;
336
337 while ((id = queue_remove(id_queue))) {
338 if (!is_id_in_scope(SYM_CLASSES, id)) {
339 yyerror2("class %s is not within scope", id);
340 return -1;
341 }
342 cladatum = hashtab_search(policydbp->p_classes.table, id);
343 if (!cladatum) {
344 yyerror2("unknown class %s", id);
345 return -1;
346 }
347 if (ebitmap_set_bit(e_classes, cladatum->s.value - 1, TRUE)) {
348 yyerror("Out of memory");
349 return -1;
350 }
351 free(id);
352 }
353 return 0;
354}
355
Stephen Smalleyba8e9922012-09-25 10:57:09 -0400356int define_default_user(int which)
357{
358 char *id;
359 class_datum_t *cladatum;
360
361 if (pass == 1) {
362 while ((id = queue_remove(id_queue)))
363 free(id);
364 return 0;
365 }
366
367 while ((id = queue_remove(id_queue))) {
368 if (!is_id_in_scope(SYM_CLASSES, id)) {
369 yyerror2("class %s is not within scope", id);
370 return -1;
371 }
372 cladatum = hashtab_search(policydbp->p_classes.table, id);
373 if (!cladatum) {
374 yyerror2("unknown class %s", id);
375 return -1;
376 }
377 if (cladatum->default_user && cladatum->default_user != which) {
378 yyerror2("conflicting default user information for class %s", id);
379 return -1;
380 }
381 cladatum->default_user = which;
382 free(id);
383 }
384
385 return 0;
386}
387
388int define_default_role(int which)
389{
390 char *id;
391 class_datum_t *cladatum;
392
393 if (pass == 1) {
394 while ((id = queue_remove(id_queue)))
395 free(id);
396 return 0;
397 }
398
399 while ((id = queue_remove(id_queue))) {
400 if (!is_id_in_scope(SYM_CLASSES, id)) {
401 yyerror2("class %s is not within scope", id);
402 return -1;
403 }
404 cladatum = hashtab_search(policydbp->p_classes.table, id);
405 if (!cladatum) {
406 yyerror2("unknown class %s", id);
407 return -1;
408 }
409 if (cladatum->default_role && cladatum->default_role != which) {
410 yyerror2("conflicting default role information for class %s", id);
411 return -1;
412 }
413 cladatum->default_role = which;
414 free(id);
415 }
416
417 return 0;
418}
419
Stephen Smalley968aed02013-10-30 15:38:49 -0400420int define_default_type(int which)
421{
422 char *id;
423 class_datum_t *cladatum;
424
425 if (pass == 1) {
426 while ((id = queue_remove(id_queue)))
427 free(id);
428 return 0;
429 }
430
431 while ((id = queue_remove(id_queue))) {
432 if (!is_id_in_scope(SYM_CLASSES, id)) {
433 yyerror2("class %s is not within scope", id);
434 return -1;
435 }
436 cladatum = hashtab_search(policydbp->p_classes.table, id);
437 if (!cladatum) {
438 yyerror2("unknown class %s", id);
439 return -1;
440 }
441 if (cladatum->default_type && cladatum->default_type != which) {
442 yyerror2("conflicting default type information for class %s", id);
443 return -1;
444 }
445 cladatum->default_type = which;
446 free(id);
447 }
448
449 return 0;
450}
451
Stephen Smalleyba8e9922012-09-25 10:57:09 -0400452int define_default_range(int which)
453{
454 char *id;
455 class_datum_t *cladatum;
456
457 if (pass == 1) {
458 while ((id = queue_remove(id_queue)))
459 free(id);
460 return 0;
461 }
462
463 while ((id = queue_remove(id_queue))) {
464 if (!is_id_in_scope(SYM_CLASSES, id)) {
465 yyerror2("class %s is not within scope", id);
466 return -1;
467 }
468 cladatum = hashtab_search(policydbp->p_classes.table, id);
469 if (!cladatum) {
470 yyerror2("unknown class %s", id);
471 return -1;
472 }
473 if (cladatum->default_range && cladatum->default_range != which) {
474 yyerror2("conflicting default range information for class %s", id);
475 return -1;
476 }
477 cladatum->default_range = which;
478 free(id);
479 }
480
481 return 0;
482}
483
SE Android8c48de12012-01-24 05:27:18 -0800484int define_common_perms(void)
485{
486 char *id = 0, *perm = 0;
487 common_datum_t *comdatum = 0;
488 perm_datum_t *perdatum = 0;
489 int ret;
490
491 if (pass == 2) {
492 while ((id = queue_remove(id_queue)))
493 free(id);
494 return 0;
495 }
496
497 id = (char *)queue_remove(id_queue);
498 if (!id) {
499 yyerror("no common name for common perm definition?");
500 return -1;
501 }
502 comdatum = hashtab_search(policydbp->p_commons.table, id);
503 if (comdatum) {
504 yyerror2("duplicate declaration for common %s\n", id);
505 return -1;
506 }
507 comdatum = (common_datum_t *) malloc(sizeof(common_datum_t));
508 if (!comdatum) {
509 yyerror("out of memory");
510 goto bad;
511 }
512 memset(comdatum, 0, sizeof(common_datum_t));
513 ret = hashtab_insert(policydbp->p_commons.table,
514 (hashtab_key_t) id, (hashtab_datum_t) comdatum);
515
516 if (ret == SEPOL_EEXIST) {
517 yyerror("duplicate common definition");
518 goto bad;
519 }
520 if (ret == SEPOL_ENOMEM) {
521 yyerror("hash table overflow");
522 goto bad;
523 }
524 comdatum->s.value = policydbp->p_commons.nprim + 1;
525 if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) {
526 yyerror("out of memory");
527 goto bad;
528 }
529 policydbp->p_commons.nprim++;
530 while ((perm = queue_remove(id_queue))) {
531 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
532 if (!perdatum) {
533 yyerror("out of memory");
534 goto bad_perm;
535 }
536 memset(perdatum, 0, sizeof(perm_datum_t));
537 perdatum->s.value = comdatum->permissions.nprim + 1;
538
539 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
540 yyerror
541 ("too many permissions to fit in an access vector");
542 goto bad_perm;
543 }
544 ret = hashtab_insert(comdatum->permissions.table,
545 (hashtab_key_t) perm,
546 (hashtab_datum_t) perdatum);
547
548 if (ret == SEPOL_EEXIST) {
549 yyerror2("duplicate permission %s in common %s", perm,
550 id);
551 goto bad_perm;
552 }
553 if (ret == SEPOL_ENOMEM) {
554 yyerror("hash table overflow");
555 goto bad_perm;
556 }
557 comdatum->permissions.nprim++;
558 }
559
560 return 0;
561
562 bad:
563 if (id)
564 free(id);
565 if (comdatum)
566 free(comdatum);
567 return -1;
568
569 bad_perm:
570 if (perm)
571 free(perm);
572 if (perdatum)
573 free(perdatum);
574 return -1;
575}
576
577int define_av_perms(int inherits)
578{
579 char *id;
580 class_datum_t *cladatum;
581 common_datum_t *comdatum;
582 perm_datum_t *perdatum = 0, *perdatum2 = 0;
583 int ret;
584
585 if (pass == 2) {
586 while ((id = queue_remove(id_queue)))
587 free(id);
588 return 0;
589 }
590
591 id = (char *)queue_remove(id_queue);
592 if (!id) {
593 yyerror("no tclass name for av perm definition?");
594 return -1;
595 }
596 cladatum = (class_datum_t *) hashtab_search(policydbp->p_classes.table,
597 (hashtab_key_t) id);
598 if (!cladatum) {
599 yyerror2("class %s is not defined", id);
600 goto bad;
601 }
602 free(id);
603
604 if (cladatum->comdatum || cladatum->permissions.nprim) {
605 yyerror("duplicate access vector definition");
606 return -1;
607 }
608 if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) {
609 yyerror("out of memory");
610 return -1;
611 }
612 if (inherits) {
613 id = (char *)queue_remove(id_queue);
614 if (!id) {
615 yyerror
616 ("no inherits name for access vector definition?");
617 return -1;
618 }
619 comdatum =
620 (common_datum_t *) hashtab_search(policydbp->p_commons.
621 table,
622 (hashtab_key_t) id);
623
624 if (!comdatum) {
625 yyerror2("common %s is not defined", id);
626 goto bad;
627 }
628 cladatum->comkey = id;
629 cladatum->comdatum = comdatum;
630
631 /*
632 * Class-specific permissions start with values
633 * after the last common permission.
634 */
635 cladatum->permissions.nprim += comdatum->permissions.nprim;
636 }
637 while ((id = queue_remove(id_queue))) {
638 perdatum = (perm_datum_t *) malloc(sizeof(perm_datum_t));
639 if (!perdatum) {
640 yyerror("out of memory");
641 goto bad;
642 }
643 memset(perdatum, 0, sizeof(perm_datum_t));
644 perdatum->s.value = ++cladatum->permissions.nprim;
645
646 if (perdatum->s.value > (sizeof(sepol_access_vector_t) * 8)) {
647 yyerror
648 ("too many permissions to fit in an access vector");
649 goto bad;
650 }
651 if (inherits) {
652 /*
653 * Class-specific permissions and
654 * common permissions exist in the same
655 * name space.
656 */
657 perdatum2 =
658 (perm_datum_t *) hashtab_search(cladatum->comdatum->
659 permissions.table,
660 (hashtab_key_t) id);
661 if (perdatum2) {
662 yyerror2("permission %s conflicts with an "
663 "inherited permission", id);
664 goto bad;
665 }
666 }
667 ret = hashtab_insert(cladatum->permissions.table,
668 (hashtab_key_t) id,
669 (hashtab_datum_t) perdatum);
670
671 if (ret == SEPOL_EEXIST) {
672 yyerror2("duplicate permission %s", id);
673 goto bad;
674 }
675 if (ret == SEPOL_ENOMEM) {
676 yyerror("hash table overflow");
677 goto bad;
678 }
679 if (add_perm_to_class(perdatum->s.value, cladatum->s.value)) {
680 yyerror("out of memory");
681 goto bad;
682 }
683 }
684
685 return 0;
686
687 bad:
688 if (id)
689 free(id);
690 if (perdatum)
691 free(perdatum);
692 return -1;
693}
694
695int define_sens(void)
696{
697 char *id;
698 mls_level_t *level = 0;
699 level_datum_t *datum = 0, *aliasdatum = 0;
700 int ret;
701 uint32_t value; /* dummy variable -- its value is never used */
702
703 if (!mlspol) {
704 yyerror("sensitivity definition in non-MLS configuration");
705 return -1;
706 }
707
708 if (pass == 2) {
709 while ((id = queue_remove(id_queue)))
710 free(id);
711 return 0;
712 }
713
714 id = (char *)queue_remove(id_queue);
715 if (!id) {
716 yyerror("no sensitivity name for sensitivity definition?");
717 return -1;
718 }
719 if (id_has_dot(id)) {
720 yyerror("sensitivity identifiers may not contain periods");
721 goto bad;
722 }
723 level = (mls_level_t *) malloc(sizeof(mls_level_t));
724 if (!level) {
725 yyerror("out of memory");
726 goto bad;
727 }
728 mls_level_init(level);
729 level->sens = 0; /* actual value set in define_dominance */
730 ebitmap_init(&level->cat); /* actual value set in define_level */
731
732 datum = (level_datum_t *) malloc(sizeof(level_datum_t));
733 if (!datum) {
734 yyerror("out of memory");
735 goto bad;
736 }
737 level_datum_init(datum);
738 datum->isalias = FALSE;
739 datum->level = level;
740
741 ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value);
742 switch (ret) {
743 case -3:{
744 yyerror("Out of memory!");
745 goto bad;
746 }
747 case -2:{
748 yyerror("duplicate declaration of sensitivity level");
749 goto bad;
750 }
751 case -1:{
752 yyerror("could not declare sensitivity level here");
753 goto bad;
754 }
755 case 0:
756 case 1:{
757 break;
758 }
759 default:{
760 assert(0); /* should never get here */
761 }
762 }
763
764 while ((id = queue_remove(id_queue))) {
765 if (id_has_dot(id)) {
766 yyerror("sensitivity aliases may not contain periods");
767 goto bad_alias;
768 }
769 aliasdatum = (level_datum_t *) malloc(sizeof(level_datum_t));
770 if (!aliasdatum) {
771 yyerror("out of memory");
772 goto bad_alias;
773 }
774 level_datum_init(aliasdatum);
775 aliasdatum->isalias = TRUE;
776 aliasdatum->level = level;
777
778 ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value);
779 switch (ret) {
780 case -3:{
781 yyerror("Out of memory!");
782 goto bad_alias;
783 }
784 case -2:{
785 yyerror
786 ("duplicate declaration of sensitivity alias");
787 goto bad_alias;
788 }
789 case -1:{
790 yyerror
791 ("could not declare sensitivity alias here");
792 goto bad_alias;
793 }
794 case 0:
795 case 1:{
796 break;
797 }
798 default:{
799 assert(0); /* should never get here */
800 }
801 }
802 }
803
804 return 0;
805
806 bad:
807 if (id)
808 free(id);
809 if (level)
810 free(level);
811 if (datum) {
812 level_datum_destroy(datum);
813 free(datum);
814 }
815 return -1;
816
817 bad_alias:
818 if (id)
819 free(id);
820 if (aliasdatum) {
821 level_datum_destroy(aliasdatum);
822 free(aliasdatum);
823 }
824 return -1;
825}
826
827int define_dominance(void)
828{
829 level_datum_t *datum;
830 int order;
831 char *id;
832
833 if (!mlspol) {
834 yyerror("dominance definition in non-MLS configuration");
835 return -1;
836 }
837
838 if (pass == 2) {
839 while ((id = queue_remove(id_queue)))
840 free(id);
841 return 0;
842 }
843
844 order = 0;
845 while ((id = (char *)queue_remove(id_queue))) {
846 datum =
847 (level_datum_t *) hashtab_search(policydbp->p_levels.table,
848 (hashtab_key_t) id);
849 if (!datum) {
850 yyerror2("unknown sensitivity %s used in dominance "
851 "definition", id);
852 free(id);
853 return -1;
854 }
855 if (datum->level->sens != 0) {
856 yyerror2("sensitivity %s occurs multiply in dominance "
857 "definition", id);
858 free(id);
859 return -1;
860 }
861 datum->level->sens = ++order;
862
863 /* no need to keep sensitivity name */
864 free(id);
865 }
866
867 if (order != policydbp->p_levels.nprim) {
868 yyerror
869 ("all sensitivities must be specified in dominance definition");
870 return -1;
871 }
872 return 0;
873}
874
875int define_category(void)
876{
877 char *id;
878 cat_datum_t *datum = 0, *aliasdatum = 0;
879 int ret;
880 uint32_t value;
881
882 if (!mlspol) {
883 yyerror("category definition in non-MLS configuration");
884 return -1;
885 }
886
887 if (pass == 2) {
888 while ((id = queue_remove(id_queue)))
889 free(id);
890 return 0;
891 }
892
893 id = (char *)queue_remove(id_queue);
894 if (!id) {
895 yyerror("no category name for category definition?");
896 return -1;
897 }
898 if (id_has_dot(id)) {
899 yyerror("category identifiers may not contain periods");
900 goto bad;
901 }
902 datum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
903 if (!datum) {
904 yyerror("out of memory");
905 goto bad;
906 }
907 cat_datum_init(datum);
908 datum->isalias = FALSE;
909
910 ret = declare_symbol(SYM_CATS, id, datum, &value, &value);
911 switch (ret) {
912 case -3:{
913 yyerror("Out of memory!");
914 goto bad;
915 }
916 case -2:{
917 yyerror("duplicate declaration of category");
918 goto bad;
919 }
920 case -1:{
921 yyerror("could not declare category here");
922 goto bad;
923 }
924 case 0:
925 case 1:{
926 break;
927 }
928 default:{
929 assert(0); /* should never get here */
930 }
931 }
932 datum->s.value = value;
933
934 while ((id = queue_remove(id_queue))) {
935 if (id_has_dot(id)) {
936 yyerror("category aliases may not contain periods");
937 goto bad_alias;
938 }
939 aliasdatum = (cat_datum_t *) malloc(sizeof(cat_datum_t));
940 if (!aliasdatum) {
941 yyerror("out of memory");
942 goto bad_alias;
943 }
944 cat_datum_init(aliasdatum);
945 aliasdatum->isalias = TRUE;
946 aliasdatum->s.value = datum->s.value;
947
948 ret =
949 declare_symbol(SYM_CATS, id, aliasdatum, NULL,
950 &datum->s.value);
951 switch (ret) {
952 case -3:{
953 yyerror("Out of memory!");
954 goto bad_alias;
955 }
956 case -2:{
957 yyerror
958 ("duplicate declaration of category aliases");
959 goto bad_alias;
960 }
961 case -1:{
962 yyerror
963 ("could not declare category aliases here");
964 goto bad_alias;
965 }
966 case 0:
967 case 1:{
968 break;
969 }
970 default:{
971 assert(0); /* should never get here */
972 }
973 }
974 }
975
976 return 0;
977
978 bad:
979 if (id)
980 free(id);
981 if (datum) {
982 cat_datum_destroy(datum);
983 free(datum);
984 }
985 return -1;
986
987 bad_alias:
988 if (id)
989 free(id);
990 if (aliasdatum) {
991 cat_datum_destroy(aliasdatum);
992 free(aliasdatum);
993 }
994 return -1;
995}
996
997static int clone_level(hashtab_key_t key, hashtab_datum_t datum, void *arg)
998{
999 level_datum_t *levdatum = (level_datum_t *) datum;
1000 mls_level_t *level = (mls_level_t *) arg, *newlevel;
1001
1002 if (levdatum->level == level) {
1003 levdatum->defined = 1;
1004 if (!levdatum->isalias)
1005 return 0;
1006 newlevel = (mls_level_t *) malloc(sizeof(mls_level_t));
1007 if (!newlevel)
1008 return -1;
1009 if (mls_level_cpy(newlevel, level)) {
1010 free(newlevel);
1011 return -1;
1012 }
1013 levdatum->level = newlevel;
1014 }
1015 return 0;
1016}
1017
1018int define_level(void)
1019{
1020 char *id;
1021 level_datum_t *levdatum;
1022
1023 if (!mlspol) {
1024 yyerror("level definition in non-MLS configuration");
1025 return -1;
1026 }
1027
1028 if (pass == 2) {
1029 while ((id = queue_remove(id_queue)))
1030 free(id);
1031 return 0;
1032 }
1033
1034 id = (char *)queue_remove(id_queue);
1035 if (!id) {
1036 yyerror("no level name for level definition?");
1037 return -1;
1038 }
1039 levdatum = (level_datum_t *) hashtab_search(policydbp->p_levels.table,
1040 (hashtab_key_t) id);
1041 if (!levdatum) {
1042 yyerror2("unknown sensitivity %s used in level definition", id);
1043 free(id);
1044 return -1;
1045 }
1046 if (ebitmap_length(&levdatum->level->cat)) {
1047 yyerror2("sensitivity %s used in multiple level definitions",
1048 id);
1049 free(id);
1050 return -1;
1051 }
1052 free(id);
1053
1054 levdatum->defined = 1;
1055
1056 while ((id = queue_remove(id_queue))) {
1057 cat_datum_t *cdatum;
1058 int range_start, range_end, i;
1059
1060 if (id_has_dot(id)) {
1061 char *id_start = id;
1062 char *id_end = strchr(id, '.');
1063
1064 *(id_end++) = '\0';
1065
1066 cdatum =
1067 (cat_datum_t *) hashtab_search(policydbp->p_cats.
1068 table,
1069 (hashtab_key_t)
1070 id_start);
1071 if (!cdatum) {
1072 yyerror2("unknown category %s", id_start);
1073 free(id);
1074 return -1;
1075 }
1076 range_start = cdatum->s.value - 1;
1077 cdatum =
1078 (cat_datum_t *) hashtab_search(policydbp->p_cats.
1079 table,
1080 (hashtab_key_t)
1081 id_end);
1082 if (!cdatum) {
1083 yyerror2("unknown category %s", id_end);
1084 free(id);
1085 return -1;
1086 }
1087 range_end = cdatum->s.value - 1;
1088
1089 if (range_end < range_start) {
1090 yyerror2("category range is invalid");
1091 free(id);
1092 return -1;
1093 }
1094 } else {
1095 cdatum =
1096 (cat_datum_t *) hashtab_search(policydbp->p_cats.
1097 table,
1098 (hashtab_key_t) id);
1099 range_start = range_end = cdatum->s.value - 1;
1100 }
1101
1102 for (i = range_start; i <= range_end; i++) {
1103 if (ebitmap_set_bit(&levdatum->level->cat, i, TRUE)) {
1104 yyerror("out of memory");
1105 free(id);
1106 return -1;
1107 }
1108 }
1109
1110 free(id);
1111 }
1112
1113 if (hashtab_map
1114 (policydbp->p_levels.table, clone_level, levdatum->level)) {
1115 yyerror("out of memory");
1116 return -1;
1117 }
1118
1119 return 0;
1120}
1121
1122int define_attrib(void)
1123{
1124 if (pass == 2) {
1125 free(queue_remove(id_queue));
1126 return 0;
1127 }
1128
1129 if (declare_type(TRUE, TRUE) == NULL) {
1130 return -1;
1131 }
1132 return 0;
1133}
1134
1135static int add_aliases_to_type(type_datum_t * type)
1136{
1137 char *id;
1138 type_datum_t *aliasdatum = NULL;
1139 int ret;
1140 while ((id = queue_remove(id_queue))) {
1141 if (id_has_dot(id)) {
1142 free(id);
1143 yyerror
1144 ("type alias identifiers may not contain periods");
1145 return -1;
1146 }
1147 aliasdatum = (type_datum_t *) malloc(sizeof(type_datum_t));
1148 if (!aliasdatum) {
1149 free(id);
1150 yyerror("Out of memory!");
1151 return -1;
1152 }
1153 memset(aliasdatum, 0, sizeof(type_datum_t));
1154 aliasdatum->s.value = type->s.value;
1155
1156 ret = declare_symbol(SYM_TYPES, id, aliasdatum,
1157 NULL, &aliasdatum->s.value);
1158 switch (ret) {
1159 case -3:{
1160 yyerror("Out of memory!");
1161 goto cleanup;
1162 }
1163 case -2:{
1164 yyerror2("duplicate declaration of alias %s",
1165 id);
1166 goto cleanup;
1167 }
1168 case -1:{
1169 yyerror("could not declare alias here");
1170 goto cleanup;
1171 }
1172 case 0: break;
1173 case 1:{
1174 /* ret == 1 means the alias was required and therefore already
1175 * has a value. Set it up as an alias with a different primary. */
1176 type_datum_destroy(aliasdatum);
1177 free(aliasdatum);
1178
1179 aliasdatum = hashtab_search(policydbp->symtab[SYM_TYPES].table, id);
1180 assert(aliasdatum);
1181
1182 aliasdatum->primary = type->s.value;
1183 aliasdatum->flavor = TYPE_ALIAS;
1184
1185 break;
1186 }
1187 default:{
1188 assert(0); /* should never get here */
1189 }
1190 }
1191 }
1192 return 0;
1193 cleanup:
1194 free(id);
1195 type_datum_destroy(aliasdatum);
1196 free(aliasdatum);
1197 return -1;
1198}
1199
1200int define_typealias(void)
1201{
1202 char *id;
1203 type_datum_t *t;
1204
1205 if (pass == 2) {
1206 while ((id = queue_remove(id_queue)))
1207 free(id);
1208 return 0;
1209 }
1210
1211 id = (char *)queue_remove(id_queue);
1212 if (!id) {
1213 yyerror("no type name for typealias definition?");
1214 return -1;
1215 }
1216
1217 if (!is_id_in_scope(SYM_TYPES, id)) {
1218 yyerror2("type %s is not within scope", id);
1219 free(id);
1220 return -1;
1221 }
1222 t = hashtab_search(policydbp->p_types.table, id);
1223 if (!t || t->flavor == TYPE_ATTRIB) {
1224 yyerror2("unknown type %s, or it was already declared as an "
1225 "attribute", id);
1226 free(id);
1227 return -1;
1228 }
1229 return add_aliases_to_type(t);
1230}
1231
1232int define_typeattribute(void)
1233{
1234 char *id;
1235 type_datum_t *t, *attr;
1236
1237 if (pass == 2) {
1238 while ((id = queue_remove(id_queue)))
1239 free(id);
1240 return 0;
1241 }
1242
1243 id = (char *)queue_remove(id_queue);
1244 if (!id) {
1245 yyerror("no type name for typeattribute definition?");
1246 return -1;
1247 }
1248
1249 if (!is_id_in_scope(SYM_TYPES, id)) {
1250 yyerror2("type %s is not within scope", id);
1251 free(id);
1252 return -1;
1253 }
1254 t = hashtab_search(policydbp->p_types.table, id);
1255 if (!t || t->flavor == TYPE_ATTRIB) {
1256 yyerror2("unknown type %s", id);
1257 free(id);
1258 return -1;
1259 }
1260
1261 while ((id = queue_remove(id_queue))) {
1262 if (!is_id_in_scope(SYM_TYPES, id)) {
1263 yyerror2("attribute %s is not within scope", id);
1264 free(id);
1265 return -1;
1266 }
1267 attr = hashtab_search(policydbp->p_types.table, id);
1268 if (!attr) {
1269 /* treat it as a fatal error */
1270 yyerror2("attribute %s is not declared", id);
1271 free(id);
1272 return -1;
1273 }
1274
1275 if (attr->flavor != TYPE_ATTRIB) {
1276 yyerror2("%s is a type, not an attribute", id);
1277 free(id);
1278 return -1;
1279 }
1280
1281 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1282 yyerror("Out of memory!");
1283 return -1;
1284 }
1285
1286 if (ebitmap_set_bit(&attr->types, (t->s.value - 1), TRUE)) {
1287 yyerror("out of memory");
1288 return -1;
1289 }
1290 }
1291
1292 return 0;
1293}
1294
1295static int define_typebounds_helper(char *bounds_id, char *type_id)
1296{
1297 type_datum_t *bounds, *type;
1298
1299 if (!is_id_in_scope(SYM_TYPES, bounds_id)) {
1300 yyerror2("type %s is not within scope", bounds_id);
1301 return -1;
1302 }
1303
1304 bounds = hashtab_search(policydbp->p_types.table, bounds_id);
1305 if (!bounds || bounds->flavor == TYPE_ATTRIB) {
1306 yyerror2("hoge unknown type %s", bounds_id);
1307 return -1;
1308 }
1309
1310 if (!is_id_in_scope(SYM_TYPES, type_id)) {
1311 yyerror2("type %s is not within scope", type_id);
1312 return -1;
1313 }
1314
1315 type = hashtab_search(policydbp->p_types.table, type_id);
1316 if (!type || type->flavor == TYPE_ATTRIB) {
1317 yyerror2("type %s is not declared", type_id);
1318 return -1;
1319 }
1320
1321 if (type->flavor == TYPE_TYPE && !type->primary) {
1322 type = policydbp->type_val_to_struct[type->s.value - 1];
1323 } else if (type->flavor == TYPE_ALIAS) {
1324 type = policydbp->type_val_to_struct[type->primary - 1];
1325 }
1326
1327 if (!type->bounds)
1328 type->bounds = bounds->s.value;
1329 else if (type->bounds != bounds->s.value) {
1330 yyerror2("type %s has inconsistent master {%s,%s}",
1331 type_id,
1332 policydbp->p_type_val_to_name[type->bounds - 1],
1333 policydbp->p_type_val_to_name[bounds->s.value - 1]);
1334 return -1;
1335 }
1336
1337 return 0;
1338}
1339
1340int define_typebounds(void)
1341{
1342 char *bounds, *id;
1343
1344 if (pass == 1) {
1345 while ((id = queue_remove(id_queue)))
1346 free(id);
1347 return 0;
1348 }
1349
1350 bounds = (char *) queue_remove(id_queue);
1351 if (!bounds) {
1352 yyerror("no type name for typebounds definition?");
1353 return -1;
1354 }
1355
1356 while ((id = queue_remove(id_queue))) {
1357 if (define_typebounds_helper(bounds, id))
1358 return -1;
1359 free(id);
1360 }
1361 free(bounds);
1362
1363 return 0;
1364}
1365
1366int define_type(int alias)
1367{
1368 char *id;
1369 type_datum_t *datum, *attr;
1370
1371 if (pass == 2) {
1372 /*
1373 * If type name contains ".", we have to define boundary
1374 * relationship implicitly to keep compatibility with
1375 * old name based hierarchy.
1376 */
1377 if ((id = queue_remove(id_queue))) {
1378 char *bounds, *delim;
1379
1380 if ((delim = strrchr(id, '.'))
1381 && (bounds = strdup(id))) {
1382 bounds[(size_t)(delim - id)] = '\0';
1383
1384 if (define_typebounds_helper(bounds, id))
1385 return -1;
1386 free(bounds);
1387 }
1388 free(id);
1389 }
1390
1391 if (alias) {
1392 while ((id = queue_remove(id_queue)))
1393 free(id);
1394 }
1395
1396 while ((id = queue_remove(id_queue)))
1397 free(id);
1398 return 0;
1399 }
1400
1401 if ((datum = declare_type(TRUE, FALSE)) == NULL) {
1402 return -1;
1403 }
1404
1405 if (alias) {
1406 if (add_aliases_to_type(datum) == -1) {
1407 return -1;
1408 }
1409 }
1410
1411 while ((id = queue_remove(id_queue))) {
1412 if (!is_id_in_scope(SYM_TYPES, id)) {
1413 yyerror2("attribute %s is not within scope", id);
1414 free(id);
1415 return -1;
1416 }
1417 attr = hashtab_search(policydbp->p_types.table, id);
1418 if (!attr) {
1419 /* treat it as a fatal error */
1420 yyerror2("attribute %s is not declared", id);
1421 return -1;
1422 }
1423
1424 if (attr->flavor != TYPE_ATTRIB) {
1425 yyerror2("%s is a type, not an attribute", id);
1426 return -1;
1427 }
1428
1429 if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
1430 yyerror("Out of memory!");
1431 return -1;
1432 }
1433
1434 if (ebitmap_set_bit(&attr->types, datum->s.value - 1, TRUE)) {
1435 yyerror("Out of memory");
1436 return -1;
1437 }
1438 }
1439
1440 return 0;
1441}
1442
1443struct val_to_name {
1444 unsigned int val;
1445 char *name;
1446};
1447
1448/* Adds a type, given by its textual name, to a typeset. If *add is
1449 0, then add the type to the negative set; otherwise if *add is 1
1450 then add it to the positive side. */
1451static int set_types(type_set_t * set, char *id, int *add, char starallowed)
1452{
1453 type_datum_t *t;
1454
1455 if (strcmp(id, "*") == 0) {
1456 if (!starallowed) {
1457 yyerror("* not allowed in this type of rule");
1458 return -1;
1459 }
1460 /* set TYPE_STAR flag */
1461 set->flags = TYPE_STAR;
1462 free(id);
1463 *add = 1;
1464 return 0;
1465 }
1466
1467 if (strcmp(id, "~") == 0) {
1468 if (!starallowed) {
1469 yyerror("~ not allowed in this type of rule");
1470 return -1;
1471 }
1472 /* complement the set */
1473 set->flags = TYPE_COMP;
1474 free(id);
1475 *add = 1;
1476 return 0;
1477 }
1478
1479 if (strcmp(id, "-") == 0) {
1480 *add = 0;
1481 free(id);
1482 return 0;
1483 }
1484
1485 if (!is_id_in_scope(SYM_TYPES, id)) {
1486 yyerror2("type %s is not within scope", id);
1487 free(id);
1488 return -1;
1489 }
1490 t = hashtab_search(policydbp->p_types.table, id);
1491 if (!t) {
1492 yyerror2("unknown type %s", id);
1493 free(id);
1494 return -1;
1495 }
1496
1497 if (*add == 0) {
1498 if (ebitmap_set_bit(&set->negset, t->s.value - 1, TRUE))
1499 goto oom;
1500 } else {
1501 if (ebitmap_set_bit(&set->types, t->s.value - 1, TRUE))
1502 goto oom;
1503 }
1504 free(id);
1505 *add = 1;
1506 return 0;
1507 oom:
1508 yyerror("Out of memory");
1509 free(id);
1510 return -1;
1511}
1512
1513int define_compute_type_helper(int which, avrule_t ** rule)
1514{
1515 char *id;
1516 type_datum_t *datum;
SE Android8c48de12012-01-24 05:27:18 -08001517 ebitmap_t tclasses;
1518 ebitmap_node_t *node;
1519 avrule_t *avrule;
1520 class_perm_node_t *perm;
1521 int i, add = 1;
1522
1523 avrule = malloc(sizeof(avrule_t));
1524 if (!avrule) {
1525 yyerror("out of memory");
1526 return -1;
1527 }
1528 avrule_init(avrule);
1529 avrule->specified = which;
1530 avrule->line = policydb_lineno;
Stephen Smalleya5e505c2014-03-05 16:06:42 -05001531 avrule->source_line = source_lineno;
1532 avrule->source_filename = strdup(source_file);
1533 if (!avrule->source_filename) {
1534 yyerror("out of memory");
1535 return -1;
1536 }
SE Android8c48de12012-01-24 05:27:18 -08001537
1538 while ((id = queue_remove(id_queue))) {
1539 if (set_types(&avrule->stypes, id, &add, 0))
Alice Chu0d73ef72013-01-08 16:05:25 -08001540 goto bad;
SE Android8c48de12012-01-24 05:27:18 -08001541 }
1542 add = 1;
1543 while ((id = queue_remove(id_queue))) {
1544 if (set_types(&avrule->ttypes, id, &add, 0))
Alice Chu0d73ef72013-01-08 16:05:25 -08001545 goto bad;
SE Android8c48de12012-01-24 05:27:18 -08001546 }
1547
1548 ebitmap_init(&tclasses);
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05001549 if (read_classes(&tclasses))
1550 goto bad;
SE Android8c48de12012-01-24 05:27:18 -08001551
1552 id = (char *)queue_remove(id_queue);
1553 if (!id) {
1554 yyerror("no newtype?");
1555 goto bad;
1556 }
1557 if (!is_id_in_scope(SYM_TYPES, id)) {
1558 yyerror2("type %s is not within scope", id);
1559 free(id);
1560 goto bad;
1561 }
1562 datum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
1563 (hashtab_key_t) id);
1564 if (!datum || datum->flavor == TYPE_ATTRIB) {
1565 yyerror2("unknown type %s", id);
1566 goto bad;
1567 }
1568
1569 ebitmap_for_each_bit(&tclasses, node, i) {
1570 if (ebitmap_node_get_bit(node, i)) {
1571 perm = malloc(sizeof(class_perm_node_t));
1572 if (!perm) {
1573 yyerror("out of memory");
Alice Chu0d73ef72013-01-08 16:05:25 -08001574 goto bad;
SE Android8c48de12012-01-24 05:27:18 -08001575 }
1576 class_perm_node_init(perm);
1577 perm->class = i + 1;
1578 perm->data = datum->s.value;
1579 perm->next = avrule->perms;
1580 avrule->perms = perm;
1581 }
1582 }
1583 ebitmap_destroy(&tclasses);
1584
1585 *rule = avrule;
1586 return 0;
1587
1588 bad:
1589 avrule_destroy(avrule);
1590 free(avrule);
1591 return -1;
1592}
1593
1594int define_compute_type(int which)
1595{
1596 char *id;
1597 avrule_t *avrule;
1598
1599 if (pass == 1) {
1600 while ((id = queue_remove(id_queue)))
1601 free(id);
1602 while ((id = queue_remove(id_queue)))
1603 free(id);
1604 while ((id = queue_remove(id_queue)))
1605 free(id);
1606 id = queue_remove(id_queue);
1607 free(id);
1608 return 0;
1609 }
1610
1611 if (define_compute_type_helper(which, &avrule))
1612 return -1;
1613
1614 append_avrule(avrule);
1615 return 0;
1616}
1617
1618avrule_t *define_cond_compute_type(int which)
1619{
1620 char *id;
1621 avrule_t *avrule;
1622
1623 if (pass == 1) {
1624 while ((id = queue_remove(id_queue)))
1625 free(id);
1626 while ((id = queue_remove(id_queue)))
1627 free(id);
1628 while ((id = queue_remove(id_queue)))
1629 free(id);
1630 id = queue_remove(id_queue);
1631 free(id);
1632 return (avrule_t *) 1;
1633 }
1634
1635 if (define_compute_type_helper(which, &avrule))
1636 return COND_ERR;
1637
1638 return avrule;
1639}
1640
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05001641int define_bool_tunable(int is_tunable)
SE Android8c48de12012-01-24 05:27:18 -08001642{
1643 char *id, *bool_value;
1644 cond_bool_datum_t *datum;
1645 int ret;
1646 uint32_t value;
1647
1648 if (pass == 2) {
1649 while ((id = queue_remove(id_queue)))
1650 free(id);
1651 return 0;
1652 }
1653
1654 id = (char *)queue_remove(id_queue);
1655 if (!id) {
1656 yyerror("no identifier for bool definition?");
1657 return -1;
1658 }
1659 if (id_has_dot(id)) {
1660 free(id);
1661 yyerror("boolean identifiers may not contain periods");
1662 return -1;
1663 }
1664 datum = (cond_bool_datum_t *) malloc(sizeof(cond_bool_datum_t));
1665 if (!datum) {
1666 yyerror("out of memory");
1667 free(id);
1668 return -1;
1669 }
1670 memset(datum, 0, sizeof(cond_bool_datum_t));
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05001671 if (is_tunable)
1672 datum->flags |= COND_BOOL_FLAGS_TUNABLE;
SE Android8c48de12012-01-24 05:27:18 -08001673 ret = declare_symbol(SYM_BOOLS, id, datum, &value, &value);
1674 switch (ret) {
1675 case -3:{
1676 yyerror("Out of memory!");
1677 goto cleanup;
1678 }
1679 case -2:{
1680 yyerror2("duplicate declaration of boolean %s", id);
1681 goto cleanup;
1682 }
1683 case -1:{
1684 yyerror("could not declare boolean here");
1685 goto cleanup;
1686 }
1687 case 0:
1688 case 1:{
1689 break;
1690 }
1691 default:{
1692 assert(0); /* should never get here */
1693 }
1694 }
1695 datum->s.value = value;
1696
1697 bool_value = (char *)queue_remove(id_queue);
1698 if (!bool_value) {
1699 yyerror("no default value for bool definition?");
1700 free(id);
1701 return -1;
1702 }
1703
1704 datum->state = (int)(bool_value[0] == 'T') ? 1 : 0;
1705 return 0;
1706 cleanup:
1707 cond_destroy_bool(id, datum, NULL);
1708 return -1;
1709}
1710
1711avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl)
1712{
1713 if (pass == 1) {
1714 /* return something so we get through pass 1 */
1715 return (avrule_t *) 1;
1716 }
1717
1718 if (sl == NULL) {
1719 /* This is a require block, return previous list */
1720 return avlist;
1721 }
1722
1723 /* prepend the new avlist to the pre-existing one */
1724 sl->next = avlist;
1725 return sl;
1726}
1727
1728int define_te_avtab_helper(int which, avrule_t ** rule)
1729{
1730 char *id;
1731 class_datum_t *cladatum;
1732 perm_datum_t *perdatum = NULL;
1733 class_perm_node_t *perms, *tail = NULL, *cur_perms = NULL;
1734 ebitmap_t tclasses;
1735 ebitmap_node_t *node;
1736 avrule_t *avrule;
1737 unsigned int i;
1738 int add = 1, ret = 0;
1739 int suppress = 0;
1740
1741 avrule = (avrule_t *) malloc(sizeof(avrule_t));
1742 if (!avrule) {
1743 yyerror("memory error");
1744 ret = -1;
1745 goto out;
1746 }
1747 avrule_init(avrule);
1748 avrule->specified = which;
1749 avrule->line = policydb_lineno;
Stephen Smalleya5e505c2014-03-05 16:06:42 -05001750 avrule->source_line = source_lineno;
1751 avrule->source_filename = strdup(source_file);
1752 if (!avrule->source_filename) {
1753 yyerror("out of memory");
1754 return -1;
1755 }
1756
SE Android8c48de12012-01-24 05:27:18 -08001757
1758 while ((id = queue_remove(id_queue))) {
1759 if (set_types
1760 (&avrule->stypes, id, &add,
1761 which == AVRULE_NEVERALLOW ? 1 : 0)) {
1762 ret = -1;
1763 goto out;
1764 }
1765 }
1766 add = 1;
1767 while ((id = queue_remove(id_queue))) {
1768 if (strcmp(id, "self") == 0) {
1769 free(id);
1770 avrule->flags |= RULE_SELF;
1771 continue;
1772 }
1773 if (set_types
1774 (&avrule->ttypes, id, &add,
1775 which == AVRULE_NEVERALLOW ? 1 : 0)) {
1776 ret = -1;
1777 goto out;
1778 }
1779 }
1780
1781 ebitmap_init(&tclasses);
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05001782 ret = read_classes(&tclasses);
1783 if (ret)
1784 goto out;
SE Android8c48de12012-01-24 05:27:18 -08001785
1786 perms = NULL;
1787 ebitmap_for_each_bit(&tclasses, node, i) {
1788 if (!ebitmap_node_get_bit(node, i))
1789 continue;
1790 cur_perms =
1791 (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
1792 if (!cur_perms) {
1793 yyerror("out of memory");
1794 ret = -1;
1795 goto out;
1796 }
1797 class_perm_node_init(cur_perms);
1798 cur_perms->class = i + 1;
1799 if (!perms)
1800 perms = cur_perms;
1801 if (tail)
1802 tail->next = cur_perms;
1803 tail = cur_perms;
1804 }
1805
1806 while ((id = queue_remove(id_queue))) {
1807 cur_perms = perms;
1808 ebitmap_for_each_bit(&tclasses, node, i) {
1809 if (!ebitmap_node_get_bit(node, i))
1810 continue;
1811 cladatum = policydbp->class_val_to_struct[i];
1812
1813 if (strcmp(id, "*") == 0) {
1814 /* set all permissions in the class */
1815 cur_perms->data = ~0U;
1816 goto next;
1817 }
1818
1819 if (strcmp(id, "~") == 0) {
1820 /* complement the set */
1821 if (which == AVRULE_DONTAUDIT)
1822 yywarn("dontaudit rule with a ~?");
1823 cur_perms->data = ~cur_perms->data;
1824 goto next;
1825 }
1826
1827 perdatum =
1828 hashtab_search(cladatum->permissions.table, id);
1829 if (!perdatum) {
1830 if (cladatum->comdatum) {
1831 perdatum =
1832 hashtab_search(cladatum->comdatum->
1833 permissions.table,
1834 id);
1835 }
1836 }
1837 if (!perdatum) {
1838 if (!suppress)
1839 yyerror2("permission %s is not defined"
1840 " for class %s", id,
1841 policydbp->p_class_val_to_name[i]);
1842 continue;
1843 } else
1844 if (!is_perm_in_scope
1845 (id, policydbp->p_class_val_to_name[i])) {
1846 if (!suppress) {
1847 yyerror2("permission %s of class %s is"
1848 " not within scope", id,
1849 policydbp->p_class_val_to_name[i]);
1850 }
1851 continue;
1852 } else {
1853 cur_perms->data |= 1U << (perdatum->s.value - 1);
1854 }
1855 next:
1856 cur_perms = cur_perms->next;
1857 }
1858
1859 free(id);
1860 }
1861
1862 ebitmap_destroy(&tclasses);
1863
1864 avrule->perms = perms;
1865 *rule = avrule;
1866
1867 out:
1868 return ret;
1869
1870}
1871
1872avrule_t *define_cond_te_avtab(int which)
1873{
1874 char *id;
1875 avrule_t *avrule;
1876 int i;
1877
1878 if (pass == 1) {
1879 for (i = 0; i < 4; i++) {
1880 while ((id = queue_remove(id_queue)))
1881 free(id);
1882 }
1883 return (avrule_t *) 1; /* any non-NULL value */
1884 }
1885
1886 if (define_te_avtab_helper(which, &avrule))
1887 return COND_ERR;
1888
1889 return avrule;
1890}
1891
1892int define_te_avtab(int which)
1893{
1894 char *id;
1895 avrule_t *avrule;
1896 int i;
1897
1898 if (pass == 1) {
1899 for (i = 0; i < 4; i++) {
1900 while ((id = queue_remove(id_queue)))
1901 free(id);
1902 }
1903 return 0;
1904 }
1905
1906 if (define_te_avtab_helper(which, &avrule))
1907 return -1;
1908
1909 /* append this avrule to the end of the current rules list */
1910 append_avrule(avrule);
1911 return 0;
1912}
1913
1914/* The role-types rule is no longer used to declare regular role or
1915 * role attribute, but solely aimed for declaring role-types associations.
1916 */
1917int define_role_types(void)
1918{
1919 role_datum_t *role;
1920 char *id;
1921 int add = 1;
1922
1923 if (pass == 1) {
1924 while ((id = queue_remove(id_queue)))
1925 free(id);
1926 return 0;
1927 }
1928
1929 id = (char *)queue_remove(id_queue);
1930 if (!id) {
1931 yyerror("no role name for role-types rule?");
1932 return -1;
1933 }
1934
1935 if (!is_id_in_scope(SYM_ROLES, id)) {
1936 yyerror2("role %s is not within scope", id);
1937 free(id);
1938 return -1;
1939 }
1940
1941 role = hashtab_search(policydbp->p_roles.table, id);
1942 if (!role) {
1943 yyerror2("unknown role %s", id);
1944 free(id);
1945 return -1;
1946 }
1947
1948 while ((id = queue_remove(id_queue))) {
1949 if (set_types(&role->types, id, &add, 0))
1950 return -1;
1951 }
1952
1953 return 0;
1954}
1955
1956int define_attrib_role(void)
1957{
1958 if (pass == 2) {
1959 free(queue_remove(id_queue));
1960 return 0;
1961 }
1962
1963 /* Declare a role attribute */
1964 if (declare_role(TRUE) == NULL)
1965 return -1;
1966
1967 return 0;
1968}
1969
1970int define_role_attr(void)
1971{
1972 char *id;
1973 role_datum_t *r, *attr;
1974
1975 if (pass == 2) {
1976 while ((id = queue_remove(id_queue)))
1977 free(id);
1978 return 0;
1979 }
1980
1981 /* Declare a regular role */
1982 if ((r = declare_role(FALSE)) == NULL)
1983 return -1;
1984
1985 while ((id = queue_remove(id_queue))) {
1986 if (!is_id_in_scope(SYM_ROLES, id)) {
1987 yyerror2("attribute %s is not within scope", id);
1988 free(id);
1989 return -1;
1990 }
1991 attr = hashtab_search(policydbp->p_roles.table, id);
1992 if (!attr) {
1993 /* treat it as a fatal error */
1994 yyerror2("role attribute %s is not declared", id);
1995 free(id);
1996 return -1;
1997 }
1998
1999 if (attr->flavor != ROLE_ATTRIB) {
2000 yyerror2("%s is a regular role, not an attribute", id);
2001 free(id);
2002 return -1;
2003 }
2004
2005 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2006 yyerror("Out of memory!");
2007 return -1;
2008 }
2009
2010 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2011 yyerror("out of memory");
2012 return -1;
2013 }
2014 }
2015
2016 return 0;
2017}
2018
2019int define_roleattribute(void)
2020{
2021 char *id;
2022 role_datum_t *r, *attr;
2023
2024 if (pass == 2) {
2025 while ((id = queue_remove(id_queue)))
2026 free(id);
2027 return 0;
2028 }
2029
2030 id = (char *)queue_remove(id_queue);
2031 if (!id) {
2032 yyerror("no role name for roleattribute definition?");
2033 return -1;
2034 }
2035
2036 if (!is_id_in_scope(SYM_ROLES, id)) {
2037 yyerror2("role %s is not within scope", id);
2038 free(id);
2039 return -1;
2040 }
2041 r = hashtab_search(policydbp->p_roles.table, id);
2042 /* We support adding one role attribute into another */
2043 if (!r) {
2044 yyerror2("unknown role %s", id);
2045 free(id);
2046 return -1;
2047 }
2048
2049 while ((id = queue_remove(id_queue))) {
2050 if (!is_id_in_scope(SYM_ROLES, id)) {
2051 yyerror2("attribute %s is not within scope", id);
2052 free(id);
2053 return -1;
2054 }
2055 attr = hashtab_search(policydbp->p_roles.table, id);
2056 if (!attr) {
2057 /* treat it as a fatal error */
2058 yyerror2("role attribute %s is not declared", id);
2059 free(id);
2060 return -1;
2061 }
2062
2063 if (attr->flavor != ROLE_ATTRIB) {
2064 yyerror2("%s is a regular role, not an attribute", id);
2065 free(id);
2066 return -1;
2067 }
2068
2069 if ((attr = get_local_role(id, attr->s.value, 1)) == NULL) {
2070 yyerror("Out of memory!");
2071 return -1;
2072 }
2073
2074 if (ebitmap_set_bit(&attr->roles, (r->s.value - 1), TRUE)) {
2075 yyerror("out of memory");
2076 return -1;
2077 }
2078 }
2079
2080 return 0;
2081}
2082
2083role_datum_t *merge_roles_dom(role_datum_t * r1, role_datum_t * r2)
2084{
2085 role_datum_t *new;
2086
2087 if (pass == 1) {
2088 return (role_datum_t *) 1; /* any non-NULL value */
2089 }
2090
2091 new = malloc(sizeof(role_datum_t));
2092 if (!new) {
2093 yyerror("out of memory");
2094 return NULL;
2095 }
2096 memset(new, 0, sizeof(role_datum_t));
2097 new->s.value = 0; /* temporary role */
2098 if (ebitmap_or(&new->dominates, &r1->dominates, &r2->dominates)) {
2099 yyerror("out of memory");
Alice Chu0d73ef72013-01-08 16:05:25 -08002100 free(new);
SE Android8c48de12012-01-24 05:27:18 -08002101 return NULL;
2102 }
2103 if (ebitmap_or(&new->types.types, &r1->types.types, &r2->types.types)) {
2104 yyerror("out of memory");
Alice Chu0d73ef72013-01-08 16:05:25 -08002105 free(new);
SE Android8c48de12012-01-24 05:27:18 -08002106 return NULL;
2107 }
2108 if (!r1->s.value) {
2109 /* free intermediate result */
2110 type_set_destroy(&r1->types);
2111 ebitmap_destroy(&r1->dominates);
2112 free(r1);
2113 }
2114 if (!r2->s.value) {
2115 /* free intermediate result */
2116 yyerror("right hand role is temporary?");
2117 type_set_destroy(&r2->types);
2118 ebitmap_destroy(&r2->dominates);
2119 free(r2);
2120 }
2121 return new;
2122}
2123
2124/* This function eliminates the ordering dependency of role dominance rule */
2125static int dominate_role_recheck(hashtab_key_t key, hashtab_datum_t datum,
2126 void *arg)
2127{
2128 role_datum_t *rdp = (role_datum_t *) arg;
2129 role_datum_t *rdatum = (role_datum_t *) datum;
2130 ebitmap_node_t *node;
2131 int i;
2132
2133 /* Don't bother to process against self role */
2134 if (rdatum->s.value == rdp->s.value)
2135 return 0;
2136
2137 /* If a dominating role found */
2138 if (ebitmap_get_bit(&(rdatum->dominates), rdp->s.value - 1)) {
2139 ebitmap_t types;
2140 ebitmap_init(&types);
2141 if (type_set_expand(&rdp->types, &types, policydbp, 1)) {
2142 ebitmap_destroy(&types);
2143 return -1;
2144 }
2145 /* raise types and dominates from dominated role */
2146 ebitmap_for_each_bit(&rdp->dominates, node, i) {
2147 if (ebitmap_node_get_bit(node, i))
2148 if (ebitmap_set_bit
2149 (&rdatum->dominates, i, TRUE))
2150 goto oom;
2151 }
2152 ebitmap_for_each_bit(&types, node, i) {
2153 if (ebitmap_node_get_bit(node, i))
2154 if (ebitmap_set_bit
2155 (&rdatum->types.types, i, TRUE))
2156 goto oom;
2157 }
2158 ebitmap_destroy(&types);
2159 }
2160
2161 /* go through all the roles */
2162 return 0;
2163 oom:
2164 yyerror("Out of memory");
2165 return -1;
2166}
2167
2168role_datum_t *define_role_dom(role_datum_t * r)
2169{
2170 role_datum_t *role;
2171 char *role_id;
2172 ebitmap_node_t *node;
2173 unsigned int i;
2174 int ret;
2175
2176 if (pass == 1) {
2177 role_id = queue_remove(id_queue);
2178 free(role_id);
2179 return (role_datum_t *) 1; /* any non-NULL value */
2180 }
2181
2182 yywarn("Role dominance has been deprecated");
2183
2184 role_id = queue_remove(id_queue);
2185 if (!is_id_in_scope(SYM_ROLES, role_id)) {
2186 yyerror2("role %s is not within scope", role_id);
2187 free(role_id);
2188 return NULL;
2189 }
2190 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
2191 role_id);
2192 if (!role) {
2193 role = (role_datum_t *) malloc(sizeof(role_datum_t));
2194 if (!role) {
2195 yyerror("out of memory");
2196 free(role_id);
2197 return NULL;
2198 }
2199 memset(role, 0, sizeof(role_datum_t));
2200 ret =
2201 declare_symbol(SYM_ROLES, (hashtab_key_t) role_id,
2202 (hashtab_datum_t) role, &role->s.value,
2203 &role->s.value);
2204 switch (ret) {
2205 case -3:{
2206 yyerror("Out of memory!");
2207 goto cleanup;
2208 }
2209 case -2:{
2210 yyerror2("duplicate declaration of role %s",
2211 role_id);
2212 goto cleanup;
2213 }
2214 case -1:{
2215 yyerror("could not declare role here");
2216 goto cleanup;
2217 }
2218 case 0:
2219 case 1:{
2220 break;
2221 }
2222 default:{
2223 assert(0); /* should never get here */
2224 }
2225 }
2226 if (ebitmap_set_bit(&role->dominates, role->s.value - 1, TRUE)) {
2227 yyerror("Out of memory!");
2228 goto cleanup;
2229 }
2230 }
2231 if (r) {
2232 ebitmap_t types;
2233 ebitmap_init(&types);
2234 ebitmap_for_each_bit(&r->dominates, node, i) {
2235 if (ebitmap_node_get_bit(node, i))
2236 if (ebitmap_set_bit(&role->dominates, i, TRUE))
2237 goto oom;
2238 }
2239 if (type_set_expand(&r->types, &types, policydbp, 1)) {
2240 ebitmap_destroy(&types);
2241 return NULL;
2242 }
2243 ebitmap_for_each_bit(&types, node, i) {
2244 if (ebitmap_node_get_bit(node, i))
2245 if (ebitmap_set_bit
2246 (&role->types.types, i, TRUE))
2247 goto oom;
2248 }
2249 ebitmap_destroy(&types);
2250 if (!r->s.value) {
2251 /* free intermediate result */
2252 type_set_destroy(&r->types);
2253 ebitmap_destroy(&r->dominates);
2254 free(r);
2255 }
2256 /*
2257 * Now go through all the roles and escalate this role's
2258 * dominates and types if a role dominates this role.
2259 */
2260 hashtab_map(policydbp->p_roles.table,
2261 dominate_role_recheck, role);
2262 }
2263 return role;
2264 cleanup:
2265 free(role_id);
2266 role_datum_destroy(role);
2267 free(role);
2268 return NULL;
2269 oom:
2270 yyerror("Out of memory");
2271 goto cleanup;
2272}
2273
2274static int role_val_to_name_helper(hashtab_key_t key, hashtab_datum_t datum,
2275 void *p)
2276{
2277 struct val_to_name *v = p;
2278 role_datum_t *roldatum;
2279
2280 roldatum = (role_datum_t *) datum;
2281
2282 if (v->val == roldatum->s.value) {
2283 v->name = key;
2284 return 1;
2285 }
2286
2287 return 0;
2288}
2289
2290static char *role_val_to_name(unsigned int val)
2291{
2292 struct val_to_name v;
2293 int rc;
2294
2295 v.val = val;
2296 rc = hashtab_map(policydbp->p_roles.table, role_val_to_name_helper, &v);
2297 if (rc)
2298 return v.name;
2299 return NULL;
2300}
2301
2302static int set_roles(role_set_t * set, char *id)
2303{
2304 role_datum_t *r;
2305
2306 if (strcmp(id, "*") == 0) {
2307 free(id);
2308 yyerror("* is not allowed for role sets");
2309 return -1;
2310 }
2311
2312 if (strcmp(id, "~") == 0) {
2313 free(id);
2314 yyerror("~ is not allowed for role sets");
2315 return -1;
2316 }
2317 if (!is_id_in_scope(SYM_ROLES, id)) {
2318 yyerror2("role %s is not within scope", id);
2319 free(id);
2320 return -1;
2321 }
2322 r = hashtab_search(policydbp->p_roles.table, id);
2323 if (!r) {
2324 yyerror2("unknown role %s", id);
2325 free(id);
2326 return -1;
2327 }
2328
2329 if (ebitmap_set_bit(&set->roles, r->s.value - 1, TRUE)) {
2330 yyerror("out of memory");
2331 free(id);
2332 return -1;
2333 }
2334 free(id);
2335 return 0;
2336}
2337
2338int define_role_trans(int class_specified)
2339{
2340 char *id;
2341 role_datum_t *role;
2342 role_set_t roles;
2343 type_set_t types;
2344 class_datum_t *cladatum;
2345 ebitmap_t e_types, e_roles, e_classes;
2346 ebitmap_node_t *tnode, *rnode, *cnode;
2347 struct role_trans *tr = NULL;
2348 struct role_trans_rule *rule = NULL;
2349 unsigned int i, j, k;
2350 int add = 1;
2351
2352 if (pass == 1) {
2353 while ((id = queue_remove(id_queue)))
2354 free(id);
2355 while ((id = queue_remove(id_queue)))
2356 free(id);
2357 if (class_specified)
2358 while ((id = queue_remove(id_queue)))
2359 free(id);
2360 id = queue_remove(id_queue);
2361 free(id);
2362 return 0;
2363 }
2364
2365 role_set_init(&roles);
2366 ebitmap_init(&e_roles);
2367 type_set_init(&types);
2368 ebitmap_init(&e_types);
2369 ebitmap_init(&e_classes);
2370
2371 while ((id = queue_remove(id_queue))) {
2372 if (set_roles(&roles, id))
2373 return -1;
2374 }
2375 add = 1;
2376 while ((id = queue_remove(id_queue))) {
2377 if (set_types(&types, id, &add, 0))
2378 return -1;
2379 }
2380
2381 if (class_specified) {
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05002382 if (read_classes(&e_classes))
2383 return -1;
SE Android8c48de12012-01-24 05:27:18 -08002384 } else {
2385 cladatum = hashtab_search(policydbp->p_classes.table,
2386 "process");
2387 if (!cladatum) {
2388 yyerror2("could not find process class for "
2389 "legacy role_transition statement");
2390 return -1;
2391 }
2392
Stephen Smalleyba8e9922012-09-25 10:57:09 -04002393 if (ebitmap_set_bit(&e_classes, cladatum->s.value - 1, TRUE)) {
2394 yyerror("out of memory");
2395 return -1;
2396 }
SE Android8c48de12012-01-24 05:27:18 -08002397 }
2398
2399 id = (char *)queue_remove(id_queue);
2400 if (!id) {
2401 yyerror("no new role in transition definition?");
2402 goto bad;
2403 }
2404 if (!is_id_in_scope(SYM_ROLES, id)) {
2405 yyerror2("role %s is not within scope", id);
2406 free(id);
2407 goto bad;
2408 }
2409 role = hashtab_search(policydbp->p_roles.table, id);
2410 if (!role) {
2411 yyerror2("unknown role %s used in transition definition", id);
2412 goto bad;
2413 }
2414
2415 if (role->flavor != ROLE_ROLE) {
2416 yyerror2("the new role %s must be a regular role", id);
2417 goto bad;
2418 }
2419
2420 /* This ebitmap business is just to ensure that there are not conflicting role_trans rules */
2421 if (role_set_expand(&roles, &e_roles, policydbp, NULL, NULL))
2422 goto bad;
2423
2424 if (type_set_expand(&types, &e_types, policydbp, 1))
2425 goto bad;
2426
2427 ebitmap_for_each_bit(&e_roles, rnode, i) {
2428 if (!ebitmap_node_get_bit(rnode, i))
2429 continue;
2430 ebitmap_for_each_bit(&e_types, tnode, j) {
2431 if (!ebitmap_node_get_bit(tnode, j))
2432 continue;
2433 ebitmap_for_each_bit(&e_classes, cnode, k) {
2434 if (!ebitmap_node_get_bit(cnode, k))
2435 continue;
2436 for (tr = policydbp->role_tr; tr;
2437 tr = tr->next) {
2438 if (tr->role == (i + 1) &&
2439 tr->type == (j + 1) &&
2440 tr->tclass == (k + 1)) {
2441 yyerror2("duplicate role "
2442 "transition for "
2443 "(%s,%s,%s)",
2444 role_val_to_name(i+1),
2445 policydbp->p_type_val_to_name[j],
2446 policydbp->p_class_val_to_name[k]);
2447 goto bad;
2448 }
2449 }
2450
2451 tr = malloc(sizeof(struct role_trans));
2452 if (!tr) {
2453 yyerror("out of memory");
2454 return -1;
2455 }
2456 memset(tr, 0, sizeof(struct role_trans));
2457 tr->role = i + 1;
2458 tr->type = j + 1;
2459 tr->tclass = k + 1;
2460 tr->new_role = role->s.value;
2461 tr->next = policydbp->role_tr;
2462 policydbp->role_tr = tr;
2463 }
2464 }
2465 }
2466 /* Now add the real rule */
2467 rule = malloc(sizeof(struct role_trans_rule));
2468 if (!rule) {
2469 yyerror("out of memory");
2470 return -1;
2471 }
2472 memset(rule, 0, sizeof(struct role_trans_rule));
2473 rule->roles = roles;
2474 rule->types = types;
2475 rule->classes = e_classes;
2476 rule->new_role = role->s.value;
2477
2478 append_role_trans(rule);
2479
2480 ebitmap_destroy(&e_roles);
2481 ebitmap_destroy(&e_types);
2482
2483 return 0;
2484
2485 bad:
2486 return -1;
2487}
2488
2489int define_role_allow(void)
2490{
2491 char *id;
2492 struct role_allow_rule *ra = 0;
2493
2494 if (pass == 1) {
2495 while ((id = queue_remove(id_queue)))
2496 free(id);
2497 while ((id = queue_remove(id_queue)))
2498 free(id);
2499 return 0;
2500 }
2501
2502 ra = malloc(sizeof(role_allow_rule_t));
2503 if (!ra) {
2504 yyerror("out of memory");
2505 return -1;
2506 }
2507 role_allow_rule_init(ra);
2508
2509 while ((id = queue_remove(id_queue))) {
Alice Chu0d73ef72013-01-08 16:05:25 -08002510 if (set_roles(&ra->roles, id)) {
2511 free(ra);
SE Android8c48de12012-01-24 05:27:18 -08002512 return -1;
Alice Chu0d73ef72013-01-08 16:05:25 -08002513 }
SE Android8c48de12012-01-24 05:27:18 -08002514 }
2515
2516 while ((id = queue_remove(id_queue))) {
Alice Chu0d73ef72013-01-08 16:05:25 -08002517 if (set_roles(&ra->new_roles, id)) {
2518 free(ra);
SE Android8c48de12012-01-24 05:27:18 -08002519 return -1;
Alice Chu0d73ef72013-01-08 16:05:25 -08002520 }
SE Android8c48de12012-01-24 05:27:18 -08002521 }
2522
2523 append_role_allow(ra);
2524 return 0;
2525}
2526
2527avrule_t *define_cond_filename_trans(void)
2528{
2529 yyerror("type transitions with a filename not allowed inside "
2530 "conditionals\n");
2531 return COND_ERR;
2532}
2533
2534int define_filename_trans(void)
2535{
2536 char *id, *name = NULL;
2537 type_set_t stypes, ttypes;
2538 ebitmap_t e_stypes, e_ttypes;
2539 ebitmap_t e_tclasses;
2540 ebitmap_node_t *snode, *tnode, *cnode;
2541 filename_trans_t *ft;
2542 filename_trans_rule_t *ftr;
SE Android8c48de12012-01-24 05:27:18 -08002543 type_datum_t *typdatum;
2544 uint32_t otype;
2545 unsigned int c, s, t;
2546 int add;
2547
2548 if (pass == 1) {
2549 /* stype */
2550 while ((id = queue_remove(id_queue)))
2551 free(id);
2552 /* ttype */
2553 while ((id = queue_remove(id_queue)))
2554 free(id);
2555 /* tclass */
2556 while ((id = queue_remove(id_queue)))
2557 free(id);
2558 /* otype */
2559 id = queue_remove(id_queue);
2560 free(id);
2561 /* name */
2562 id = queue_remove(id_queue);
2563 free(id);
2564 return 0;
2565 }
2566
2567
2568 add = 1;
2569 type_set_init(&stypes);
2570 while ((id = queue_remove(id_queue))) {
2571 if (set_types(&stypes, id, &add, 0))
2572 goto bad;
2573 }
2574
2575 add =1;
2576 type_set_init(&ttypes);
2577 while ((id = queue_remove(id_queue))) {
2578 if (set_types(&ttypes, id, &add, 0))
2579 goto bad;
2580 }
2581
2582 ebitmap_init(&e_tclasses);
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05002583 if (read_classes(&e_tclasses))
2584 goto bad;
SE Android8c48de12012-01-24 05:27:18 -08002585
2586 id = (char *)queue_remove(id_queue);
2587 if (!id) {
2588 yyerror("no otype in transition definition?");
2589 goto bad;
2590 }
2591 if (!is_id_in_scope(SYM_TYPES, id)) {
2592 yyerror2("type %s is not within scope", id);
2593 free(id);
2594 goto bad;
2595 }
2596 typdatum = hashtab_search(policydbp->p_types.table, id);
2597 if (!typdatum) {
2598 yyerror2("unknown type %s used in transition definition", id);
2599 goto bad;
2600 }
2601 free(id);
2602 otype = typdatum->s.value;
2603
2604 name = queue_remove(id_queue);
2605 if (!name) {
2606 yyerror("no pathname specified in filename_trans definition?");
2607 goto bad;
2608 }
2609
2610 /* We expand the class set into seperate rules. We expand the types
2611 * just to make sure there are not duplicates. They will get turned
2612 * into seperate rules later */
2613 ebitmap_init(&e_stypes);
2614 if (type_set_expand(&stypes, &e_stypes, policydbp, 1))
2615 goto bad;
2616
2617 ebitmap_init(&e_ttypes);
2618 if (type_set_expand(&ttypes, &e_ttypes, policydbp, 1))
2619 goto bad;
2620
2621 ebitmap_for_each_bit(&e_tclasses, cnode, c) {
2622 if (!ebitmap_node_get_bit(cnode, c))
2623 continue;
2624 ebitmap_for_each_bit(&e_stypes, snode, s) {
2625 if (!ebitmap_node_get_bit(snode, s))
2626 continue;
2627 ebitmap_for_each_bit(&e_ttypes, tnode, t) {
2628 if (!ebitmap_node_get_bit(tnode, t))
2629 continue;
2630
2631 for (ft = policydbp->filename_trans; ft; ft = ft->next) {
2632 if (ft->stype == (s + 1) &&
2633 ft->ttype == (t + 1) &&
2634 ft->tclass == (c + 1) &&
2635 !strcmp(ft->name, name)) {
2636 yyerror2("duplicate filename transition for: filename_trans %s %s %s:%s",
2637 name,
2638 policydbp->p_type_val_to_name[s],
2639 policydbp->p_type_val_to_name[t],
2640 policydbp->p_class_val_to_name[c]);
2641 goto bad;
2642 }
2643 }
2644
2645 ft = malloc(sizeof(*ft));
2646 if (!ft) {
2647 yyerror("out of memory");
2648 goto bad;
2649 }
2650 memset(ft, 0, sizeof(*ft));
2651
2652 ft->next = policydbp->filename_trans;
2653 policydbp->filename_trans = ft;
2654
2655 ft->name = strdup(name);
2656 if (!ft->name) {
2657 yyerror("out of memory");
2658 goto bad;
2659 }
2660 ft->stype = s + 1;
2661 ft->ttype = t + 1;
2662 ft->tclass = c + 1;
2663 ft->otype = otype;
2664 }
2665 }
2666
2667 /* Now add the real rule since we didn't find any duplicates */
2668 ftr = malloc(sizeof(*ftr));
2669 if (!ftr) {
2670 yyerror("out of memory");
2671 goto bad;
2672 }
2673 filename_trans_rule_init(ftr);
2674 append_filename_trans(ftr);
2675
2676 ftr->name = strdup(name);
2677 ftr->stypes = stypes;
2678 ftr->ttypes = ttypes;
2679 ftr->tclass = c + 1;
2680 ftr->otype = otype;
2681 }
2682
2683 free(name);
2684 ebitmap_destroy(&e_stypes);
2685 ebitmap_destroy(&e_ttypes);
2686 ebitmap_destroy(&e_tclasses);
2687
2688 return 0;
2689
2690bad:
2691 free(name);
2692 return -1;
2693}
2694
2695static constraint_expr_t *constraint_expr_clone(constraint_expr_t * expr)
2696{
2697 constraint_expr_t *h = NULL, *l = NULL, *e, *newe;
2698 for (e = expr; e; e = e->next) {
2699 newe = malloc(sizeof(*newe));
2700 if (!newe)
2701 goto oom;
2702 if (constraint_expr_init(newe) == -1) {
2703 free(newe);
2704 goto oom;
2705 }
2706 if (l)
2707 l->next = newe;
2708 else
2709 h = newe;
2710 l = newe;
2711 newe->expr_type = e->expr_type;
2712 newe->attr = e->attr;
2713 newe->op = e->op;
2714 if (newe->expr_type == CEXPR_NAMES) {
2715 if (newe->attr & CEXPR_TYPE) {
2716 if (type_set_cpy
2717 (newe->type_names, e->type_names))
2718 goto oom;
2719 } else {
2720 if (ebitmap_cpy(&newe->names, &e->names))
2721 goto oom;
2722 }
2723 }
2724 }
2725
2726 return h;
2727 oom:
2728 e = h;
2729 while (e) {
2730 l = e;
2731 e = e->next;
2732 constraint_expr_destroy(l);
2733 }
2734 return NULL;
2735}
2736
2737int define_constraint(constraint_expr_t * expr)
2738{
2739 struct constraint_node *node;
2740 char *id;
2741 class_datum_t *cladatum;
2742 perm_datum_t *perdatum;
2743 ebitmap_t classmap;
2744 ebitmap_node_t *enode;
2745 constraint_expr_t *e;
2746 unsigned int i;
2747 int depth;
2748 unsigned char useexpr = 1;
2749
2750 if (pass == 1) {
2751 while ((id = queue_remove(id_queue)))
2752 free(id);
2753 while ((id = queue_remove(id_queue)))
2754 free(id);
2755 return 0;
2756 }
2757
2758 depth = -1;
2759 for (e = expr; e; e = e->next) {
2760 switch (e->expr_type) {
2761 case CEXPR_NOT:
2762 if (depth < 0) {
2763 yyerror("illegal constraint expression");
2764 return -1;
2765 }
2766 break;
2767 case CEXPR_AND:
2768 case CEXPR_OR:
2769 if (depth < 1) {
2770 yyerror("illegal constraint expression");
2771 return -1;
2772 }
2773 depth--;
2774 break;
2775 case CEXPR_ATTR:
2776 case CEXPR_NAMES:
2777 if (e->attr & CEXPR_XTARGET) {
2778 yyerror("illegal constraint expression");
2779 return -1; /* only for validatetrans rules */
2780 }
2781 if (depth == (CEXPR_MAXDEPTH - 1)) {
2782 yyerror("constraint expression is too deep");
2783 return -1;
2784 }
2785 depth++;
2786 break;
2787 default:
2788 yyerror("illegal constraint expression");
2789 return -1;
2790 }
2791 }
2792 if (depth != 0) {
2793 yyerror("illegal constraint expression");
2794 return -1;
2795 }
2796
2797 ebitmap_init(&classmap);
2798 while ((id = queue_remove(id_queue))) {
2799 if (!is_id_in_scope(SYM_CLASSES, id)) {
2800 yyerror2("class %s is not within scope", id);
2801 free(id);
2802 return -1;
2803 }
2804 cladatum =
2805 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2806 (hashtab_key_t) id);
2807 if (!cladatum) {
2808 yyerror2("class %s is not defined", id);
2809 ebitmap_destroy(&classmap);
2810 free(id);
2811 return -1;
2812 }
2813 if (ebitmap_set_bit(&classmap, cladatum->s.value - 1, TRUE)) {
2814 yyerror("out of memory");
2815 ebitmap_destroy(&classmap);
2816 free(id);
2817 return -1;
2818 }
2819 node = malloc(sizeof(struct constraint_node));
2820 if (!node) {
2821 yyerror("out of memory");
Stephen Smalley968aed02013-10-30 15:38:49 -04002822 free(node);
SE Android8c48de12012-01-24 05:27:18 -08002823 return -1;
2824 }
2825 memset(node, 0, sizeof(constraint_node_t));
2826 if (useexpr) {
2827 node->expr = expr;
2828 useexpr = 0;
2829 } else {
2830 node->expr = constraint_expr_clone(expr);
2831 }
2832 if (!node->expr) {
2833 yyerror("out of memory");
Alice Chu0d73ef72013-01-08 16:05:25 -08002834 free(node);
SE Android8c48de12012-01-24 05:27:18 -08002835 return -1;
2836 }
2837 node->permissions = 0;
2838
2839 node->next = cladatum->constraints;
2840 cladatum->constraints = node;
2841
2842 free(id);
2843 }
2844
2845 while ((id = queue_remove(id_queue))) {
2846 ebitmap_for_each_bit(&classmap, enode, i) {
2847 if (ebitmap_node_get_bit(enode, i)) {
2848 cladatum = policydbp->class_val_to_struct[i];
2849 node = cladatum->constraints;
2850
2851 perdatum =
2852 (perm_datum_t *) hashtab_search(cladatum->
2853 permissions.
2854 table,
2855 (hashtab_key_t)
2856 id);
2857 if (!perdatum) {
2858 if (cladatum->comdatum) {
2859 perdatum =
2860 (perm_datum_t *)
2861 hashtab_search(cladatum->
2862 comdatum->
2863 permissions.
2864 table,
2865 (hashtab_key_t)
2866 id);
2867 }
2868 if (!perdatum) {
2869 yyerror2("permission %s is not"
2870 " defined", id);
2871 free(id);
2872 ebitmap_destroy(&classmap);
2873 return -1;
2874 }
2875 }
2876 node->permissions |=
2877 (1 << (perdatum->s.value - 1));
2878 }
2879 }
2880 free(id);
2881 }
2882
2883 ebitmap_destroy(&classmap);
2884
2885 return 0;
2886}
2887
2888int define_validatetrans(constraint_expr_t * expr)
2889{
2890 struct constraint_node *node;
2891 char *id;
2892 class_datum_t *cladatum;
2893 ebitmap_t classmap;
2894 constraint_expr_t *e;
2895 int depth;
2896 unsigned char useexpr = 1;
2897
2898 if (pass == 1) {
2899 while ((id = queue_remove(id_queue)))
2900 free(id);
2901 return 0;
2902 }
2903
2904 depth = -1;
2905 for (e = expr; e; e = e->next) {
2906 switch (e->expr_type) {
2907 case CEXPR_NOT:
2908 if (depth < 0) {
2909 yyerror("illegal validatetrans expression");
2910 return -1;
2911 }
2912 break;
2913 case CEXPR_AND:
2914 case CEXPR_OR:
2915 if (depth < 1) {
2916 yyerror("illegal validatetrans expression");
2917 return -1;
2918 }
2919 depth--;
2920 break;
2921 case CEXPR_ATTR:
2922 case CEXPR_NAMES:
2923 if (depth == (CEXPR_MAXDEPTH - 1)) {
2924 yyerror("validatetrans expression is too deep");
2925 return -1;
2926 }
2927 depth++;
2928 break;
2929 default:
2930 yyerror("illegal validatetrans expression");
2931 return -1;
2932 }
2933 }
2934 if (depth != 0) {
2935 yyerror("illegal validatetrans expression");
2936 return -1;
2937 }
2938
2939 ebitmap_init(&classmap);
2940 while ((id = queue_remove(id_queue))) {
2941 if (!is_id_in_scope(SYM_CLASSES, id)) {
2942 yyerror2("class %s is not within scope", id);
2943 free(id);
2944 return -1;
2945 }
2946 cladatum =
2947 (class_datum_t *) hashtab_search(policydbp->p_classes.table,
2948 (hashtab_key_t) id);
2949 if (!cladatum) {
2950 yyerror2("class %s is not defined", id);
2951 ebitmap_destroy(&classmap);
2952 free(id);
2953 return -1;
2954 }
2955 if (ebitmap_set_bit(&classmap, (cladatum->s.value - 1), TRUE)) {
2956 yyerror("out of memory");
2957 ebitmap_destroy(&classmap);
2958 free(id);
2959 return -1;
2960 }
2961
2962 node = malloc(sizeof(struct constraint_node));
2963 if (!node) {
2964 yyerror("out of memory");
2965 return -1;
2966 }
2967 memset(node, 0, sizeof(constraint_node_t));
2968 if (useexpr) {
2969 node->expr = expr;
2970 useexpr = 0;
2971 } else {
2972 node->expr = constraint_expr_clone(expr);
2973 }
2974 node->permissions = 0;
2975
2976 node->next = cladatum->validatetrans;
2977 cladatum->validatetrans = node;
2978
2979 free(id);
2980 }
2981
2982 ebitmap_destroy(&classmap);
2983
2984 return 0;
2985}
2986
2987uintptr_t define_cexpr(uint32_t expr_type, uintptr_t arg1, uintptr_t arg2)
2988{
2989 struct constraint_expr *expr, *e1 = NULL, *e2;
2990 user_datum_t *user;
2991 role_datum_t *role;
2992 ebitmap_t negset;
2993 char *id;
2994 uint32_t val;
2995 int add = 1;
2996
2997 if (pass == 1) {
2998 if (expr_type == CEXPR_NAMES) {
2999 while ((id = queue_remove(id_queue)))
3000 free(id);
3001 }
3002 return 1; /* any non-NULL value */
3003 }
3004
3005 if ((expr = malloc(sizeof(*expr))) == NULL ||
3006 constraint_expr_init(expr) == -1) {
3007 yyerror("out of memory");
3008 free(expr);
3009 return 0;
3010 }
3011 expr->expr_type = expr_type;
3012
3013 switch (expr_type) {
3014 case CEXPR_NOT:
3015 e1 = NULL;
3016 e2 = (struct constraint_expr *)arg1;
3017 while (e2) {
3018 e1 = e2;
3019 e2 = e2->next;
3020 }
3021 if (!e1 || e1->next) {
3022 yyerror("illegal constraint expression");
3023 constraint_expr_destroy(expr);
3024 return 0;
3025 }
3026 e1->next = expr;
3027 return arg1;
3028 case CEXPR_AND:
3029 case CEXPR_OR:
3030 e1 = NULL;
3031 e2 = (struct constraint_expr *)arg1;
3032 while (e2) {
3033 e1 = e2;
3034 e2 = e2->next;
3035 }
3036 if (!e1 || e1->next) {
3037 yyerror("illegal constraint expression");
3038 constraint_expr_destroy(expr);
3039 return 0;
3040 }
3041 e1->next = (struct constraint_expr *)arg2;
3042
3043 e1 = NULL;
3044 e2 = (struct constraint_expr *)arg2;
3045 while (e2) {
3046 e1 = e2;
3047 e2 = e2->next;
3048 }
3049 if (!e1 || e1->next) {
3050 yyerror("illegal constraint expression");
3051 constraint_expr_destroy(expr);
3052 return 0;
3053 }
3054 e1->next = expr;
3055 return arg1;
3056 case CEXPR_ATTR:
3057 expr->attr = arg1;
3058 expr->op = arg2;
3059 return (uintptr_t) expr;
3060 case CEXPR_NAMES:
3061 add = 1;
3062 expr->attr = arg1;
3063 expr->op = arg2;
3064 ebitmap_init(&negset);
3065 while ((id = (char *)queue_remove(id_queue))) {
3066 if (expr->attr & CEXPR_USER) {
3067 if (!is_id_in_scope(SYM_USERS, id)) {
3068 yyerror2("user %s is not within scope",
3069 id);
3070 constraint_expr_destroy(expr);
3071 return 0;
3072 }
3073 user =
3074 (user_datum_t *) hashtab_search(policydbp->
3075 p_users.
3076 table,
3077 (hashtab_key_t)
3078 id);
3079 if (!user) {
3080 yyerror2("unknown user %s", id);
3081 constraint_expr_destroy(expr);
3082 return 0;
3083 }
3084 val = user->s.value;
3085 } else if (expr->attr & CEXPR_ROLE) {
3086 if (!is_id_in_scope(SYM_ROLES, id)) {
3087 yyerror2("role %s is not within scope",
3088 id);
3089 constraint_expr_destroy(expr);
3090 return 0;
3091 }
3092 role =
3093 (role_datum_t *) hashtab_search(policydbp->
3094 p_roles.
3095 table,
3096 (hashtab_key_t)
3097 id);
3098 if (!role) {
3099 yyerror2("unknown role %s", id);
3100 constraint_expr_destroy(expr);
3101 return 0;
3102 }
3103 val = role->s.value;
3104 } else if (expr->attr & CEXPR_TYPE) {
3105 if (set_types(expr->type_names, id, &add, 0)) {
3106 constraint_expr_destroy(expr);
3107 return 0;
3108 }
3109 continue;
3110 } else {
3111 yyerror("invalid constraint expression");
3112 constraint_expr_destroy(expr);
3113 return 0;
3114 }
3115 if (ebitmap_set_bit(&expr->names, val - 1, TRUE)) {
3116 yyerror("out of memory");
3117 ebitmap_destroy(&expr->names);
3118 constraint_expr_destroy(expr);
3119 return 0;
3120 }
3121 free(id);
3122 }
3123 ebitmap_destroy(&negset);
3124 return (uintptr_t) expr;
3125 default:
Stephen Smalley968aed02013-10-30 15:38:49 -04003126 break;
SE Android8c48de12012-01-24 05:27:18 -08003127 }
3128
3129 yyerror("invalid constraint expression");
Stephen Smalley968aed02013-10-30 15:38:49 -04003130 constraint_expr_destroy(expr);
SE Android8c48de12012-01-24 05:27:18 -08003131 return 0;
3132}
3133
3134int define_conditional(cond_expr_t * expr, avrule_t * t, avrule_t * f)
3135{
3136 cond_expr_t *e;
3137 int depth;
3138 cond_node_t cn, *cn_old;
3139
3140 /* expression cannot be NULL */
3141 if (!expr) {
3142 yyerror("illegal conditional expression");
3143 return -1;
3144 }
3145 if (!t) {
3146 if (!f) {
3147 /* empty is fine, destroy expression and return */
3148 cond_expr_destroy(expr);
3149 return 0;
3150 }
3151 /* Invert */
3152 t = f;
3153 f = 0;
3154 expr = define_cond_expr(COND_NOT, expr, 0);
3155 if (!expr) {
3156 yyerror("unable to invert");
3157 return -1;
3158 }
3159 }
3160
3161 /* verify expression */
3162 depth = -1;
3163 for (e = expr; e; e = e->next) {
3164 switch (e->expr_type) {
3165 case COND_NOT:
3166 if (depth < 0) {
3167 yyerror
3168 ("illegal conditional expression; Bad NOT");
3169 return -1;
3170 }
3171 break;
3172 case COND_AND:
3173 case COND_OR:
3174 case COND_XOR:
3175 case COND_EQ:
3176 case COND_NEQ:
3177 if (depth < 1) {
3178 yyerror
3179 ("illegal conditional expression; Bad binary op");
3180 return -1;
3181 }
3182 depth--;
3183 break;
3184 case COND_BOOL:
3185 if (depth == (COND_EXPR_MAXDEPTH - 1)) {
3186 yyerror
3187 ("conditional expression is like totally too deep");
3188 return -1;
3189 }
3190 depth++;
3191 break;
3192 default:
3193 yyerror("illegal conditional expression");
3194 return -1;
3195 }
3196 }
3197 if (depth != 0) {
3198 yyerror("illegal conditional expression");
3199 return -1;
3200 }
3201
3202 /* use tmp conditional node to partially build new node */
3203 memset(&cn, 0, sizeof(cn));
3204 cn.expr = expr;
3205 cn.avtrue_list = t;
3206 cn.avfalse_list = f;
3207
3208 /* normalize/precompute expression */
3209 if (cond_normalize_expr(policydbp, &cn) < 0) {
3210 yyerror("problem normalizing conditional expression");
3211 return -1;
3212 }
3213
3214 /* get the existing conditional node, or create a new one */
3215 cn_old = get_current_cond_list(&cn);
3216 if (!cn_old) {
3217 return -1;
3218 }
3219
3220 append_cond_list(&cn);
3221
3222 /* note that there is no check here for duplicate rules, nor
3223 * check that rule already exists in base -- that will be
3224 * handled during conditional expansion, in expand.c */
3225
3226 cn.avtrue_list = NULL;
3227 cn.avfalse_list = NULL;
3228 cond_node_destroy(&cn);
3229
3230 return 0;
3231}
3232
3233cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void *arg2)
3234{
3235 struct cond_expr *expr, *e1 = NULL, *e2;
3236 cond_bool_datum_t *bool_var;
3237 char *id;
3238
3239 /* expressions are handled in the second pass */
3240 if (pass == 1) {
3241 if (expr_type == COND_BOOL) {
3242 while ((id = queue_remove(id_queue))) {
3243 free(id);
3244 }
3245 }
3246 return (cond_expr_t *) 1; /* any non-NULL value */
3247 }
3248
3249 /* create a new expression struct */
3250 expr = malloc(sizeof(struct cond_expr));
3251 if (!expr) {
3252 yyerror("out of memory");
3253 return NULL;
3254 }
3255 memset(expr, 0, sizeof(cond_expr_t));
3256 expr->expr_type = expr_type;
3257
3258 /* create the type asked for */
3259 switch (expr_type) {
3260 case COND_NOT:
3261 e1 = NULL;
3262 e2 = (struct cond_expr *)arg1;
3263 while (e2) {
3264 e1 = e2;
3265 e2 = e2->next;
3266 }
3267 if (!e1 || e1->next) {
3268 yyerror("illegal conditional NOT expression");
3269 free(expr);
3270 return NULL;
3271 }
3272 e1->next = expr;
3273 return (struct cond_expr *)arg1;
3274 case COND_AND:
3275 case COND_OR:
3276 case COND_XOR:
3277 case COND_EQ:
3278 case COND_NEQ:
3279 e1 = NULL;
3280 e2 = (struct cond_expr *)arg1;
3281 while (e2) {
3282 e1 = e2;
3283 e2 = e2->next;
3284 }
3285 if (!e1 || e1->next) {
3286 yyerror
3287 ("illegal left side of conditional binary op expression");
3288 free(expr);
3289 return NULL;
3290 }
3291 e1->next = (struct cond_expr *)arg2;
3292
3293 e1 = NULL;
3294 e2 = (struct cond_expr *)arg2;
3295 while (e2) {
3296 e1 = e2;
3297 e2 = e2->next;
3298 }
3299 if (!e1 || e1->next) {
3300 yyerror
3301 ("illegal right side of conditional binary op expression");
3302 free(expr);
3303 return NULL;
3304 }
3305 e1->next = expr;
3306 return (struct cond_expr *)arg1;
3307 case COND_BOOL:
3308 id = (char *)queue_remove(id_queue);
3309 if (!id) {
3310 yyerror("bad conditional; expected boolean id");
3311 free(id);
3312 free(expr);
3313 return NULL;
3314 }
3315 if (!is_id_in_scope(SYM_BOOLS, id)) {
3316 yyerror2("boolean %s is not within scope", id);
3317 free(id);
3318 free(expr);
3319 return NULL;
3320 }
3321 bool_var =
3322 (cond_bool_datum_t *) hashtab_search(policydbp->p_bools.
3323 table,
3324 (hashtab_key_t) id);
3325 if (!bool_var) {
3326 yyerror2("unknown boolean %s in conditional expression",
3327 id);
3328 free(expr);
3329 free(id);
3330 return NULL;
3331 }
3332 expr->bool = bool_var->s.value;
3333 free(id);
3334 return expr;
3335 default:
3336 yyerror("illegal conditional expression");
Alice Chu0d73ef72013-01-08 16:05:25 -08003337 free(expr);
SE Android8c48de12012-01-24 05:27:18 -08003338 return NULL;
3339 }
3340}
3341
3342static int set_user_roles(role_set_t * set, char *id)
3343{
3344 role_datum_t *r;
3345 unsigned int i;
3346 ebitmap_node_t *node;
3347
3348 if (strcmp(id, "*") == 0) {
3349 free(id);
3350 yyerror("* is not allowed in user declarations");
3351 return -1;
3352 }
3353
3354 if (strcmp(id, "~") == 0) {
3355 free(id);
3356 yyerror("~ is not allowed in user declarations");
3357 return -1;
3358 }
3359
3360 if (!is_id_in_scope(SYM_ROLES, id)) {
3361 yyerror2("role %s is not within scope", id);
3362 free(id);
3363 return -1;
3364 }
3365 r = hashtab_search(policydbp->p_roles.table, id);
3366 if (!r) {
3367 yyerror2("unknown role %s", id);
3368 free(id);
3369 return -1;
3370 }
3371
3372 /* set the role and every role it dominates */
3373 ebitmap_for_each_bit(&r->dominates, node, i) {
3374 if (ebitmap_node_get_bit(node, i))
3375 if (ebitmap_set_bit(&set->roles, i, TRUE))
3376 goto oom;
3377 }
3378 free(id);
3379 return 0;
3380 oom:
3381 yyerror("out of memory");
3382 return -1;
3383}
3384
3385static int parse_categories(char *id, level_datum_t * levdatum, ebitmap_t * cats)
3386{
3387 cat_datum_t *cdatum;
3388 int range_start, range_end, i;
3389
3390 if (id_has_dot(id)) {
3391 char *id_start = id;
3392 char *id_end = strchr(id, '.');
3393
3394 *(id_end++) = '\0';
3395
3396 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3397 (hashtab_key_t)
3398 id_start);
3399 if (!cdatum) {
3400 yyerror2("unknown category %s", id_start);
3401 return -1;
3402 }
3403 range_start = cdatum->s.value - 1;
3404 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3405 (hashtab_key_t) id_end);
3406 if (!cdatum) {
3407 yyerror2("unknown category %s", id_end);
3408 return -1;
3409 }
3410 range_end = cdatum->s.value - 1;
3411
3412 if (range_end < range_start) {
3413 yyerror2("category range is invalid");
3414 return -1;
3415 }
3416 } else {
3417 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3418 (hashtab_key_t) id);
3419 if (!cdatum) {
3420 yyerror2("unknown category %s", id);
3421 return -1;
3422 }
3423 range_start = range_end = cdatum->s.value - 1;
3424 }
3425
3426 for (i = range_start; i <= range_end; i++) {
3427 if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
3428 uint32_t level_value = levdatum->level->sens - 1;
3429 policydb_index_others(NULL, policydbp, 0);
3430 yyerror2("category %s can not be associated "
3431 "with level %s",
3432 policydbp->p_cat_val_to_name[i],
3433 policydbp->p_sens_val_to_name[level_value]);
3434 return -1;
3435 }
3436 if (ebitmap_set_bit(cats, i, TRUE)) {
3437 yyerror("out of memory");
3438 return -1;
3439 }
3440 }
3441
3442 return 0;
3443}
3444
3445static int parse_semantic_categories(char *id, level_datum_t * levdatum,
3446 mls_semantic_cat_t ** cats)
3447{
3448 cat_datum_t *cdatum;
3449 mls_semantic_cat_t *newcat;
3450 unsigned int range_start, range_end;
3451
3452 if (id_has_dot(id)) {
3453 char *id_start = id;
3454 char *id_end = strchr(id, '.');
3455
3456 *(id_end++) = '\0';
3457
3458 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3459 (hashtab_key_t)
3460 id_start);
3461 if (!cdatum) {
3462 yyerror2("unknown category %s", id_start);
3463 return -1;
3464 }
3465 range_start = cdatum->s.value;
3466
3467 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3468 (hashtab_key_t) id_end);
3469 if (!cdatum) {
3470 yyerror2("unknown category %s", id_end);
3471 return -1;
3472 }
3473 range_end = cdatum->s.value;
3474 } else {
3475 cdatum = (cat_datum_t *) hashtab_search(policydbp->p_cats.table,
3476 (hashtab_key_t) id);
3477 if (!cdatum) {
3478 yyerror2("unknown category %s", id);
3479 return -1;
3480 }
3481 range_start = range_end = cdatum->s.value;
3482 }
3483
3484 newcat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
3485 if (!newcat) {
3486 yyerror("out of memory");
3487 return -1;
3488 }
3489
3490 mls_semantic_cat_init(newcat);
3491 newcat->next = *cats;
3492 newcat->low = range_start;
3493 newcat->high = range_end;
3494
3495 *cats = newcat;
3496
3497 return 0;
3498}
3499
3500int define_user(void)
3501{
3502 char *id;
3503 user_datum_t *usrdatum;
3504 level_datum_t *levdatum;
3505 int l;
3506
3507 if (pass == 1) {
3508 while ((id = queue_remove(id_queue)))
3509 free(id);
3510 if (mlspol) {
3511 while ((id = queue_remove(id_queue)))
3512 free(id);
3513 id = queue_remove(id_queue);
3514 free(id);
3515 for (l = 0; l < 2; l++) {
3516 while ((id = queue_remove(id_queue))) {
3517 free(id);
3518 }
3519 id = queue_remove(id_queue);
3520 if (!id)
3521 break;
3522 free(id);
3523 }
3524 }
3525 return 0;
3526 }
3527
3528 if ((usrdatum = declare_user()) == NULL) {
3529 return -1;
3530 }
3531
3532 while ((id = queue_remove(id_queue))) {
3533 if (set_user_roles(&usrdatum->roles, id))
3534 continue;
3535 }
3536
3537 if (mlspol) {
3538 id = queue_remove(id_queue);
3539 if (!id) {
3540 yyerror("no default level specified for user");
3541 return -1;
3542 }
3543
3544 levdatum = (level_datum_t *)
3545 hashtab_search(policydbp->p_levels.table,
3546 (hashtab_key_t) id);
3547 if (!levdatum) {
3548 yyerror2("unknown sensitivity %s used in user"
3549 " level definition", id);
3550 free(id);
3551 return -1;
3552 }
3553 free(id);
3554
3555 usrdatum->dfltlevel.sens = levdatum->level->sens;
3556
3557 while ((id = queue_remove(id_queue))) {
3558 if (parse_semantic_categories(id, levdatum,
3559 &usrdatum->dfltlevel.cat)) {
3560 free(id);
3561 return -1;
3562 }
3563 free(id);
3564 }
3565
3566 id = queue_remove(id_queue);
3567
3568 for (l = 0; l < 2; l++) {
3569 levdatum = (level_datum_t *)
3570 hashtab_search(policydbp->p_levels.table,
3571 (hashtab_key_t) id);
3572 if (!levdatum) {
3573 yyerror2("unknown sensitivity %s used in user"
3574 " range definition", id);
3575 free(id);
3576 return -1;
3577 }
3578 free(id);
3579
3580 usrdatum->range.level[l].sens = levdatum->level->sens;
3581
3582 while ((id = queue_remove(id_queue))) {
3583 if (parse_semantic_categories(id, levdatum,
3584 &usrdatum->range.level[l].cat)) {
3585 free(id);
3586 return -1;
3587 }
3588 free(id);
3589 }
3590
3591 id = queue_remove(id_queue);
3592 if (!id)
3593 break;
3594 }
3595
3596 if (l == 0) {
3597 if (mls_semantic_level_cpy(&usrdatum->range.level[1],
3598 &usrdatum->range.level[0])) {
3599 yyerror("out of memory");
3600 return -1;
3601 }
3602 }
3603 }
3604 return 0;
3605}
3606
3607static int parse_security_context(context_struct_t * c)
3608{
3609 char *id;
3610 role_datum_t *role;
3611 type_datum_t *typdatum;
3612 user_datum_t *usrdatum;
3613 level_datum_t *levdatum;
3614 int l;
3615
3616 if (pass == 1) {
3617 id = queue_remove(id_queue);
3618 free(id); /* user */
3619 id = queue_remove(id_queue);
3620 free(id); /* role */
3621 id = queue_remove(id_queue);
3622 free(id); /* type */
3623 if (mlspol) {
3624 id = queue_remove(id_queue);
3625 free(id);
3626 for (l = 0; l < 2; l++) {
3627 while ((id = queue_remove(id_queue))) {
3628 free(id);
3629 }
3630 id = queue_remove(id_queue);
3631 if (!id)
3632 break;
3633 free(id);
3634 }
3635 }
3636 return 0;
3637 }
3638
Alice Chu0d73ef72013-01-08 16:05:25 -08003639 /* check context c to make sure ok to dereference c later */
3640 if (c == NULL) {
3641 yyerror("null context pointer!");
3642 return -1;
3643 }
3644
SE Android8c48de12012-01-24 05:27:18 -08003645 context_init(c);
3646
3647 /* extract the user */
3648 id = queue_remove(id_queue);
3649 if (!id) {
3650 yyerror("no effective user?");
3651 goto bad;
3652 }
3653 if (!is_id_in_scope(SYM_USERS, id)) {
3654 yyerror2("user %s is not within scope", id);
3655 free(id);
3656 goto bad;
3657 }
3658 usrdatum = (user_datum_t *) hashtab_search(policydbp->p_users.table,
3659 (hashtab_key_t) id);
3660 if (!usrdatum) {
3661 yyerror2("user %s is not defined", id);
3662 free(id);
3663 goto bad;
3664 }
3665 c->user = usrdatum->s.value;
3666
3667 /* no need to keep the user name */
3668 free(id);
3669
3670 /* extract the role */
3671 id = (char *)queue_remove(id_queue);
3672 if (!id) {
3673 yyerror("no role name for sid context definition?");
3674 return -1;
3675 }
3676 if (!is_id_in_scope(SYM_ROLES, id)) {
3677 yyerror2("role %s is not within scope", id);
3678 free(id);
3679 return -1;
3680 }
3681 role = (role_datum_t *) hashtab_search(policydbp->p_roles.table,
3682 (hashtab_key_t) id);
3683 if (!role) {
3684 yyerror2("role %s is not defined", id);
3685 free(id);
3686 return -1;
3687 }
3688 c->role = role->s.value;
3689
3690 /* no need to keep the role name */
3691 free(id);
3692
3693 /* extract the type */
3694 id = (char *)queue_remove(id_queue);
3695 if (!id) {
3696 yyerror("no type name for sid context definition?");
3697 return -1;
3698 }
3699 if (!is_id_in_scope(SYM_TYPES, id)) {
3700 yyerror2("type %s is not within scope", id);
3701 free(id);
3702 return -1;
3703 }
3704 typdatum = (type_datum_t *) hashtab_search(policydbp->p_types.table,
3705 (hashtab_key_t) id);
3706 if (!typdatum || typdatum->flavor == TYPE_ATTRIB) {
3707 yyerror2("type %s is not defined or is an attribute", id);
3708 free(id);
3709 return -1;
3710 }
3711 c->type = typdatum->s.value;
3712
3713 /* no need to keep the type name */
3714 free(id);
3715
3716 if (mlspol) {
3717 /* extract the low sensitivity */
3718 id = (char *)queue_head(id_queue);
3719 if (!id) {
3720 yyerror("no sensitivity name for sid context"
3721 " definition?");
3722 return -1;
3723 }
3724
3725 id = (char *)queue_remove(id_queue);
3726 for (l = 0; l < 2; l++) {
3727 levdatum = (level_datum_t *)
3728 hashtab_search(policydbp->p_levels.table,
3729 (hashtab_key_t) id);
3730 if (!levdatum) {
3731 yyerror2("Sensitivity %s is not defined", id);
3732 free(id);
3733 return -1;
3734 }
3735 free(id);
3736 c->range.level[l].sens = levdatum->level->sens;
3737
3738 /* extract low category set */
3739 while ((id = queue_remove(id_queue))) {
3740 if (parse_categories(id, levdatum,
3741 &c->range.level[l].cat)) {
3742 free(id);
3743 return -1;
3744 }
3745 free(id);
3746 }
3747
3748 /* extract high sensitivity */
3749 id = (char *)queue_remove(id_queue);
3750 if (!id)
3751 break;
3752 }
3753
3754 if (l == 0) {
3755 c->range.level[1].sens = c->range.level[0].sens;
3756 if (ebitmap_cpy(&c->range.level[1].cat,
3757 &c->range.level[0].cat)) {
3758
3759 yyerror("out of memory");
3760 goto bad;
3761 }
3762 }
3763 }
3764
3765 if (!policydb_context_isvalid(policydbp, c)) {
3766 yyerror("invalid security context");
3767 goto bad;
3768 }
3769 return 0;
3770
3771 bad:
3772 context_destroy(c);
3773
3774 return -1;
3775}
3776
3777int define_initial_sid_context(void)
3778{
3779 char *id;
3780 ocontext_t *c, *head;
3781
3782 if (pass == 1) {
3783 id = (char *)queue_remove(id_queue);
3784 free(id);
3785 parse_security_context(NULL);
3786 return 0;
3787 }
3788
3789 id = (char *)queue_remove(id_queue);
3790 if (!id) {
3791 yyerror("no sid name for SID context definition?");
3792 return -1;
3793 }
3794 head = policydbp->ocontexts[OCON_ISID];
3795 for (c = head; c; c = c->next) {
3796 if (!strcmp(id, c->u.name))
3797 break;
3798 }
3799
3800 if (!c) {
3801 yyerror2("SID %s is not defined", id);
3802 free(id);
3803 return -1;
3804 }
3805 if (c->context[0].user) {
3806 yyerror2("The context for SID %s is multiply defined", id);
3807 free(id);
3808 return -1;
3809 }
3810 /* no need to keep the sid name */
3811 free(id);
3812
3813 if (parse_security_context(&c->context[0]))
3814 return -1;
3815
3816 return 0;
3817}
3818
3819int define_fs_context(unsigned int major, unsigned int minor)
3820{
3821 ocontext_t *newc, *c, *head;
3822
3823 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
3824 yyerror("fscon not supported for target");
3825 return -1;
3826 }
3827
3828 if (pass == 1) {
3829 parse_security_context(NULL);
3830 parse_security_context(NULL);
3831 return 0;
3832 }
3833
3834 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
3835 if (!newc) {
3836 yyerror("out of memory");
3837 return -1;
3838 }
3839 memset(newc, 0, sizeof(ocontext_t));
3840
3841 newc->u.name = (char *)malloc(6);
3842 if (!newc->u.name) {
3843 yyerror("out of memory");
3844 free(newc);
3845 return -1;
3846 }
3847 sprintf(newc->u.name, "%02x:%02x", major, minor);
3848
3849 if (parse_security_context(&newc->context[0])) {
3850 free(newc->u.name);
3851 free(newc);
3852 return -1;
3853 }
3854 if (parse_security_context(&newc->context[1])) {
3855 context_destroy(&newc->context[0]);
3856 free(newc->u.name);
3857 free(newc);
3858 return -1;
3859 }
3860 head = policydbp->ocontexts[OCON_FS];
3861
3862 for (c = head; c; c = c->next) {
3863 if (!strcmp(newc->u.name, c->u.name)) {
3864 yyerror2("duplicate entry for file system %s",
3865 newc->u.name);
3866 context_destroy(&newc->context[0]);
3867 context_destroy(&newc->context[1]);
3868 free(newc->u.name);
3869 free(newc);
3870 return -1;
3871 }
3872 }
3873
3874 newc->next = head;
3875 policydbp->ocontexts[OCON_FS] = newc;
3876
3877 return 0;
3878}
3879
3880int define_pirq_context(unsigned int pirq)
3881{
3882 ocontext_t *newc, *c, *l, *head;
3883 char *id;
3884
3885 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3886 yyerror("pirqcon not supported for target");
3887 return -1;
3888 }
3889
3890 if (pass == 1) {
3891 id = (char *) queue_remove(id_queue);
3892 free(id);
3893 parse_security_context(NULL);
3894 return 0;
3895 }
3896
3897 newc = malloc(sizeof(ocontext_t));
3898 if (!newc) {
3899 yyerror("out of memory");
3900 return -1;
3901 }
3902 memset(newc, 0, sizeof(ocontext_t));
3903
3904 newc->u.pirq = pirq;
3905
3906 if (parse_security_context(&newc->context[0])) {
3907 free(newc);
3908 return -1;
3909 }
3910
3911 head = policydbp->ocontexts[OCON_XEN_PIRQ];
3912 for (l = NULL, c = head; c; l = c, c = c->next) {
3913 unsigned int pirq2;
3914
3915 pirq2 = c->u.pirq;
3916 if (pirq == pirq2) {
3917 yyerror2("duplicate pirqcon entry for %d ", pirq);
3918 goto bad;
3919 }
3920 }
3921
3922 if (l)
3923 l->next = newc;
3924 else
3925 policydbp->ocontexts[OCON_XEN_PIRQ] = newc;
3926
3927 return 0;
3928
3929bad:
3930 free(newc);
3931 return -1;
3932}
3933
3934int define_iomem_context(unsigned long low, unsigned long high)
3935{
3936 ocontext_t *newc, *c, *l, *head;
3937 char *id;
3938
3939 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
3940 yyerror("iomemcon not supported for target");
3941 return -1;
3942 }
3943
3944 if (pass == 1) {
3945 id = (char *)queue_remove(id_queue);
3946 free(id);
3947 parse_security_context(NULL);
3948 return 0;
3949 }
3950
3951 newc = malloc(sizeof(ocontext_t));
3952 if (!newc) {
3953 yyerror("out of memory");
3954 return -1;
3955 }
3956 memset(newc, 0, sizeof(ocontext_t));
3957
3958 newc->u.iomem.low_iomem = low;
3959 newc->u.iomem.high_iomem = high;
3960
3961 if (low > high) {
3962 yyerror2("low memory 0x%x exceeds high memory 0x%x", low, high);
3963 free(newc);
3964 return -1;
3965 }
3966
3967 if (parse_security_context(&newc->context[0])) {
3968 free(newc);
3969 return -1;
3970 }
3971
3972 head = policydbp->ocontexts[OCON_XEN_IOMEM];
3973 for (l = NULL, c = head; c; l = c, c = c->next) {
3974 unsigned int low2, high2;
3975
3976 low2 = c->u.iomem.low_iomem;
3977 high2 = c->u.iomem.high_iomem;
3978 if (low <= high2 && low2 <= high) {
3979 yyerror2("iomemcon entry for 0x%x-0x%x overlaps with "
3980 "earlier entry 0x%x-0x%x", low, high,
3981 low2, high2);
3982 goto bad;
3983 }
3984 }
3985
3986 if (l)
3987 l->next = newc;
3988 else
3989 policydbp->ocontexts[OCON_XEN_IOMEM] = newc;
3990
3991 return 0;
3992
3993bad:
3994 free(newc);
3995 return -1;
3996}
3997
3998int define_ioport_context(unsigned long low, unsigned long high)
3999{
4000 ocontext_t *newc, *c, *l, *head;
4001 char *id;
4002
4003 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4004 yyerror("ioportcon not supported for target");
4005 return -1;
4006 }
4007
4008 if (pass == 1) {
4009 id = (char *)queue_remove(id_queue);
4010 free(id);
4011 parse_security_context(NULL);
4012 return 0;
4013 }
4014
4015 newc = malloc(sizeof(ocontext_t));
4016 if (!newc) {
4017 yyerror("out of memory");
4018 return -1;
4019 }
4020 memset(newc, 0, sizeof(ocontext_t));
4021
4022 newc->u.ioport.low_ioport = low;
4023 newc->u.ioport.high_ioport = high;
4024
4025 if (low > high) {
4026 yyerror2("low ioport 0x%x exceeds high ioport 0x%x", low, high);
4027 free(newc);
4028 return -1;
4029 }
4030
4031 if (parse_security_context(&newc->context[0])) {
4032 free(newc);
4033 return -1;
4034 }
4035
4036 head = policydbp->ocontexts[OCON_XEN_IOPORT];
4037 for (l = NULL, c = head; c; l = c, c = c->next) {
4038 unsigned int low2, high2;
4039
4040 low2 = c->u.ioport.low_ioport;
4041 high2 = c->u.ioport.high_ioport;
4042 if (low <= high2 && low2 <= high) {
4043 yyerror2("ioportcon entry for 0x%x-0x%x overlaps with"
4044 "earlier entry 0x%x-0x%x", low, high,
4045 low2, high2);
4046 goto bad;
4047 }
4048 }
4049
4050 if (l)
4051 l->next = newc;
4052 else
4053 policydbp->ocontexts[OCON_XEN_IOPORT] = newc;
4054
4055 return 0;
4056
4057bad:
4058 free(newc);
4059 return -1;
4060}
4061
4062int define_pcidevice_context(unsigned long device)
4063{
4064 ocontext_t *newc, *c, *l, *head;
4065 char *id;
4066
4067 if (policydbp->target_platform != SEPOL_TARGET_XEN) {
4068 yyerror("pcidevicecon not supported for target");
4069 return -1;
4070 }
4071
4072 if (pass == 1) {
4073 id = (char *) queue_remove(id_queue);
4074 free(id);
4075 parse_security_context(NULL);
4076 return 0;
4077 }
4078
4079 newc = malloc(sizeof(ocontext_t));
4080 if (!newc) {
4081 yyerror("out of memory");
4082 return -1;
4083 }
4084 memset(newc, 0, sizeof(ocontext_t));
4085
4086 newc->u.device = device;
4087
4088 if (parse_security_context(&newc->context[0])) {
4089 free(newc);
4090 return -1;
4091 }
4092
4093 head = policydbp->ocontexts[OCON_XEN_PCIDEVICE];
4094 for (l = NULL, c = head; c; l = c, c = c->next) {
4095 unsigned int device2;
4096
4097 device2 = c->u.device;
4098 if (device == device2) {
4099 yyerror2("duplicate pcidevicecon entry for 0x%x ",
4100 device);
4101 goto bad;
4102 }
4103 }
4104
4105 if (l)
4106 l->next = newc;
4107 else
4108 policydbp->ocontexts[OCON_XEN_PCIDEVICE] = newc;
4109
4110 return 0;
4111
4112bad:
4113 free(newc);
4114 return -1;
4115}
4116
4117int define_port_context(unsigned int low, unsigned int high)
4118{
4119 ocontext_t *newc, *c, *l, *head;
4120 unsigned int protocol;
4121 char *id;
4122
4123 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4124 yyerror("portcon not supported for target");
4125 return -1;
4126 }
4127
4128 if (pass == 1) {
4129 id = (char *)queue_remove(id_queue);
4130 free(id);
4131 parse_security_context(NULL);
4132 return 0;
4133 }
4134
4135 newc = malloc(sizeof(ocontext_t));
4136 if (!newc) {
4137 yyerror("out of memory");
4138 return -1;
4139 }
4140 memset(newc, 0, sizeof(ocontext_t));
4141
4142 id = (char *)queue_remove(id_queue);
4143 if (!id) {
4144 free(newc);
4145 return -1;
4146 }
4147 if ((strcmp(id, "tcp") == 0) || (strcmp(id, "TCP") == 0)) {
4148 protocol = IPPROTO_TCP;
4149 } else if ((strcmp(id, "udp") == 0) || (strcmp(id, "UDP") == 0)) {
4150 protocol = IPPROTO_UDP;
4151 } else {
4152 yyerror2("unrecognized protocol %s", id);
4153 free(newc);
4154 return -1;
4155 }
4156
4157 newc->u.port.protocol = protocol;
4158 newc->u.port.low_port = low;
4159 newc->u.port.high_port = high;
4160
4161 if (low > high) {
4162 yyerror2("low port %d exceeds high port %d", low, high);
4163 free(newc);
4164 return -1;
4165 }
4166
4167 if (parse_security_context(&newc->context[0])) {
4168 free(newc);
4169 return -1;
4170 }
4171
4172 /* Preserve the matching order specified in the configuration. */
4173 head = policydbp->ocontexts[OCON_PORT];
4174 for (l = NULL, c = head; c; l = c, c = c->next) {
4175 unsigned int prot2, low2, high2;
4176
4177 prot2 = c->u.port.protocol;
4178 low2 = c->u.port.low_port;
4179 high2 = c->u.port.high_port;
4180 if (protocol != prot2)
4181 continue;
4182 if (low == low2 && high == high2) {
4183 yyerror2("duplicate portcon entry for %s %d-%d ", id,
4184 low, high);
4185 goto bad;
4186 }
4187 if (low2 <= low && high2 >= high) {
4188 yyerror2("portcon entry for %s %d-%d hidden by earlier "
4189 "entry for %d-%d", id, low, high, low2, high2);
4190 goto bad;
4191 }
4192 }
4193
4194 if (l)
4195 l->next = newc;
4196 else
4197 policydbp->ocontexts[OCON_PORT] = newc;
4198
4199 return 0;
4200
4201 bad:
4202 free(newc);
4203 return -1;
4204}
4205
4206int define_netif_context(void)
4207{
4208 ocontext_t *newc, *c, *head;
4209
4210 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4211 yyerror("netifcon not supported for target");
4212 return -1;
4213 }
4214
4215 if (pass == 1) {
4216 free(queue_remove(id_queue));
4217 parse_security_context(NULL);
4218 parse_security_context(NULL);
4219 return 0;
4220 }
4221
4222 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4223 if (!newc) {
4224 yyerror("out of memory");
4225 return -1;
4226 }
4227 memset(newc, 0, sizeof(ocontext_t));
4228
4229 newc->u.name = (char *)queue_remove(id_queue);
4230 if (!newc->u.name) {
4231 free(newc);
4232 return -1;
4233 }
4234 if (parse_security_context(&newc->context[0])) {
4235 free(newc->u.name);
4236 free(newc);
4237 return -1;
4238 }
4239 if (parse_security_context(&newc->context[1])) {
4240 context_destroy(&newc->context[0]);
4241 free(newc->u.name);
4242 free(newc);
4243 return -1;
4244 }
4245 head = policydbp->ocontexts[OCON_NETIF];
4246
4247 for (c = head; c; c = c->next) {
4248 if (!strcmp(newc->u.name, c->u.name)) {
4249 yyerror2("duplicate entry for network interface %s",
4250 newc->u.name);
4251 context_destroy(&newc->context[0]);
4252 context_destroy(&newc->context[1]);
4253 free(newc->u.name);
4254 free(newc);
4255 return -1;
4256 }
4257 }
4258
4259 newc->next = head;
4260 policydbp->ocontexts[OCON_NETIF] = newc;
4261 return 0;
4262}
4263
4264int define_ipv4_node_context()
4265{
4266 char *id;
4267 int rc = 0;
4268 struct in_addr addr, mask;
4269 ocontext_t *newc, *c, *l, *head;
4270
4271 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4272 yyerror("nodecon not supported for target");
4273 return -1;
4274 }
4275
4276 if (pass == 1) {
4277 free(queue_remove(id_queue));
4278 free(queue_remove(id_queue));
4279 parse_security_context(NULL);
4280 goto out;
4281 }
4282
4283 id = queue_remove(id_queue);
4284 if (!id) {
4285 yyerror("failed to read ipv4 address");
4286 rc = -1;
4287 goto out;
4288 }
4289
4290 rc = inet_pton(AF_INET, id, &addr);
4291 free(id);
4292 if (rc < 1) {
4293 yyerror("failed to parse ipv4 address");
4294 if (rc == 0)
4295 rc = -1;
4296 goto out;
4297 }
4298
4299 id = queue_remove(id_queue);
4300 if (!id) {
4301 yyerror("failed to read ipv4 address");
4302 rc = -1;
4303 goto out;
4304 }
4305
4306 rc = inet_pton(AF_INET, id, &mask);
4307 free(id);
4308 if (rc < 1) {
4309 yyerror("failed to parse ipv4 mask");
4310 if (rc == 0)
4311 rc = -1;
4312 goto out;
4313 }
4314
4315 newc = malloc(sizeof(ocontext_t));
4316 if (!newc) {
4317 yyerror("out of memory");
4318 rc = -1;
4319 goto out;
4320 }
4321
4322 memset(newc, 0, sizeof(ocontext_t));
4323 newc->u.node.addr = addr.s_addr;
4324 newc->u.node.mask = mask.s_addr;
4325
4326 if (parse_security_context(&newc->context[0])) {
4327 free(newc);
4328 return -1;
4329 }
4330
4331 /* Create order of most specific to least retaining
4332 the order specified in the configuration. */
4333 head = policydbp->ocontexts[OCON_NODE];
4334 for (l = NULL, c = head; c; l = c, c = c->next) {
4335 if (newc->u.node.mask > c->u.node.mask)
4336 break;
4337 }
4338
4339 newc->next = c;
4340
4341 if (l)
4342 l->next = newc;
4343 else
4344 policydbp->ocontexts[OCON_NODE] = newc;
4345 rc = 0;
4346out:
4347 return rc;
4348}
4349
4350int define_ipv6_node_context(void)
4351{
4352 char *id;
4353 int rc = 0;
4354 struct in6_addr addr, mask;
4355 ocontext_t *newc, *c, *l, *head;
4356
4357 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4358 yyerror("nodecon not supported for target");
4359 return -1;
4360 }
4361
4362 if (pass == 1) {
4363 free(queue_remove(id_queue));
4364 free(queue_remove(id_queue));
4365 parse_security_context(NULL);
4366 goto out;
4367 }
4368
4369 id = queue_remove(id_queue);
4370 if (!id) {
4371 yyerror("failed to read ipv6 address");
4372 rc = -1;
4373 goto out;
4374 }
4375
4376 rc = inet_pton(AF_INET6, id, &addr);
4377 free(id);
4378 if (rc < 1) {
4379 yyerror("failed to parse ipv6 address");
4380 if (rc == 0)
4381 rc = -1;
4382 goto out;
4383 }
4384
4385 id = queue_remove(id_queue);
4386 if (!id) {
4387 yyerror("failed to read ipv6 address");
4388 rc = -1;
4389 goto out;
4390 }
4391
4392 rc = inet_pton(AF_INET6, id, &mask);
4393 free(id);
4394 if (rc < 1) {
4395 yyerror("failed to parse ipv6 mask");
4396 if (rc == 0)
4397 rc = -1;
4398 goto out;
4399 }
4400
4401 newc = malloc(sizeof(ocontext_t));
4402 if (!newc) {
4403 yyerror("out of memory");
4404 rc = -1;
4405 goto out;
4406 }
4407
4408 memset(newc, 0, sizeof(ocontext_t));
Stephen Smalley3fab9cd2012-01-24 08:38:01 -05004409
4410#ifdef DARWIN
4411 memcpy(&newc->u.node6.addr[0], &addr.s6_addr[0], 16);
4412 memcpy(&newc->u.node6.mask[0], &mask.s6_addr[0], 16);
4413#else
SE Android8c48de12012-01-24 05:27:18 -08004414 memcpy(&newc->u.node6.addr[0], &addr.s6_addr32[0], 16);
4415 memcpy(&newc->u.node6.mask[0], &mask.s6_addr32[0], 16);
Stephen Smalley3fab9cd2012-01-24 08:38:01 -05004416#endif
SE Android8c48de12012-01-24 05:27:18 -08004417
4418 if (parse_security_context(&newc->context[0])) {
4419 free(newc);
4420 rc = -1;
4421 goto out;
4422 }
4423
4424 /* Create order of most specific to least retaining
4425 the order specified in the configuration. */
4426 head = policydbp->ocontexts[OCON_NODE6];
4427 for (l = NULL, c = head; c; l = c, c = c->next) {
4428 if (memcmp(&newc->u.node6.mask, &c->u.node6.mask, 16) > 0)
4429 break;
4430 }
4431
4432 newc->next = c;
4433
4434 if (l)
4435 l->next = newc;
4436 else
4437 policydbp->ocontexts[OCON_NODE6] = newc;
4438
4439 rc = 0;
4440 out:
4441 return rc;
4442}
4443
4444int define_fs_use(int behavior)
4445{
4446 ocontext_t *newc, *c, *head;
4447
4448 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4449 yyerror("fsuse not supported for target");
4450 return -1;
4451 }
4452
4453 if (pass == 1) {
4454 free(queue_remove(id_queue));
4455 parse_security_context(NULL);
4456 return 0;
4457 }
4458
4459 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4460 if (!newc) {
4461 yyerror("out of memory");
4462 return -1;
4463 }
4464 memset(newc, 0, sizeof(ocontext_t));
4465
4466 newc->u.name = (char *)queue_remove(id_queue);
4467 if (!newc->u.name) {
4468 free(newc);
4469 return -1;
4470 }
4471 newc->v.behavior = behavior;
4472 if (parse_security_context(&newc->context[0])) {
4473 free(newc->u.name);
4474 free(newc);
4475 return -1;
4476 }
4477
4478 head = policydbp->ocontexts[OCON_FSUSE];
4479
4480 for (c = head; c; c = c->next) {
4481 if (!strcmp(newc->u.name, c->u.name)) {
4482 yyerror2("duplicate fs_use entry for filesystem type %s",
4483 newc->u.name);
4484 context_destroy(&newc->context[0]);
4485 free(newc->u.name);
4486 free(newc);
4487 return -1;
4488 }
4489 }
4490
4491 newc->next = head;
4492 policydbp->ocontexts[OCON_FSUSE] = newc;
4493 return 0;
4494}
4495
4496int define_genfs_context_helper(char *fstype, int has_type)
4497{
4498 struct genfs *genfs_p, *genfs, *newgenfs;
4499 ocontext_t *newc, *c, *head, *p;
4500 char *type = NULL;
4501 int len, len2;
4502
4503 if (policydbp->target_platform != SEPOL_TARGET_SELINUX) {
4504 yyerror("genfs not supported for target");
4505 return -1;
4506 }
4507
4508 if (pass == 1) {
4509 free(fstype);
4510 free(queue_remove(id_queue));
4511 if (has_type)
4512 free(queue_remove(id_queue));
4513 parse_security_context(NULL);
4514 return 0;
4515 }
4516
4517 for (genfs_p = NULL, genfs = policydbp->genfs;
4518 genfs; genfs_p = genfs, genfs = genfs->next) {
4519 if (strcmp(fstype, genfs->fstype) <= 0)
4520 break;
4521 }
4522
4523 if (!genfs || strcmp(fstype, genfs->fstype)) {
4524 newgenfs = malloc(sizeof(struct genfs));
4525 if (!newgenfs) {
4526 yyerror("out of memory");
4527 return -1;
4528 }
4529 memset(newgenfs, 0, sizeof(struct genfs));
4530 newgenfs->fstype = fstype;
4531 newgenfs->next = genfs;
4532 if (genfs_p)
4533 genfs_p->next = newgenfs;
4534 else
4535 policydbp->genfs = newgenfs;
4536 genfs = newgenfs;
4537 }
4538
4539 newc = (ocontext_t *) malloc(sizeof(ocontext_t));
4540 if (!newc) {
4541 yyerror("out of memory");
4542 return -1;
4543 }
4544 memset(newc, 0, sizeof(ocontext_t));
4545
4546 newc->u.name = (char *)queue_remove(id_queue);
4547 if (!newc->u.name)
4548 goto fail;
4549 if (has_type) {
4550 type = (char *)queue_remove(id_queue);
4551 if (!type)
4552 goto fail;
4553 if (type[1] != 0) {
4554 yyerror2("invalid type %s", type);
4555 goto fail;
4556 }
4557 switch (type[0]) {
4558 case 'b':
4559 newc->v.sclass = SECCLASS_BLK_FILE;
4560 break;
4561 case 'c':
4562 newc->v.sclass = SECCLASS_CHR_FILE;
4563 break;
4564 case 'd':
4565 newc->v.sclass = SECCLASS_DIR;
4566 break;
4567 case 'p':
4568 newc->v.sclass = SECCLASS_FIFO_FILE;
4569 break;
4570 case 'l':
4571 newc->v.sclass = SECCLASS_LNK_FILE;
4572 break;
4573 case 's':
4574 newc->v.sclass = SECCLASS_SOCK_FILE;
4575 break;
4576 case '-':
4577 newc->v.sclass = SECCLASS_FILE;
4578 break;
4579 default:
4580 yyerror2("invalid type %s", type);
4581 goto fail;
4582 }
4583 }
4584 if (parse_security_context(&newc->context[0]))
4585 goto fail;
4586
4587 head = genfs->head;
4588
4589 for (p = NULL, c = head; c; p = c, c = c->next) {
4590 if (!strcmp(newc->u.name, c->u.name) &&
4591 (!newc->v.sclass || !c->v.sclass
4592 || newc->v.sclass == c->v.sclass)) {
4593 yyerror2("duplicate entry for genfs entry (%s, %s)",
4594 fstype, newc->u.name);
4595 goto fail;
4596 }
4597 len = strlen(newc->u.name);
4598 len2 = strlen(c->u.name);
4599 if (len > len2)
4600 break;
4601 }
4602
4603 newc->next = c;
4604 if (p)
4605 p->next = newc;
4606 else
4607 genfs->head = newc;
4608 return 0;
4609 fail:
4610 if (type)
4611 free(type);
4612 context_destroy(&newc->context[0]);
4613 if (fstype)
4614 free(fstype);
4615 if (newc->u.name)
4616 free(newc->u.name);
4617 free(newc);
4618 return -1;
4619}
4620
4621int define_genfs_context(int has_type)
4622{
4623 return define_genfs_context_helper(queue_remove(id_queue), has_type);
4624}
4625
4626int define_range_trans(int class_specified)
4627{
4628 char *id;
4629 level_datum_t *levdatum = 0;
4630 class_datum_t *cladatum;
4631 range_trans_rule_t *rule;
4632 int l, add = 1;
4633
4634 if (!mlspol) {
4635 yyerror("range_transition rule in non-MLS configuration");
4636 return -1;
4637 }
4638
4639 if (pass == 1) {
4640 while ((id = queue_remove(id_queue)))
4641 free(id);
4642 while ((id = queue_remove(id_queue)))
4643 free(id);
4644 if (class_specified)
4645 while ((id = queue_remove(id_queue)))
4646 free(id);
4647 id = queue_remove(id_queue);
4648 free(id);
4649 for (l = 0; l < 2; l++) {
4650 while ((id = queue_remove(id_queue))) {
4651 free(id);
4652 }
4653 id = queue_remove(id_queue);
4654 if (!id)
4655 break;
4656 free(id);
4657 }
4658 return 0;
4659 }
4660
4661 rule = malloc(sizeof(struct range_trans_rule));
4662 if (!rule) {
4663 yyerror("out of memory");
4664 return -1;
4665 }
4666 range_trans_rule_init(rule);
4667
4668 while ((id = queue_remove(id_queue))) {
4669 if (set_types(&rule->stypes, id, &add, 0))
4670 goto out;
4671 }
4672 add = 1;
4673 while ((id = queue_remove(id_queue))) {
4674 if (set_types(&rule->ttypes, id, &add, 0))
4675 goto out;
4676 }
4677
4678 if (class_specified) {
Stephen Smalleycd88c5c2012-02-21 14:27:00 -05004679 if (read_classes(&rule->tclasses))
4680 goto out;
SE Android8c48de12012-01-24 05:27:18 -08004681 } else {
4682 cladatum = hashtab_search(policydbp->p_classes.table,
4683 "process");
4684 if (!cladatum) {
4685 yyerror2("could not find process class for "
4686 "legacy range_transition statement");
4687 goto out;
4688 }
4689
Stephen Smalley968aed02013-10-30 15:38:49 -04004690 if (ebitmap_set_bit(&rule->tclasses, cladatum->s.value - 1, TRUE)) {
4691 yyerror("out of memory");
4692 goto out;
4693 }
SE Android8c48de12012-01-24 05:27:18 -08004694 }
4695
4696 id = (char *)queue_remove(id_queue);
4697 if (!id) {
4698 yyerror("no range in range_transition definition?");
4699 goto out;
4700 }
4701 for (l = 0; l < 2; l++) {
4702 levdatum = hashtab_search(policydbp->p_levels.table, id);
4703 if (!levdatum) {
4704 yyerror2("unknown level %s used in range_transition "
4705 "definition", id);
4706 free(id);
4707 goto out;
4708 }
4709 free(id);
4710
4711 rule->trange.level[l].sens = levdatum->level->sens;
4712
4713 while ((id = queue_remove(id_queue))) {
4714 if (parse_semantic_categories(id, levdatum,
4715 &rule->trange.level[l].cat)) {
4716 free(id);
4717 goto out;
4718 }
4719 free(id);
4720 }
4721
4722 id = (char *)queue_remove(id_queue);
4723 if (!id)
4724 break;
4725 }
4726 if (l == 0) {
4727 if (mls_semantic_level_cpy(&rule->trange.level[1],
4728 &rule->trange.level[0])) {
4729 yyerror("out of memory");
4730 goto out;
4731 }
4732 }
4733
4734 append_range_trans(rule);
4735 return 0;
4736
4737out:
4738 range_trans_rule_destroy(rule);
Alice Chu0d73ef72013-01-08 16:05:25 -08004739 free(rule);
SE Android8c48de12012-01-24 05:27:18 -08004740 return -1;
4741}
4742
4743/* FLASK */