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