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