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