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