Home | History | Annotate | Download | only in src
      1 /* Authors: Steve Lawrence <slawrence (at) tresys.com>
      2  *
      3  * Functions to convert policy module to CIL
      4  *
      5  * Copyright (C) 2015 Tresys Technology, LLC
      6  *
      7  *  This library is free software; you can redistribute it and/or
      8  *  modify it under the terms of the GNU Lesser General Public
      9  *  License as published by the Free Software Foundation; either
     10  *  version 2.1 of the License, or (at your option) any later version.
     11  *
     12  *  This library is distributed in the hope that it will be useful,
     13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15  *  Lesser General Public License for more details.
     16  *
     17  *  You should have received a copy of the GNU Lesser General Public
     18  *  License along with this library; if not, write to the Free Software
     19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     20  */
     21 
     22 #include <arpa/inet.h>
     23 #include <ctype.h>
     24 #include <errno.h>
     25 #include <fcntl.h>
     26 #include <getopt.h>
     27 #include <libgen.h>
     28 #include <netinet/in.h>
     29 #ifndef IPPROTO_DCCP
     30 #define IPPROTO_DCCP 33
     31 #endif
     32 #include <signal.h>
     33 #include <stdarg.h>
     34 #include <stdio.h>
     35 #include <stdlib.h>
     36 #include <string.h>
     37 #include <sys/types.h>
     38 #include <sys/stat.h>
     39 #include <unistd.h>
     40 
     41 #include <sepol/module.h>
     42 #include <sepol/module_to_cil.h>
     43 #include <sepol/policydb/conditional.h>
     44 #include <sepol/policydb/hashtab.h>
     45 #include <sepol/policydb/polcaps.h>
     46 #include <sepol/policydb/policydb.h>
     47 #include <sepol/policydb/services.h>
     48 #include <sepol/policydb/util.h>
     49 
     50 #include "private.h"
     51 
     52 #ifdef __GNUC__
     53 #  define UNUSED(x) UNUSED_ ## x __attribute__((__unused__))
     54 #else
     55 #  define UNUSED(x) UNUSED_ ## x
     56 #endif
     57 
     58 FILE *out_file;
     59 
     60 #define STACK_SIZE 16
     61 #define DEFAULT_LEVEL "systemlow"
     62 #define DEFAULT_OBJECT "object_r"
     63 #define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/cil/src/cil_post.c */
     64 #define TYPEATTR_INFIX "_typeattr_"        /* Also in libsepol/cil/src/cil_post.c */
     65 #define ROLEATTR_INFIX "_roleattr_"
     66 
     67 __attribute__ ((format(printf, 1, 2)))
     68 static void log_err(const char *fmt, ...)
     69 {
     70 	va_list argptr;
     71 	va_start(argptr, fmt);
     72 	if (vfprintf(stderr, fmt, argptr) < 0) {
     73 		_exit(EXIT_FAILURE);
     74 	}
     75 	va_end(argptr);
     76 	if (fprintf(stderr, "\n") < 0) {
     77 		_exit(EXIT_FAILURE);
     78 	}
     79 }
     80 
     81 static void cil_indent(int indent)
     82 {
     83 	if (fprintf(out_file, "%*s", indent * 4, "") < 0) {
     84 		log_err("Failed to write to output");
     85 		_exit(EXIT_FAILURE);
     86 	}
     87 }
     88 
     89 __attribute__ ((format(printf, 1, 2)))
     90 static void cil_printf(const char *fmt, ...) {
     91 	va_list argptr;
     92 	va_start(argptr, fmt);
     93 	if (vfprintf(out_file, fmt, argptr) < 0) {
     94 		log_err("Failed to write to output");
     95 		_exit(EXIT_FAILURE);
     96 	}
     97 	va_end(argptr);
     98 }
     99 
    100 __attribute__ ((format(printf, 2, 3)))
    101 static void cil_println(int indent, const char *fmt, ...)
    102 {
    103 	cil_indent(indent);
    104 	va_list argptr;
    105 	va_start(argptr, fmt);
    106 	if (vfprintf(out_file, fmt, argptr) < 0) {
    107 		log_err("Failed to write to output");
    108 		_exit(EXIT_FAILURE);
    109 	}
    110 	va_end(argptr);
    111 	if (fprintf(out_file, "\n") < 0) {
    112 		log_err("Failed to write to output");
    113 		_exit(EXIT_FAILURE);
    114 	}
    115 }
    116 
    117 static int get_line(char **start, char *end, char **line)
    118 {
    119 	int rc = 1;
    120 	char *p = NULL;
    121 	size_t len = 0;
    122 
    123 	*line = NULL;
    124 
    125 	for (p = *start; p < end && isspace(*p); p++);
    126 
    127 	*start = p;
    128 
    129 	for (len = 0; p < end && *p != '\n' && *p != '\0'; p++, len++);
    130 
    131 	if (zero_or_saturated(len)) {
    132 		rc = 0;
    133 		goto exit;
    134 	}
    135 
    136 	*line = malloc(len+1);
    137 	if (*line == NULL) {
    138 		log_err("Out of memory");
    139 		rc = -1;
    140 		goto exit;
    141 	}
    142 
    143 	memcpy(*line, *start, len);
    144 	(*line)[len] = '\0';
    145 
    146 	*start = p;
    147 
    148 	return rc;
    149 
    150 exit:
    151 	*start = NULL;
    152 	return rc;
    153 }
    154 
    155 struct map_args {
    156 	struct policydb *pdb;
    157 	struct avrule_block *block;
    158 	struct stack *decl_stack;
    159 	int scope;
    160 	int indent;
    161 	int sym_index;
    162 };
    163 
    164 struct stack {
    165 	 void **stack;
    166 	 int pos;
    167 	 int size;
    168 };
    169 
    170 struct role_list_node {
    171 	char *role_name;
    172 	role_datum_t *role;
    173 };
    174 
    175 struct attr_list_node {
    176 	char *attr_name;
    177 	int is_type;
    178 	void *set;
    179 };
    180 
    181 struct list_node {
    182 	void *data;
    183 	struct list_node *next;
    184 };
    185 
    186 struct list {
    187 	struct list_node *head;
    188 };
    189 
    190 /* A linked list of all roles stored in the pdb
    191  * which is iterated to determine types associated
    192  * with each role when printing role_type statements
    193  */
    194 static struct list *role_list;
    195 
    196 static void list_destroy(struct list **list)
    197 {
    198 	struct list_node *curr = (*list)->head;
    199 	struct list_node *tmp;
    200 
    201 	while (curr != NULL) {
    202 		tmp = curr->next;
    203 		free(curr);
    204 		curr = tmp;
    205 	}
    206 
    207 	free(*list);
    208 	*list = NULL;
    209 }
    210 
    211 static void role_list_destroy(void)
    212 {
    213 	struct list_node *curr = role_list->head;
    214 
    215 	while (curr != NULL) {
    216 		free(curr->data);
    217 		curr->data = NULL;
    218 		curr = curr->next;
    219 	}
    220 
    221 	list_destroy(&role_list);
    222 }
    223 
    224 static void attr_list_destroy(struct list **attr_list)
    225 {
    226 	if (attr_list == NULL || *attr_list == NULL) {
    227 		return;
    228 	}
    229 
    230 	struct list_node *curr = (*attr_list)->head;
    231 	struct attr_list_node *attr;
    232 
    233 	while (curr != NULL) {
    234 		attr = curr->data;
    235 		if (attr != NULL) {
    236 			free(attr->attr_name);
    237 		}
    238 
    239 		free(curr->data);
    240 		curr->data = NULL;
    241 		curr = curr->next;
    242 	}
    243 
    244 	list_destroy(attr_list);
    245 }
    246 
    247 static int list_init(struct list **list)
    248 {
    249 	int rc = -1;
    250 	struct list *l = calloc(1, sizeof(*l));
    251 	if (l == NULL) {
    252 		goto exit;
    253 	}
    254 
    255 	*list = l;
    256 
    257 	return 0;
    258 
    259 exit:
    260 	list_destroy(&l);
    261 	return rc;
    262 }
    263 
    264 static int list_prepend(struct list *list, void *data)
    265 {
    266 	int rc = -1;
    267 	struct list_node *node = calloc(1, sizeof(*node));
    268 	if (node == NULL) {
    269 		goto exit;
    270 	}
    271 
    272 	node->data = data;
    273 	node->next = list->head;
    274 	list->head = node;
    275 
    276 	rc = 0;
    277 
    278 exit:
    279 	return rc;
    280 }
    281 
    282 static int roles_gather_map(char *key, void *data, void *args)
    283 {
    284 	struct role_list_node *role_node;
    285 	role_datum_t *role = data;
    286 	int rc = -1;
    287 
    288 	role_node = calloc(1, sizeof(*role_node));
    289 	if (role_node == NULL) {
    290 		return rc;
    291 	}
    292 
    293 	role_node->role_name = key;
    294 	role_node->role = role;
    295 
    296 	rc = list_prepend((struct list *)args, role_node);
    297 	return rc;
    298 }
    299 
    300 static int role_list_create(hashtab_t roles_tab)
    301 {
    302 	int rc = -1;
    303 
    304 	rc = list_init(&role_list);
    305 	if (rc != 0) {
    306 		goto exit;
    307 	}
    308 
    309 	rc = hashtab_map(roles_tab, roles_gather_map, role_list);
    310 
    311 exit:
    312 	return rc;
    313 }
    314 
    315 // array of lists, where each list contains all the aliases defined in the scope at index i
    316 static struct list **typealias_lists;
    317 static uint32_t typealias_lists_len;
    318 
    319 static int typealiases_gather_map(char *key, void *data, void *arg)
    320 {
    321 	int rc = -1;
    322 	struct type_datum *type = data;
    323 	struct policydb *pdb = arg;
    324 	struct scope_datum *scope;
    325 	uint32_t i;
    326 	uint32_t scope_id;
    327 
    328 	if (type->primary != 1) {
    329 		scope = hashtab_search(pdb->scope[SYM_TYPES].table, key);
    330 		if (scope == NULL) {
    331 			return -1;
    332 		}
    333 
    334 		for (i = 0; i < scope->decl_ids_len; i++) {
    335 			scope_id = scope->decl_ids[i];
    336 			if (typealias_lists[scope_id] == NULL) {
    337 				rc = list_init(&typealias_lists[scope_id]);
    338 				if (rc != 0) {
    339 					goto exit;
    340 				}
    341 			}
    342 			list_prepend(typealias_lists[scope_id], key);
    343 		}
    344 	}
    345 
    346 	return 0;
    347 
    348 exit:
    349 	return rc;
    350 }
    351 
    352 static void typealias_list_destroy(void)
    353 {
    354 	uint32_t i;
    355 	for (i = 0; i < typealias_lists_len; i++) {
    356 		if (typealias_lists[i] != NULL) {
    357 			list_destroy(&typealias_lists[i]);
    358 		}
    359 	}
    360 	typealias_lists_len = 0;
    361 	free(typealias_lists);
    362 	typealias_lists = NULL;
    363 }
    364 
    365 static int typealias_list_create(struct policydb *pdb)
    366 {
    367 	uint32_t max_decl_id = 0;
    368 	struct avrule_decl *decl;
    369 	struct avrule_block *block;
    370 	uint32_t rc = -1;
    371 
    372 	for (block = pdb->global; block != NULL; block = block->next) {
    373 		decl = block->branch_list;
    374 		if (decl != NULL && decl->decl_id > max_decl_id) {
    375 			max_decl_id = decl->decl_id;
    376 		}
    377 	}
    378 
    379 	typealias_lists = calloc(max_decl_id + 1, sizeof(*typealias_lists));
    380 	typealias_lists_len = max_decl_id + 1;
    381 
    382 	rc = hashtab_map(pdb->p_types.table, typealiases_gather_map, pdb);
    383 	if (rc != 0) {
    384 		goto exit;
    385 	}
    386 
    387 	return 0;
    388 
    389 exit:
    390 	typealias_list_destroy();
    391 
    392 	return rc;
    393 }
    394 
    395 
    396 static int stack_destroy(struct stack **stack)
    397 {
    398 	if (stack == NULL || *stack == NULL) {
    399 		return 0;
    400 	}
    401 
    402 	free((*stack)->stack);
    403 	free(*stack);
    404 	*stack = NULL;
    405 
    406 	return 0;
    407 }
    408 
    409 static int stack_init(struct stack **stack)
    410 {
    411 	int rc = -1;
    412 	struct stack *s = calloc(1, sizeof(*s));
    413 	if (s == NULL) {
    414 		goto exit;
    415 	}
    416 
    417 	s->stack = malloc(sizeof(*s->stack) * STACK_SIZE);
    418 	if (s->stack == NULL) {
    419 		goto exit;
    420 	}
    421 
    422 	s->pos = -1;
    423 	s->size = STACK_SIZE;
    424 
    425 	*stack = s;
    426 
    427 	return 0;
    428 
    429 exit:
    430 	stack_destroy(&s);
    431 	return rc;
    432 }
    433 
    434 static int stack_push(struct stack *stack, void *ptr)
    435 {
    436 	int rc = -1;
    437 	void *new_stack;
    438 
    439 	if (stack->pos + 1 == stack->size) {
    440 		new_stack = realloc(stack->stack, sizeof(*stack->stack) * (stack->size * 2));
    441 		if (new_stack == NULL) {
    442 			goto exit;
    443 		}
    444 		stack->stack = new_stack;
    445 		stack->size *= 2;
    446 	}
    447 
    448 	stack->pos++;
    449 	stack->stack[stack->pos] = ptr;
    450 
    451 	rc = 0;
    452 exit:
    453 	return rc;
    454 }
    455 
    456 static void *stack_pop(struct stack *stack)
    457 {
    458 	if (stack->pos == -1) {
    459 		return NULL;
    460 	}
    461 
    462 	stack->pos--;
    463 	return stack->stack[stack->pos + 1];
    464 }
    465 
    466 static void *stack_peek(struct stack *stack)
    467 {
    468 	if (stack->pos == -1) {
    469 		return NULL;
    470 	}
    471 
    472 	return stack->stack[stack->pos];
    473 }
    474 
    475 static int is_id_in_scope_with_start(struct policydb *pdb, struct stack *decl_stack, int start, uint32_t symbol_type, char *id)
    476 {
    477 	int i;
    478 	uint32_t j;
    479 	struct avrule_decl *decl;
    480 	struct scope_datum *scope;
    481 
    482 	scope = hashtab_search(pdb->scope[symbol_type].table, id);
    483 	if (scope == NULL) {
    484 		return 0;
    485 	}
    486 
    487 	for (i = start; i >= 0; i--) {
    488 		decl = decl_stack->stack[i];
    489 
    490 		for (j = 0; j < scope->decl_ids_len; j++) {
    491 			if (scope->decl_ids[j] == decl->decl_id) {
    492 				return 1;
    493 			}
    494 		}
    495 	}
    496 
    497 	return 0;
    498 }
    499 
    500 static int is_id_in_ancestor_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type)
    501 {
    502 	int start = decl_stack->pos - 1;
    503 
    504 	return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type);
    505 }
    506 
    507 static int is_id_in_scope(struct policydb *pdb, struct stack *decl_stack, char *type, uint32_t symbol_type)
    508 {
    509 	int start = decl_stack->pos;
    510 
    511 	return is_id_in_scope_with_start(pdb, decl_stack, start, symbol_type, type);
    512 }
    513 
    514 static int semantic_level_to_cil(struct policydb *pdb, int sens_offset, struct mls_semantic_level *level)
    515 {
    516 	struct mls_semantic_cat *cat;
    517 
    518 	cil_printf("(%s ", pdb->p_sens_val_to_name[level->sens - sens_offset]);
    519 
    520 	if (level->cat != NULL) {
    521 		cil_printf("(");
    522 	}
    523 
    524 	for (cat = level->cat; cat != NULL; cat = cat->next) {
    525 		if (cat->low == cat->high) {
    526 			cil_printf("%s", pdb->p_cat_val_to_name[cat->low - 1]);
    527 		} else {
    528 			cil_printf("range %s %s", pdb->p_cat_val_to_name[cat->low - 1], pdb->p_cat_val_to_name[cat->high - 1]);
    529 		}
    530 
    531 		if (cat->next != NULL) {
    532 			cil_printf(" ");
    533 		}
    534 	}
    535 
    536 	if (level->cat != NULL) {
    537 		cil_printf(")");
    538 	}
    539 
    540 	cil_printf(")");
    541 
    542 	return 0;
    543 }
    544 
    545 static int avrule_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const struct class_perm_node *classperms)
    546 {
    547 	int rc = -1;
    548 	const char *rule;
    549 	const struct class_perm_node *classperm;
    550 	char *perms;
    551 
    552 	switch (type) {
    553 	case AVRULE_ALLOWED:
    554 		rule = "allow";
    555 		break;
    556 	case AVRULE_AUDITALLOW:
    557 		rule = "auditallow";
    558 		break;
    559 	case AVRULE_AUDITDENY:
    560 		rule = "auditdenty";
    561 		break;
    562 	case AVRULE_DONTAUDIT:
    563 		rule = "dontaudit";
    564 		break;
    565 	case AVRULE_NEVERALLOW:
    566 		rule = "neverallow";
    567 		break;
    568 	case AVRULE_TRANSITION:
    569 		rule = "typetransition";
    570 		break;
    571 	case AVRULE_MEMBER:
    572 		rule = "typemember";
    573 		break;
    574 	case AVRULE_CHANGE:
    575 		rule = "typechange";
    576 		break;
    577 	default:
    578 		log_err("Unknown avrule type: %i", type);
    579 		rc = -1;
    580 		goto exit;
    581 	}
    582 
    583 	for (classperm = classperms; classperm != NULL; classperm = classperm->next) {
    584 		if (type & AVRULE_AV) {
    585 			perms = sepol_av_to_string(pdb, classperm->tclass, classperm->data);
    586 			if (perms == NULL) {
    587 				log_err("Failed to generate permission string");
    588 				rc = -1;
    589 				goto exit;
    590 			}
    591 			cil_println(indent, "(%s %s %s (%s (%s)))",
    592 					rule, src, tgt,
    593 					pdb->p_class_val_to_name[classperm->tclass - 1],
    594 					perms + 1);
    595 		} else {
    596 			cil_println(indent, "(%s %s %s %s %s)",
    597 					rule, src, tgt,
    598 					pdb->p_class_val_to_name[classperm->tclass - 1],
    599 					pdb->p_type_val_to_name[classperm->data - 1]);
    600 		}
    601 	}
    602 
    603 	return 0;
    604 
    605 exit:
    606 	return rc;
    607 }
    608 
    609 #define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p))
    610 
    611 static int xperms_to_cil(const av_extended_perms_t *xperms)
    612 {
    613 	uint16_t value;
    614 	uint16_t low_bit;
    615 	uint16_t low_value;
    616 	unsigned int bit;
    617 	unsigned int in_range = 0;
    618 	int first = 1;
    619 
    620 	if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
    621 		&& (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
    622 		return -1;
    623 
    624 	for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
    625 		if (!xperm_test(bit, xperms->perms))
    626 			continue;
    627 
    628 		if (in_range && next_bit_in_range(bit, xperms->perms)) {
    629 			/* continue until high value found */
    630 			continue;
    631 		} else if (next_bit_in_range(bit, xperms->perms)) {
    632 			/* low value */
    633 			low_bit = bit;
    634 			in_range = 1;
    635 			continue;
    636 		}
    637 
    638 		if (!first)
    639 			cil_printf(" ");
    640 		else
    641 			first = 0;
    642 
    643 		if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
    644 			value = xperms->driver<<8 | bit;
    645 			low_value = xperms->driver<<8 | low_bit;
    646 			if (in_range) {
    647 				cil_printf("(range 0x%hx 0x%hx)", low_value, value);
    648 				in_range = 0;
    649 			} else {
    650 				cil_printf("0x%hx", value);
    651 			}
    652 		} else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
    653 			value = bit << 8;
    654 			low_value = low_bit << 8;
    655 			if (in_range) {
    656 				cil_printf("(range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff));
    657 				in_range = 0;
    658 			} else {
    659 				cil_printf("(range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff));
    660 			}
    661 		}
    662 	}
    663 
    664 	return 0;
    665 }
    666 
    667 static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const class_perm_node_t *classperms, const av_extended_perms_t *xperms)
    668 {
    669 	int rc = -1;
    670 	const char *rule;
    671 	const struct class_perm_node *classperm;
    672 
    673 	switch (type) {
    674 	case AVRULE_XPERMS_ALLOWED:
    675 		rule = "allowx";
    676 		break;
    677 	case AVRULE_XPERMS_AUDITALLOW:
    678 		rule = "auditallowx";
    679 		break;
    680 	case AVRULE_XPERMS_DONTAUDIT:
    681 		rule = "dontauditx";
    682 		break;
    683 	case AVRULE_XPERMS_NEVERALLOW:
    684 		rule = "neverallowx";
    685 		break;
    686 	default:
    687 		log_err("Unknown avrule xperm type: %i", type);
    688 		rc = -1;
    689 		goto exit;
    690 	}
    691 
    692 	for (classperm = classperms; classperm != NULL; classperm = classperm->next) {
    693 		cil_indent(indent);
    694 		cil_printf("(%s %s %s (%s %s (", rule, src, tgt,
    695 			   "ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]);
    696 		xperms_to_cil(xperms);
    697 		cil_printf(")))\n");
    698 	}
    699 
    700 	return 0;
    701 
    702 exit:
    703 	return rc;
    704 }
    705 
    706 static int num_digits(int n)
    707 {
    708 	int num = 1;
    709 	while (n >= 10) {
    710 		n /= 10;
    711 		num++;
    712 	}
    713 	return num;
    714 }
    715 
    716 static int ebitmap_to_cil(struct policydb *pdb, struct ebitmap *map, int type)
    717 {
    718 	struct ebitmap_node *node;
    719 	uint32_t i;
    720 	char **val_to_name = pdb->sym_val_to_name[type];
    721 
    722 	ebitmap_for_each_bit(map, node, i) {
    723 		if (!ebitmap_get_bit(map, i)) {
    724 			continue;
    725 		}
    726 		cil_printf("%s ", val_to_name[i]);
    727 	}
    728 
    729 	return 0;
    730 }
    731 
    732 static char *get_new_attr_name(struct policydb *pdb, int is_type)
    733 {
    734 	static unsigned int num_attrs = 0;
    735 	int len, rlen;
    736 	const char *infix;
    737 	char *attr_name = NULL;
    738 
    739 	num_attrs++;
    740 
    741 	if (is_type) {
    742 		infix = TYPEATTR_INFIX;
    743 	} else {
    744 		infix = ROLEATTR_INFIX;
    745 	}
    746 
    747 	len = strlen(pdb->name) + strlen(infix) + num_digits(num_attrs) + 1;
    748 	attr_name = malloc(len);
    749 	if (!attr_name) {
    750 		log_err("Out of memory");
    751 		goto exit;
    752 	}
    753 
    754 	rlen = snprintf(attr_name, len, "%s%s%i", pdb->name, infix, num_attrs);
    755 	if (rlen < 0 || rlen >= len) {
    756 		log_err("Failed to generate attribute name");
    757 		free(attr_name);
    758 		attr_name = NULL;
    759 		goto exit;
    760 	}
    761 
    762 exit:
    763 	return attr_name;
    764 }
    765 
    766 static int cil_add_attr_to_list(struct list *attr_list, char *attr_name, int is_type, void *set)
    767 {
    768 	struct attr_list_node *attr_list_node = NULL;
    769 	int rc = 0;
    770 
    771 	attr_list_node = calloc(1, sizeof(*attr_list_node));
    772 	if (attr_list_node == NULL) {
    773 		log_err("Out of memory");
    774 		rc = -1;
    775 		goto exit;
    776 	}
    777 
    778 	rc = list_prepend(attr_list, attr_list_node);
    779 	if (rc != 0) {
    780 		goto exit;
    781 	}
    782 
    783 	attr_list_node->attr_name = attr_name;
    784 	attr_list_node->is_type = is_type;
    785 	attr_list_node->set = set;
    786 
    787 	return rc;
    788 
    789 exit:
    790 	free(attr_list_node);
    791 	return rc;
    792 }
    793 
    794 static int cil_print_attr_strs(int indent, struct policydb *pdb, int is_type, void *set, char *attr_name)
    795 {
    796 	// CIL doesn't support anonymous positive/negative/complemented sets.  So
    797 	// instead we create a CIL type/roleattributeset that matches the set. If
    798 	// the set has a negative set, then convert it to is (P & !N), where P is
    799 	// the list of members in the positive set , and N is the list of members
    800 	// in the negative set. Additonally, if the set is complemented, then wrap
    801 	// the whole thing with a negation.
    802 
    803 	struct ebitmap_node *node;
    804 	struct ebitmap *pos, *neg;
    805 	uint32_t flags;
    806 	unsigned i;
    807 	struct type_set *ts;
    808 	struct role_set *rs;
    809 	int has_positive, has_negative;
    810 	const char *kind;
    811 	char **val_to_name;
    812 	int rc = 0;
    813 
    814 	if (is_type) {
    815 		kind = "type";
    816 		val_to_name = pdb->p_type_val_to_name;
    817 		ts = (struct type_set *)set;
    818 		pos = &ts->types;
    819 		neg = &ts->negset;
    820 		flags = ts->flags;
    821 		has_positive = pos && (ebitmap_length(pos) > 0);
    822 		has_negative = neg && (ebitmap_length(neg) > 0);
    823 	} else {
    824 		kind = "role";
    825 		val_to_name = pdb->p_role_val_to_name;
    826 		rs = (struct role_set *)set;
    827 		pos = &rs->roles;
    828 		neg = NULL;
    829 		flags = rs->flags;
    830 		has_positive = pos && (ebitmap_length(pos) > 0);
    831 		has_negative = 0;
    832 	}
    833 
    834 	cil_println(indent, "(%sattribute %s)", kind, attr_name);
    835 	cil_indent(indent);
    836 	cil_printf("(%sattributeset %s ", kind, attr_name);
    837 
    838 	if (flags & TYPE_STAR) {
    839 		cil_printf("(all)");
    840 	}
    841 
    842 	if (flags & TYPE_COMP) {
    843 		cil_printf("(not ");
    844 	}
    845 
    846 	if (has_positive && has_negative) {
    847 		cil_printf("(and ");
    848 	}
    849 
    850 	if (has_positive) {
    851 		cil_printf("(");
    852 		ebitmap_for_each_bit(pos, node, i) {
    853 			if (!ebitmap_get_bit(pos, i)) {
    854 				continue;
    855 			}
    856 			cil_printf("%s ", val_to_name[i]);
    857 		}
    858 		cil_printf(") ");
    859 	}
    860 
    861 	if (has_negative) {
    862 		cil_printf("(not (");
    863 
    864 		ebitmap_for_each_bit(neg, node, i) {
    865 			if (!ebitmap_get_bit(neg, i)) {
    866 				continue;
    867 			}
    868 			cil_printf("%s ", val_to_name[i]);
    869 		}
    870 
    871 		cil_printf("))");
    872 	}
    873 
    874 	if (has_positive && has_negative) {
    875 		cil_printf(")");
    876 	}
    877 
    878 	if (flags & TYPE_COMP) {
    879 		cil_printf(")");
    880 	}
    881 
    882 	cil_printf(")\n");
    883 
    884 	return rc;
    885 }
    886 
    887 static int cil_print_attr_list(int indent, struct policydb *pdb, struct list *attr_list)
    888 {
    889 	struct list_node *curr;
    890 	struct attr_list_node *node;
    891 	int rc = 0;
    892 
    893 	for (curr = attr_list->head; curr != NULL; curr = curr->next) {
    894 		node = curr->data;
    895 		rc = cil_print_attr_strs(indent, pdb, node->is_type, node->set, node->attr_name);
    896 		if (rc != 0) {
    897 			return rc;
    898 		}
    899 	}
    900 
    901 	return rc;
    902 }
    903 
    904 static char *search_attr_list(struct list *attr_list, int is_type, void *set)
    905 {
    906 	struct list_node *curr;
    907 	struct attr_list_node *node;
    908 	struct role_set *rs1 = NULL, *rs2;
    909 	struct type_set *ts1 = NULL, *ts2;
    910 
    911 	if (is_type) {
    912 		ts1 = (struct type_set *)set;
    913 	} else {
    914 		rs1 = (struct role_set *)set;
    915 	}
    916 
    917 	for (curr = attr_list->head; curr != NULL; curr = curr->next) {
    918 		node = curr->data;
    919 		if (node->is_type != is_type)
    920 			continue;
    921 		if (ts1) {
    922 			ts2 = (struct type_set *)node->set;
    923 			if (ts1->flags != ts2->flags)
    924 				continue;
    925 			if (ebitmap_cmp(&ts1->negset, &ts2->negset) == 0)
    926 				continue;
    927 			if (ebitmap_cmp(&ts1->types, &ts2->types) == 0)
    928 				continue;
    929 			return node->attr_name;
    930 		} else {
    931 			rs2 = (struct role_set *)node->set;
    932 			if (rs1->flags != rs2->flags)
    933 				continue;
    934 			if (ebitmap_cmp(&rs1->roles, &rs2->roles) == 0)
    935 				continue;
    936 			return node->attr_name;
    937 		}
    938 	}
    939 
    940 	return NULL;
    941 }
    942 
    943 static int set_to_names(struct policydb *pdb, int is_type, void *set, struct list *attr_list, char ***names, int *num_names)
    944 {
    945 	char *attr_name = NULL;
    946 	int rc = 0;
    947 
    948 	*names = NULL;
    949 	*num_names = 0;
    950 
    951 	attr_name = search_attr_list(attr_list, is_type, set);
    952 
    953 	if (!attr_name) {
    954 		attr_name = get_new_attr_name(pdb, is_type);
    955 		if (!attr_name) {
    956 			rc = -1;
    957 			goto exit;
    958 		}
    959 
    960 		rc = cil_add_attr_to_list(attr_list, attr_name, is_type, set);
    961 		if (rc != 0) {
    962 			free(attr_name);
    963 			goto exit;
    964 		}
    965 	}
    966 
    967 	*names = malloc(sizeof(char *));
    968 	if (!*names) {
    969 		log_err("Out of memory");
    970 		free(attr_name);
    971 		rc = -1;
    972 		goto exit;
    973 	}
    974 	*names[0] = attr_name;
    975 	*num_names = 1;
    976 
    977 exit:
    978 	return rc;
    979 }
    980 
    981 static int ebitmap_to_names(struct ebitmap *map, char **vals_to_names, char ***names, int *num_names)
    982 {
    983 	int rc = 0;
    984 	struct ebitmap_node *node;
    985 	uint32_t i;
    986 	uint32_t num;
    987 	char **name_arr;
    988 
    989 	num = 0;
    990 	ebitmap_for_each_bit(map, node, i) {
    991 		if (ebitmap_get_bit(map, i))
    992 			num++;
    993 	}
    994 
    995 	name_arr = malloc(sizeof(*name_arr) * num);
    996 	if (name_arr == NULL) {
    997 		log_err("Out of memory");
    998 		rc = -1;
    999 		goto exit;
   1000 	}
   1001 
   1002 	num = 0;
   1003 	ebitmap_for_each_bit(map, node, i) {
   1004 		if (ebitmap_get_bit(map, i)) {
   1005 			name_arr[num] = vals_to_names[i];
   1006 			num++;
   1007 		}
   1008 	}
   1009 
   1010 	*names = name_arr;
   1011 	*num_names = num;
   1012 
   1013 exit:
   1014 	return rc;
   1015 }
   1016 
   1017 static int process_roleset(struct policydb *pdb, struct role_set *rs, struct list *attr_list, char ***names, int *num_names)
   1018 {
   1019 	int rc = 0;
   1020 
   1021 	*names = NULL;
   1022 	*num_names = 0;
   1023 
   1024 	if (rs->flags) {
   1025 		rc = set_to_names(pdb, 0, &rs->roles, attr_list, names, num_names);
   1026 		if (rc != 0) {
   1027 			goto exit;
   1028 		}
   1029 	} else {
   1030 		rc = ebitmap_to_names(&rs->roles, pdb->p_role_val_to_name, names, num_names);
   1031 		if (rc != 0) {
   1032 			goto exit;
   1033 		}
   1034 	}
   1035 
   1036 exit:
   1037 	return rc;
   1038 }
   1039 
   1040 static int process_typeset(struct policydb *pdb, struct type_set *ts, struct list *attr_list, char ***names, int *num_names)
   1041 {
   1042 	int rc = 0;
   1043 
   1044 	*names = NULL;
   1045 	*num_names = 0;
   1046 
   1047 	if (ebitmap_length(&ts->negset) > 0 || ts->flags != 0) {
   1048 		rc = set_to_names(pdb, 1, ts, attr_list, names, num_names);
   1049 		if (rc != 0) {
   1050 			goto exit;
   1051 		}
   1052 	} else {
   1053 		rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, names, num_names);
   1054 		if (rc != 0) {
   1055 			goto exit;
   1056 		}
   1057 	}
   1058 
   1059 exit:
   1060 	return rc;
   1061 }
   1062 
   1063 static void names_destroy(char ***names, int *num_names)
   1064 {
   1065 	free(*names);
   1066 	*names = NULL;
   1067 	*num_names = 0;
   1068 }
   1069 
   1070 static int roletype_role_in_ancestor_to_cil(struct policydb *pdb, struct stack *decl_stack, char *type_name, int indent)
   1071 {
   1072 	struct list_node *curr;
   1073 	char **tnames = NULL;
   1074 	int num_tnames, i;
   1075 	struct role_list_node *role_node = NULL;
   1076 	int rc;
   1077 	struct type_set *ts;
   1078 	struct list *attr_list = NULL;
   1079 
   1080 	rc = list_init(&attr_list);
   1081 	if (rc != 0) {
   1082 		goto exit;
   1083 	}
   1084 
   1085 	curr = role_list->head;
   1086 	for (curr = role_list->head; curr != NULL; curr = curr->next) {
   1087 		role_node = curr->data;
   1088 		if (!is_id_in_ancestor_scope(pdb, decl_stack, role_node->role_name, SYM_ROLES)) {
   1089 			continue;
   1090 		}
   1091 
   1092 		ts = &role_node->role->types;
   1093 		rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames);
   1094 		if (rc != 0) {
   1095 			goto exit;
   1096 		}
   1097 		for (i = 0; i < num_tnames; i++) {
   1098 			if (!strcmp(type_name, tnames[i])) {
   1099 				cil_println(indent, "(roletype %s %s)", role_node->role_name, type_name);
   1100 			}
   1101 		}
   1102 		names_destroy(&tnames, &num_tnames);
   1103 	}
   1104 
   1105 	rc = cil_print_attr_list(indent, pdb, attr_list);
   1106 	if (rc != 0) {
   1107 		goto exit;
   1108 	}
   1109 
   1110 exit:
   1111 	attr_list_destroy(&attr_list);
   1112 	return rc;
   1113 }
   1114 
   1115 
   1116 static int name_list_to_string(char **names, int num_names, char **string)
   1117 {
   1118 	// create a space separated string of the names
   1119 	int rc = -1;
   1120 	int len = 0;
   1121 	int i;
   1122 	char *str;
   1123 	char *strpos;
   1124 	int name_len;
   1125 	int rlen;
   1126 
   1127 	for (i = 0; i < num_names; i++) {
   1128 		len += strlen(names[i]);
   1129 	}
   1130 
   1131 	// add spaces + null terminator
   1132 	len += (num_names - 1) + 1;
   1133 
   1134 	str = malloc(len);
   1135 	if (str == NULL) {
   1136 		log_err("Out of memory");
   1137 		rc = -1;
   1138 		goto exit;
   1139 	}
   1140 
   1141 	strpos = str;
   1142 
   1143 	for (i = 0; i < num_names; i++) {
   1144 		name_len = strlen(names[i]);
   1145 		rlen = snprintf(strpos, len - (strpos - str), "%s", names[i]);
   1146 		if (rlen < 0 || rlen >= len) {
   1147 			log_err("Failed to generate name list");
   1148 			rc = -1;
   1149 			goto exit;
   1150 		}
   1151 
   1152 		if (i < num_names - 1) {
   1153 			strpos[name_len] = ' ';
   1154 		}
   1155 		strpos += name_len + 1;
   1156 	}
   1157 
   1158 	*string = str;
   1159 
   1160 	return 0;
   1161 exit:
   1162 	return rc;
   1163 }
   1164 
   1165 static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *avrule_list, struct list *attr_list)
   1166 {
   1167 	int rc = -1;
   1168 	struct avrule *avrule;
   1169 	char **snames = NULL;
   1170 	char **tnames = NULL;
   1171 	int s, t, num_snames, num_tnames;
   1172 	struct type_set *ts;
   1173 
   1174 	for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) {
   1175 		if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) &&
   1176 		    avrule->source_filename) {
   1177 			cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename);
   1178 		}
   1179 
   1180 		ts = &avrule->stypes;
   1181 		rc = process_typeset(pdb, ts, attr_list, &snames, &num_snames);
   1182 		if (rc != 0) {
   1183 			goto exit;
   1184 		}
   1185 
   1186 		ts = &avrule->ttypes;
   1187 		rc = process_typeset(pdb, ts, attr_list, &tnames, &num_tnames);
   1188 		if (rc != 0) {
   1189 			goto exit;
   1190 		}
   1191 
   1192 		for (s = 0; s < num_snames; s++) {
   1193 			for (t = 0; t < num_tnames; t++) {
   1194 				if (avrule->specified & AVRULE_XPERMS) {
   1195 					rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms, avrule->xperms);
   1196 				} else {
   1197 					rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms);
   1198 				}
   1199 				if (rc != 0) {
   1200 					goto exit;
   1201 				}
   1202 			}
   1203 
   1204 			if (avrule->flags & RULE_SELF) {
   1205 				if (avrule->specified & AVRULE_XPERMS) {
   1206 					rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms, avrule->xperms);
   1207 				} else {
   1208 					rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms);
   1209 				}
   1210 				if (rc != 0) {
   1211 					goto exit;
   1212 				}
   1213 			}
   1214 		}
   1215 
   1216 		names_destroy(&snames, &num_snames);
   1217 		names_destroy(&tnames, &num_tnames);
   1218 
   1219 		if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) &&
   1220 		    avrule->source_filename) {
   1221 			cil_println(0, ";;* lme\n");
   1222 		}
   1223 	}
   1224 
   1225 	return 0;
   1226 
   1227 exit:
   1228 	names_destroy(&snames, &num_snames);
   1229 	names_destroy(&tnames, &num_tnames);
   1230 
   1231 	return rc;
   1232 }
   1233 
   1234 static int cond_expr_to_cil(int indent, struct policydb *pdb, struct cond_expr *cond_expr, uint32_t flags)
   1235 {
   1236 	int rc = 0;
   1237 	struct cond_expr *curr;
   1238 	struct stack *stack = NULL;
   1239 	int len = 0;
   1240 	int rlen;
   1241 	char *new_val = NULL;
   1242 	char *val1 = NULL;
   1243 	char *val2 = NULL;
   1244 	int num_params;
   1245 	const char *op;
   1246 	const char *fmt_str;
   1247 	const char *type;
   1248 
   1249 	rc = stack_init(&stack);
   1250 	if (rc != 0) {
   1251 		log_err("Out of memory");
   1252 		goto exit;
   1253 	}
   1254 
   1255 	for (curr = cond_expr; curr != NULL; curr = curr->next) {
   1256 		if (curr->expr_type == COND_BOOL) {
   1257 			val1 = pdb->p_bool_val_to_name[curr->bool - 1];
   1258 			// length of boolean + 2 parens + null terminator
   1259 			len = strlen(val1) + 2 + 1;
   1260 			new_val = malloc(len);
   1261 			if (new_val == NULL) {
   1262 				log_err("Out of memory");
   1263 				rc = -1;
   1264 				goto exit;
   1265 			}
   1266 			rlen = snprintf(new_val, len, "(%s)", val1);
   1267 			if (rlen < 0 || rlen >= len) {
   1268 				log_err("Failed to generate conditional expression");
   1269 				rc = -1;
   1270 				goto exit;
   1271 			}
   1272 			num_params = 0;
   1273 		} else {
   1274 			switch(curr->expr_type) {
   1275 			case COND_NOT:	op = "not";	break;
   1276 			case COND_OR:	op = "or";	break;
   1277 			case COND_AND:	op = "and";	break;
   1278 			case COND_XOR:	op = "xor";	break;
   1279 			case COND_EQ:	op = "eq";	break;
   1280 			case COND_NEQ:	op = "neq";	break;
   1281 			default:
   1282 				rc = -1;
   1283 				goto exit;
   1284 			}
   1285 
   1286 			num_params = curr->expr_type == COND_NOT ? 1 : 2;
   1287 
   1288 			if (num_params == 1) {
   1289 				val1 = stack_pop(stack);
   1290 				val2 = strdup("");
   1291 				if (val2 == NULL) {
   1292 					log_err("Out of memory");
   1293 					rc = -1;
   1294 					goto exit;
   1295 				}
   1296 				fmt_str = "(%s %s)";
   1297 			} else {
   1298 				val2 = stack_pop(stack);
   1299 				val1 = stack_pop(stack);
   1300 				fmt_str = "(%s %s %s)";
   1301 			}
   1302 
   1303 			if (val1 == NULL || val2 == NULL) {
   1304 				log_err("Invalid conditional expression");
   1305 				rc = -1;
   1306 				goto exit;
   1307 			}
   1308 
   1309 			// length = length of parameters +
   1310 			//          length of operator +
   1311 			//          1 space preceeding each parameter +
   1312 			//          2 parens around the whole expression
   1313 			//          + null terminator
   1314 			len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1;
   1315 			new_val = malloc(len);
   1316 			if (new_val == NULL) {
   1317 				log_err("Out of memory");
   1318 				rc = -1;
   1319 				goto exit;
   1320 			}
   1321 
   1322 			// although we always supply val2 and there isn't always a 2nd
   1323 			// value, it should only be used when there are actually two values
   1324 			// in the format strings
   1325 			rlen = snprintf(new_val, len, fmt_str, op, val1, val2);
   1326 			if (rlen < 0 || rlen >= len) {
   1327 				log_err("Failed to generate conditional expression");
   1328 				rc = -1;
   1329 				goto exit;
   1330 			}
   1331 
   1332 			free(val1);
   1333 			free(val2);
   1334 			val1 = NULL;
   1335 			val2 = NULL;
   1336 		}
   1337 
   1338 		rc = stack_push(stack, new_val);
   1339 		if (rc != 0) {
   1340 			log_err("Out of memory");
   1341 			goto exit;
   1342 		}
   1343 		new_val = NULL;
   1344 	}
   1345 
   1346 	if (flags & COND_NODE_FLAGS_TUNABLE) {
   1347 		type = "tunableif";
   1348 	} else {
   1349 		type = "booleanif";
   1350 	}
   1351 
   1352 	val1 = stack_pop(stack);
   1353 	if (val1 == NULL || stack_peek(stack) != NULL) {
   1354 		log_err("Invalid conditional expression");
   1355 		rc = -1;
   1356 		goto exit;
   1357 	}
   1358 
   1359 	cil_println(indent, "(%s %s", type, val1);
   1360 	free(val1);
   1361 	val1 = NULL;
   1362 
   1363 	rc = 0;
   1364 
   1365 exit:
   1366 	free(new_val);
   1367 	free(val1);
   1368 	free(val2);
   1369 	while ((val1 = stack_pop(stack)) != NULL) {
   1370 		free(val1);
   1371 	}
   1372 	stack_destroy(&stack);
   1373 
   1374 	return rc;
   1375 }
   1376 
   1377 static int cond_list_to_cil(int indent, struct policydb *pdb, struct cond_node *cond_list, struct list *attr_list)
   1378 {
   1379 	int rc = 0;
   1380 	struct cond_node *cond;
   1381 
   1382 	for (cond = cond_list; cond != NULL; cond = cond->next) {
   1383 
   1384 		rc = cond_expr_to_cil(indent, pdb, cond->expr, cond->flags);
   1385 		if (rc != 0) {
   1386 			goto exit;
   1387 		}
   1388 
   1389 		if (cond->avtrue_list != NULL) {
   1390 			cil_println(indent + 1, "(true");
   1391 			rc = avrule_list_to_cil(indent + 2, pdb, cond->avtrue_list, attr_list);
   1392 			if (rc != 0) {
   1393 				goto exit;
   1394 			}
   1395 			cil_println(indent + 1, ")");
   1396 		}
   1397 
   1398 		if (cond->avfalse_list != NULL) {
   1399 			cil_println(indent + 1, "(false");
   1400 			rc = avrule_list_to_cil(indent + 2, pdb, cond->avfalse_list, attr_list);
   1401 			if (rc != 0) {
   1402 				goto exit;
   1403 			}
   1404 			cil_println(indent + 1, ")");
   1405 		}
   1406 
   1407 		cil_println(indent, ")");
   1408 	}
   1409 
   1410 exit:
   1411 	return rc;
   1412 }
   1413 
   1414 static int role_trans_to_cil(int indent, struct policydb *pdb, struct role_trans_rule *rules, struct list *role_attr_list, struct list *type_attr_list)
   1415 {
   1416 	int rc = 0;
   1417 	struct role_trans_rule *rule;
   1418 	char **role_names = NULL;
   1419 	int num_role_names = 0;
   1420 	int role;
   1421 	char **type_names = NULL;
   1422 	int num_type_names = 0;
   1423 	int type;
   1424 	uint32_t i;
   1425 	struct ebitmap_node *node;
   1426 	struct type_set *ts;
   1427 	struct role_set *rs;
   1428 
   1429 	for (rule = rules; rule != NULL; rule = rule->next) {
   1430 		rs = &rule->roles;
   1431 		rc = process_roleset(pdb, rs, role_attr_list, &role_names, &num_role_names);
   1432 		if (rc != 0) {
   1433 			goto exit;
   1434 		}
   1435 
   1436 		ts = &rule->types;
   1437 		rc = process_typeset(pdb, ts, type_attr_list, &type_names, &num_type_names);
   1438 		if (rc != 0) {
   1439 			goto exit;
   1440 		}
   1441 
   1442 		for (role = 0; role < num_role_names; role++) {
   1443 			for (type = 0; type < num_type_names; type++) {
   1444 				ebitmap_for_each_bit(&rule->classes, node, i) {
   1445 					if (!ebitmap_get_bit(&rule->classes, i)) {
   1446 						continue;
   1447 					}
   1448 					cil_println(indent, "(roletransition %s %s %s %s)",
   1449 						    role_names[role], type_names[type],
   1450 						    pdb->p_class_val_to_name[i],
   1451 						    pdb->p_role_val_to_name[rule->new_role - 1]);
   1452 				}
   1453 			}
   1454 		}
   1455 
   1456 		names_destroy(&role_names, &num_role_names);
   1457 		names_destroy(&type_names, &num_type_names);
   1458 	}
   1459 
   1460 exit:
   1461 	names_destroy(&role_names, &num_role_names);
   1462 	names_destroy(&type_names, &num_type_names);
   1463 
   1464 	return rc;
   1465 }
   1466 
   1467 static int role_allows_to_cil(int indent, struct policydb *pdb, struct role_allow_rule *rules, struct list *attr_list)
   1468 {
   1469 	int rc = -1;
   1470 	struct role_allow_rule *rule;
   1471 	char **roles = NULL;
   1472 	int num_roles = 0;
   1473 	char **new_roles = NULL;
   1474 	int num_new_roles = 0;
   1475 	int i,j;
   1476 	struct role_set *rs;
   1477 
   1478 	for (rule = rules; rule != NULL; rule = rule->next) {
   1479 		rs = &rule->roles;
   1480 		rc = process_roleset(pdb, rs, attr_list, &roles, &num_roles);
   1481 		if (rc != 0) {
   1482 			goto exit;
   1483 		}
   1484 
   1485 		rs = &rule->new_roles;
   1486 		rc = process_roleset(pdb, rs, attr_list, &new_roles, &num_new_roles);
   1487 		if (rc != 0) {
   1488 			goto exit;
   1489 		}
   1490 
   1491 		for (i = 0; i < num_roles; i++) {
   1492 			for (j = 0; j < num_new_roles; j++) {
   1493 				cil_println(indent, "(roleallow %s %s)", roles[i], new_roles[j]);
   1494 			}
   1495 		}
   1496 
   1497 		names_destroy(&roles, &num_roles);
   1498 		names_destroy(&new_roles, &num_new_roles);
   1499 	}
   1500 
   1501 	rc = 0;
   1502 
   1503 exit:
   1504 	names_destroy(&roles, &num_roles);
   1505 	names_destroy(&new_roles, &num_new_roles);
   1506 
   1507 	return rc;
   1508 }
   1509 
   1510 static int range_trans_to_cil(int indent, struct policydb *pdb, struct range_trans_rule *rules, struct list *attr_list)
   1511 {
   1512 	int rc = -1;
   1513 	struct range_trans_rule *rule;
   1514 	char **stypes = NULL;
   1515 	int num_stypes = 0;
   1516 	int stype;
   1517 	char **ttypes = NULL;
   1518 	int num_ttypes = 0;
   1519 	int ttype;
   1520 	struct ebitmap_node *node;
   1521 	uint32_t i;
   1522 	struct type_set *ts;
   1523 
   1524 	if (!pdb->mls) {
   1525 		return 0;
   1526 	}
   1527 
   1528 	for (rule = rules; rule != NULL; rule = rule->next) {
   1529 		ts = &rule->stypes;
   1530 		rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes);
   1531 		if (rc != 0) {
   1532 			goto exit;
   1533 		}
   1534 
   1535 		ts = &rule->ttypes;
   1536 		rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes);
   1537 		if (rc != 0) {
   1538 			goto exit;
   1539 		}
   1540 
   1541 		for (stype = 0; stype < num_stypes; stype++) {
   1542 			for (ttype = 0; ttype < num_ttypes; ttype++) {
   1543 				ebitmap_for_each_bit(&rule->tclasses, node, i) {
   1544 					if (!ebitmap_get_bit(&rule->tclasses, i)) {
   1545 						continue;
   1546 					}
   1547 
   1548 					cil_indent(indent);
   1549 					cil_printf("(rangetransition %s %s %s ", stypes[stype], ttypes[ttype], pdb->p_class_val_to_name[i]);
   1550 
   1551 					cil_printf("(");
   1552 
   1553 					rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[0]);
   1554 					if (rc != 0) {
   1555 						goto exit;
   1556 					}
   1557 
   1558 					cil_printf(" ");
   1559 
   1560 					rc = semantic_level_to_cil(pdb, 1, &rule->trange.level[1]);
   1561 					if (rc != 0) {
   1562 						goto exit;
   1563 					}
   1564 
   1565 					cil_printf("))\n");
   1566 				}
   1567 
   1568 			}
   1569 		}
   1570 
   1571 		names_destroy(&stypes, &num_stypes);
   1572 		names_destroy(&ttypes, &num_ttypes);
   1573 	}
   1574 
   1575 	rc = 0;
   1576 
   1577 exit:
   1578 	names_destroy(&stypes, &num_stypes);
   1579 	names_destroy(&ttypes, &num_ttypes);
   1580 
   1581 	return rc;
   1582 }
   1583 
   1584 static int filename_trans_to_cil(int indent, struct policydb *pdb, struct filename_trans_rule *rules, struct list *attr_list)
   1585 {
   1586 	int rc = -1;
   1587 	char **stypes = NULL;
   1588 	int num_stypes = 0;
   1589 	int stype;
   1590 	char **ttypes = NULL;
   1591 	int num_ttypes = 0;
   1592 	int ttype;
   1593 	struct type_set *ts;
   1594 	struct filename_trans_rule *rule;
   1595 
   1596 	for (rule = rules; rule != NULL; rule = rule->next) {
   1597 		ts = &rule->stypes;
   1598 		rc = process_typeset(pdb, ts, attr_list, &stypes, &num_stypes);
   1599 		if (rc != 0) {
   1600 			goto exit;
   1601 		}
   1602 
   1603 		ts = &rule->ttypes;
   1604 		rc = process_typeset(pdb, ts, attr_list, &ttypes, &num_ttypes);
   1605 		if (rc != 0) {
   1606 			goto exit;
   1607 		}
   1608 
   1609 		for (stype = 0; stype < num_stypes; stype++) {
   1610 			for (ttype = 0; ttype < num_ttypes; ttype++) {
   1611 				cil_println(indent, "(typetransition %s %s %s \"%s\" %s)",
   1612 					    stypes[stype], ttypes[ttype],
   1613 					    pdb->p_class_val_to_name[rule->tclass - 1],
   1614 					    rule->name,
   1615 					    pdb->p_type_val_to_name[rule->otype - 1]);
   1616 			}
   1617 		}
   1618 
   1619 		names_destroy(&stypes, &num_stypes);
   1620 		names_destroy(&ttypes, &num_ttypes);
   1621 	}
   1622 
   1623 	rc = 0;
   1624 exit:
   1625 	names_destroy(&stypes, &num_stypes);
   1626 	names_destroy(&ttypes, &num_ttypes);
   1627 
   1628 	return rc;
   1629 }
   1630 
   1631 struct class_perm_datum {
   1632 	char *name;
   1633 	uint32_t val;
   1634 };
   1635 
   1636 struct class_perm_array {
   1637 	struct class_perm_datum *perms;
   1638 	uint32_t count;
   1639 };
   1640 
   1641 static int class_perm_to_array(char *key, void *data, void *args)
   1642 {
   1643 	struct class_perm_array *arr = args;
   1644 	struct perm_datum *datum = data;
   1645 	arr->perms[arr->count].name = key;
   1646 	arr->perms[arr->count].val = datum->s.value;
   1647 	arr->count++;
   1648 
   1649 	return 0;
   1650 }
   1651 
   1652 static int class_perm_cmp(const void *a, const void *b)
   1653 {
   1654 	const struct class_perm_datum *aa = a;
   1655 	const struct class_perm_datum *bb = b;
   1656 
   1657 	return aa->val - bb->val;
   1658 }
   1659 
   1660 static int common_to_cil(char *key, void *data, void *UNUSED(arg))
   1661 {
   1662 	int rc = -1;
   1663 	struct common_datum *common = data;
   1664 	struct class_perm_array arr;
   1665 	uint32_t i;
   1666 
   1667 	arr.count = 0;
   1668 	arr.perms = calloc(common->permissions.nprim, sizeof(*arr.perms));
   1669 	rc = hashtab_map(common->permissions.table, class_perm_to_array, &arr);
   1670 	if (rc != 0) {
   1671 		goto exit;
   1672 	}
   1673 
   1674 	qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp);
   1675 
   1676 	cil_printf("(common %s (", key);
   1677 	for (i = 0; i < arr.count; i++) {
   1678 		cil_printf("%s ", arr.perms[i].name);
   1679 	}
   1680 	cil_printf("))\n");
   1681 
   1682 	rc = 0;
   1683 
   1684 exit:
   1685 	free(arr.perms);
   1686 	return rc;
   1687 }
   1688 
   1689 
   1690 static int constraint_expr_to_string(struct policydb *pdb, struct constraint_expr *exprs, char **expr_string)
   1691 {
   1692 	int rc = -1;
   1693 	struct constraint_expr *expr;
   1694 	struct stack *stack = NULL;
   1695 	int len = 0;
   1696 	int rlen;
   1697 	char *new_val = NULL;
   1698 	char *val1 = NULL;
   1699 	char *val2 = NULL;
   1700 	uint32_t num_params;
   1701 	const char *op;
   1702 	const char *fmt_str;
   1703 	const char *attr1;
   1704 	const char *attr2;
   1705 	char *names;
   1706 	char **name_list = NULL;
   1707 	int num_names = 0;
   1708 	struct type_set *ts;
   1709 
   1710 	rc = stack_init(&stack);
   1711 	if (rc != 0) {
   1712 		goto exit;
   1713 	}
   1714 
   1715 	for (expr = exprs; expr != NULL; expr = expr->next) {
   1716 		if (expr->expr_type == CEXPR_ATTR || expr->expr_type == CEXPR_NAMES) {
   1717 			switch (expr->op) {
   1718 			case CEXPR_EQ:      op = "eq";     break;
   1719 			case CEXPR_NEQ:     op = "neq";    break;
   1720 			case CEXPR_DOM:     op = "dom";    break;
   1721 			case CEXPR_DOMBY:   op = "domby";  break;
   1722 			case CEXPR_INCOMP:  op = "incomp"; break;
   1723 			default:
   1724 				log_err("Unknown constraint operator type: %i", expr->op);
   1725 				rc = -1;
   1726 				goto exit;
   1727 			}
   1728 
   1729 			switch (expr->attr) {
   1730 			case CEXPR_USER:                 attr1 = "u1"; attr2 = "u2"; break;
   1731 			case CEXPR_USER | CEXPR_TARGET:  attr1 = "u2"; attr2 = "";   break;
   1732 			case CEXPR_USER | CEXPR_XTARGET: attr1 = "u3"; attr2 = "";   break;
   1733 			case CEXPR_ROLE:                 attr1 = "r1"; attr2 = "r2"; break;
   1734 			case CEXPR_ROLE | CEXPR_TARGET:  attr1 = "r2"; attr2 = "";   break;
   1735 			case CEXPR_ROLE | CEXPR_XTARGET: attr1 = "r3"; attr2 = "";   break;
   1736 			case CEXPR_TYPE:                 attr1 = "t1"; attr2 = "";   break;
   1737 			case CEXPR_TYPE | CEXPR_TARGET:  attr1 = "t2"; attr2 = "";   break;
   1738 			case CEXPR_TYPE | CEXPR_XTARGET: attr1 = "t3"; attr2 = "";   break;
   1739 			case CEXPR_L1L2:                 attr1 = "l1"; attr2 = "l2"; break;
   1740 			case CEXPR_L1H2:                 attr1 = "l1"; attr2 = "h2"; break;
   1741 			case CEXPR_H1L2:                 attr1 = "h1"; attr2 = "l2"; break;
   1742 			case CEXPR_H1H2:                 attr1 = "h1"; attr2 = "h2"; break;
   1743 			case CEXPR_L1H1:                 attr1 = "l1"; attr2 = "h1"; break;
   1744 			case CEXPR_L2H2:                 attr1 = "l2"; attr2 = "h2"; break;
   1745 			default:
   1746 				log_err("Unknown expression attribute type: %i", expr->attr);
   1747 				rc = -1;
   1748 				goto exit;
   1749 			}
   1750 
   1751 			if (expr->expr_type == CEXPR_ATTR) {
   1752 				// length of values/attrs + 2 separating spaces + 2 parens + null terminator
   1753 				len = strlen(op) + strlen(attr1) + strlen(attr2) + 2 + 2 + 1;
   1754 				new_val = malloc(len);
   1755 				if (new_val == NULL) {
   1756 					log_err("Out of memory");
   1757 					rc = -1;
   1758 					goto exit;
   1759 				}
   1760 				rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, attr2);
   1761 				if (rlen < 0 || rlen >= len) {
   1762 					log_err("Failed to generate constraint expression");
   1763 					rc = -1;
   1764 					goto exit;
   1765 				}
   1766 			} else {
   1767 				if (expr->attr & CEXPR_TYPE) {
   1768 					ts = expr->type_names;
   1769 					rc = ebitmap_to_names(&ts->types, pdb->p_type_val_to_name, &name_list, &num_names);
   1770 					if (rc != 0) {
   1771 						goto exit;
   1772 					}
   1773 				} else if (expr->attr & CEXPR_USER) {
   1774 					rc = ebitmap_to_names(&expr->names, pdb->p_user_val_to_name, &name_list, &num_names);
   1775 					if (rc != 0) {
   1776 						goto exit;
   1777 					}
   1778 				} else if (expr->attr & CEXPR_ROLE) {
   1779 					rc = ebitmap_to_names(&expr->names, pdb->p_role_val_to_name, &name_list, &num_names);
   1780 					if (rc != 0) {
   1781 						goto exit;
   1782 					}
   1783 				}
   1784 				rc = name_list_to_string(name_list, num_names, &names);
   1785 				if (rc != 0) {
   1786 					goto exit;
   1787 				}
   1788 
   1789 				// length of values/oper + 2 spaces + 2 parens + null terminator
   1790 				len = strlen(op) + strlen(attr1) +  strlen(names) + 2 + 2 + 1;
   1791 				new_val = malloc(len);
   1792 				if (new_val == NULL) {
   1793 					log_err("Out of memory");
   1794 					rc = -1;
   1795 					goto exit;
   1796 				}
   1797 				rlen = snprintf(new_val, len, "(%s %s %s)", op, attr1, names);
   1798 				if (rlen < 0 || rlen >= len) {
   1799 					log_err("Failed to generate constraint expression");
   1800 					rc = -1;
   1801 					goto exit;
   1802 				}
   1803 
   1804 				names_destroy(&name_list, &num_names);
   1805 				free(names);
   1806 			}
   1807 
   1808 			num_params = 0;
   1809 		} else {
   1810 			switch (expr->expr_type) {
   1811 			case CEXPR_NOT: op = "not"; break;
   1812 			case CEXPR_AND: op = "and"; break;
   1813 			case CEXPR_OR:  op = "or"; break;
   1814 			default:
   1815 				log_err("Unknown constraint expression type: %i", expr->expr_type);
   1816 				rc = -1;
   1817 				goto exit;
   1818 			}
   1819 
   1820 			num_params = expr->expr_type == CEXPR_NOT ? 1 : 2;
   1821 
   1822 			if (num_params == 1) {
   1823 				val1 = stack_pop(stack);
   1824 				val2 = strdup("");
   1825 				if (val2 == NULL) {
   1826 					log_err("Out of memory");
   1827 					rc = -1;
   1828 					goto exit;
   1829 				}
   1830 				fmt_str = "(%s %s)";
   1831 			} else {
   1832 				val2 = stack_pop(stack);
   1833 				val1 = stack_pop(stack);
   1834 				fmt_str = "(%s %s %s)";
   1835 			}
   1836 
   1837 			if (val1 == NULL || val2 == NULL) {
   1838 				log_err("Invalid constraint expression");
   1839 				rc = -1;
   1840 				goto exit;
   1841 			}
   1842 
   1843 			// length = length of parameters +
   1844 			//          length of operator +
   1845 			//          1 space preceeding each parameter +
   1846 			//          2 parens around the whole expression
   1847 			//          + null terminator
   1848 			len = strlen(val1) + strlen(val2) + strlen(op) + (num_params * 1) + 2 + 1;
   1849 			new_val = malloc(len);
   1850 			if (new_val == NULL) {
   1851 				log_err("Out of memory");
   1852 				rc = -1;
   1853 				goto exit;
   1854 			}
   1855 
   1856 			// although we always supply val2 and there isn't always a 2nd
   1857 			// value, it should only be used when there are actually two values
   1858 			// in the format strings
   1859 			rlen = snprintf(new_val, len, fmt_str, op, val1, val2);
   1860 			if (rlen < 0 || rlen >= len) {
   1861 				log_err("Failed to generate constraint expression");
   1862 				rc = -1;
   1863 				goto exit;
   1864 			}
   1865 
   1866 			free(val1);
   1867 			free(val2);
   1868 			val1 = NULL;
   1869 			val2 = NULL;
   1870 		}
   1871 
   1872 		rc = stack_push(stack, new_val);
   1873 		if (rc != 0) {
   1874 			log_err("Out of memory");
   1875 			goto exit;
   1876 		}
   1877 
   1878 		new_val = NULL;
   1879 	}
   1880 
   1881 	new_val = stack_pop(stack);
   1882 	if (new_val == NULL || stack_peek(stack) != NULL) {
   1883 		log_err("Invalid constraint expression");
   1884 		rc = -1;
   1885 		goto exit;
   1886 	}
   1887 
   1888 	*expr_string = new_val;
   1889 	new_val = NULL;
   1890 
   1891 	rc = 0;
   1892 
   1893 exit:
   1894 	names_destroy(&name_list, &num_names);
   1895 
   1896 	free(new_val);
   1897 	free(val1);
   1898 	free(val2);
   1899 	while ((val1 = stack_pop(stack)) != NULL) {
   1900 		free(val1);
   1901 	}
   1902 	stack_destroy(&stack);
   1903 
   1904 	return rc;
   1905 }
   1906 
   1907 
   1908 static int constraints_to_cil(int indent, struct policydb *pdb, char *classkey, struct class_datum *class, struct constraint_node *constraints, int is_constraint)
   1909 {
   1910 	int rc = -1;
   1911 	struct constraint_node *node;
   1912 	char *expr = NULL;
   1913 	const char *mls;
   1914 	char *perms;
   1915 
   1916 	mls = pdb->mls ? "mls" : "";
   1917 
   1918 	for (node = constraints; node != NULL; node = node->next) {
   1919 
   1920 		rc = constraint_expr_to_string(pdb, node->expr, &expr);
   1921 		if (rc != 0) {
   1922 			goto exit;
   1923 		}
   1924 
   1925 		if (is_constraint) {
   1926 			perms = sepol_av_to_string(pdb, class->s.value, node->permissions);
   1927 			cil_println(indent, "(%sconstrain (%s (%s)) %s)", mls, classkey, perms + 1, expr);
   1928 		} else {
   1929 			cil_println(indent, "(%svalidatetrans %s %s)", mls, classkey, expr);
   1930 		}
   1931 
   1932 		free(expr);
   1933 		expr = NULL;
   1934 	}
   1935 
   1936 	rc = 0;
   1937 
   1938 exit:
   1939 	free(expr);
   1940 	return rc;
   1941 }
   1942 
   1943 static int class_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
   1944 {
   1945 	int rc = -1;
   1946 	struct class_datum *class = datum;
   1947 	const char *dflt;
   1948 	struct class_perm_array arr;
   1949 	uint32_t i;
   1950 
   1951 	if (scope == SCOPE_REQ) {
   1952 		return 0;
   1953 	}
   1954 
   1955 	arr.count = 0;
   1956 	arr.perms = calloc(class->permissions.nprim, sizeof(*arr.perms));
   1957 	rc = hashtab_map(class->permissions.table, class_perm_to_array, &arr);
   1958 	if (rc != 0) {
   1959 		goto exit;
   1960 	}
   1961 
   1962 	qsort(arr.perms, arr.count, sizeof(*arr.perms), class_perm_cmp);
   1963 
   1964 	cil_indent(indent);
   1965 	cil_printf("(class %s (", key);
   1966 	for (i = 0; i < arr.count; i++) {
   1967 		cil_printf("%s ", arr.perms[i].name);
   1968 	}
   1969 	cil_printf("))\n");
   1970 
   1971 	if (class->comkey != NULL) {
   1972 		cil_println(indent, "(classcommon %s %s)", key, class->comkey);
   1973 	}
   1974 
   1975 	if (class->default_user != 0) {
   1976 		switch (class->default_user) {
   1977 		case DEFAULT_SOURCE:	dflt = "source";	break;
   1978 		case DEFAULT_TARGET:	dflt = "target";	break;
   1979 		default:
   1980 			log_err("Unknown default user value: %i", class->default_user);
   1981 			rc = -1;
   1982 			goto exit;
   1983 		}
   1984 		cil_println(indent, "(defaultuser %s %s)", key, dflt);
   1985 	}
   1986 
   1987 	if (class->default_role != 0) {
   1988 		switch (class->default_role) {
   1989 		case DEFAULT_SOURCE:	dflt = "source";	break;
   1990 		case DEFAULT_TARGET:	dflt = "target";	break;
   1991 		default:
   1992 			log_err("Unknown default role value: %i", class->default_role);
   1993 			rc = -1;
   1994 			goto exit;
   1995 		}
   1996 		cil_println(indent, "(defaultrole %s %s)", key, dflt);
   1997 	}
   1998 
   1999 	if (class->default_type != 0) {
   2000 		switch (class->default_type) {
   2001 		case DEFAULT_SOURCE:	dflt = "source";	break;
   2002 		case DEFAULT_TARGET:	dflt = "target";	break;
   2003 		default:
   2004 			log_err("Unknown default type value: %i", class->default_type);
   2005 			rc = -1;
   2006 			goto exit;
   2007 		}
   2008 		cil_println(indent, "(defaulttype %s %s)", key, dflt);
   2009 	}
   2010 
   2011 	if (class->default_range != 0) {
   2012 		switch (class->default_range) {
   2013 		case DEFAULT_SOURCE_LOW:		dflt = "source low";	break;
   2014 		case DEFAULT_SOURCE_HIGH:		dflt = "source high";	break;
   2015 		case DEFAULT_SOURCE_LOW_HIGH:	dflt = "source low-high";	break;
   2016 		case DEFAULT_TARGET_LOW:		dflt = "target low";	break;
   2017 		case DEFAULT_TARGET_HIGH:		dflt = "target high";	break;
   2018 		case DEFAULT_TARGET_LOW_HIGH:	dflt = "target low-high";	break;
   2019 		default:
   2020 			log_err("Unknown default range value: %i", class->default_range);
   2021 			rc = -1;
   2022 			goto exit;
   2023 		}
   2024 		cil_println(indent, "(defaultrange %s %s)", key, dflt);
   2025 
   2026 	}
   2027 
   2028 	if (class->constraints != NULL) {
   2029 		rc = constraints_to_cil(indent, pdb, key, class, class->constraints, 1);
   2030 		if (rc != 0) {
   2031 			goto exit;
   2032 		}
   2033 	}
   2034 
   2035 	if (class->validatetrans != NULL) {
   2036 		rc = constraints_to_cil(indent, pdb, key, class, class->validatetrans, 0);
   2037 		if (rc != 0) {
   2038 			goto exit;
   2039 		}
   2040 	}
   2041 
   2042 	rc = 0;
   2043 
   2044 exit:
   2045 	free(arr.perms);
   2046 	return rc;
   2047 }
   2048 
   2049 static int class_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order)
   2050 {
   2051 	struct ebitmap_node *node;
   2052 	uint32_t i;
   2053 
   2054 	if (ebitmap_cardinality(&order) == 0) {
   2055 		return 0;
   2056 	}
   2057 
   2058 	cil_indent(indent);
   2059 	cil_printf("(classorder (");
   2060 
   2061 	ebitmap_for_each_bit(&order, node, i) {
   2062 		if (!ebitmap_get_bit(&order, i)) {
   2063 			continue;
   2064 		}
   2065 		cil_printf("%s ", pdb->sym_val_to_name[SYM_CLASSES][i]);
   2066 	}
   2067 
   2068 	cil_printf("))\n");
   2069 
   2070 	return 0;
   2071 }
   2072 
   2073 static int role_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope)
   2074 {
   2075 	int rc = -1;
   2076 	struct ebitmap_node *node;
   2077 	uint32_t i;
   2078 	int j;
   2079 	char **types = NULL;
   2080 	int num_types = 0;
   2081 	struct role_datum *role = datum;
   2082 	struct type_set *ts;
   2083 	struct list *attr_list = NULL;
   2084 
   2085 	rc = list_init(&attr_list);
   2086 	if (rc != 0) {
   2087 		goto exit;
   2088 	}
   2089 
   2090 	if (scope == SCOPE_REQ) {
   2091 		// if a role/roleattr is in the REQ scope, then it could cause an
   2092 		// optional block to fail, even if it is never used. However in CIL,
   2093 		// symbols must be used in order to cause an optional block to fail. So
   2094 		// for symbols in the REQ scope, add them to a roleattribute as a way
   2095 		// to 'use' them in the optional without affecting the resulting policy.
   2096 		cil_println(indent, "(roleattributeset " GEN_REQUIRE_ATTR " %s)", key);
   2097 	}
   2098 
   2099 	switch (role->flavor) {
   2100 	case ROLE_ROLE:
   2101 		if (scope == SCOPE_DECL) {
   2102 			// Only declare certain roles if we are reading a base module.
   2103 			// These roles are defined in the base module and sometimes in
   2104 			// other non-base modules. If we generated the roles regardless of
   2105 			// the policy type, it would result in duplicate declarations,
   2106 			// which isn't allowed in CIL. Patches have been made to refpolicy
   2107 			// to remove these duplicate role declarations, but we need to be
   2108 			// backwards compatable and support older policies. Since we know
   2109 			// these roles are always declared in base, only print them when we
   2110 			// see them in the base module. If the declarations appear in a
   2111 			// non-base module, ignore their declarations.
   2112 			//
   2113 			// Note that this is a hack, and if a policy author does not define
   2114 			// one of these roles in base, the declaration will not appeaer in
   2115 			// the resulting policy, likely resulting in a compilation error in
   2116 			// CIL.
   2117 			//
   2118 			// To make things more complicated, the auditadm_r and secadm_r
   2119 			// roles could actually be in either the base module or a non-base
   2120 			// module, or both. So we can't rely on this same behavior. So for
   2121 			// these roles, don't declare them here, even if they are in a base
   2122 			// or non-base module. Instead we will just declare them in the
   2123 			// base module elsewhere.
   2124 			int is_base_role = (!strcmp(key, "user_r") ||
   2125 			                    !strcmp(key, "staff_r") ||
   2126 			                    !strcmp(key, "sysadm_r") ||
   2127 			                    !strcmp(key, "system_r") ||
   2128 			                    !strcmp(key, "unconfined_r"));
   2129 			int is_builtin_role = (!strcmp(key, "auditadm_r") ||
   2130 			                       !strcmp(key, "secadm_r"));
   2131 			if ((is_base_role && pdb->policy_type == SEPOL_POLICY_BASE) ||
   2132 			    (!is_base_role && !is_builtin_role)) {
   2133 				cil_println(indent, "(role %s)", key);
   2134 			}
   2135 		}
   2136 
   2137 		if (ebitmap_cardinality(&role->dominates) > 1) {
   2138 			log_err("Warning: role 'dominance' statement unsupported in CIL. Dropping from output.");
   2139 		}
   2140 
   2141 		ts = &role->types;
   2142 		rc = process_typeset(pdb, ts, attr_list, &types, &num_types);
   2143 		if (rc != 0) {
   2144 			goto exit;
   2145 		}
   2146 
   2147 		for (j = 0; j < num_types; j++) {
   2148 			if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) {
   2149 				cil_println(indent, "(roletype %s %s)", key, types[j]);
   2150 			}
   2151 		}
   2152 
   2153 		if (role->bounds > 0) {
   2154 			cil_println(indent, "(rolebounds %s %s)", key, pdb->p_role_val_to_name[role->bounds - 1]);
   2155 		}
   2156 		break;
   2157 
   2158 	case ROLE_ATTRIB:
   2159 		if (scope == SCOPE_DECL) {
   2160 			cil_println(indent, "(roleattribute %s)", key);
   2161 		}
   2162 
   2163 		if (ebitmap_cardinality(&role->roles) > 0) {
   2164 			cil_indent(indent);
   2165 			cil_printf("(roleattributeset %s (", key);
   2166 			ebitmap_for_each_bit(&role->roles, node, i) {
   2167 				if (!ebitmap_get_bit(&role->roles, i)) {
   2168 					continue;
   2169 				}
   2170 				cil_printf("%s ", pdb->p_role_val_to_name[i]);
   2171 			}
   2172 			cil_printf("))\n");
   2173 		}
   2174 
   2175 		ts = &role->types;
   2176 		rc = process_typeset(pdb, ts, attr_list, &types, &num_types);
   2177 		if (rc != 0) {
   2178 			goto exit;
   2179 		}
   2180 
   2181 
   2182 		for (j = 0; j < num_types; j++) {
   2183 			if (is_id_in_scope(pdb, decl_stack, types[j], SYM_TYPES)) {
   2184 				cil_println(indent, "(roletype %s %s)", key, types[j]);
   2185 			}
   2186 		}
   2187 
   2188 		break;
   2189 
   2190 	default:
   2191 		log_err("Unknown role type: %i", role->flavor);
   2192 		rc = -1;
   2193 		goto exit;
   2194 	}
   2195 
   2196 	rc = cil_print_attr_list(indent, pdb, attr_list);
   2197 	if (rc != 0) {
   2198 		goto exit;
   2199 	}
   2200 
   2201 exit:
   2202 	attr_list_destroy(&attr_list);
   2203 	names_destroy(&types, &num_types);
   2204 
   2205 	return rc;
   2206 }
   2207 
   2208 static int type_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack, char *key, void *datum, int scope)
   2209 {
   2210 	int rc = -1;
   2211 	struct type_datum *type = datum;
   2212 
   2213 	if (scope == SCOPE_REQ) {
   2214 		// if a type/typeattr is in the REQ scope, then it could cause an
   2215 		// optional block to fail, even if it is never used. However in CIL,
   2216 		// symbols must be used in order to cause an optional block to fail. So
   2217 		// for symbols in the REQ scope, add them to a typeattribute as a way
   2218 		// to 'use' them in the optional without affecting the resulting policy.
   2219 		cil_println(indent, "(typeattributeset " GEN_REQUIRE_ATTR " %s)", key);
   2220 	}
   2221 
   2222 	rc = roletype_role_in_ancestor_to_cil(pdb, decl_stack, key, indent);
   2223 	if (rc != 0) {
   2224 		goto exit;
   2225 	}
   2226 
   2227 	switch(type->flavor) {
   2228 	case TYPE_TYPE:
   2229 		if (scope == SCOPE_DECL) {
   2230 			cil_println(indent, "(type %s)", key);
   2231 			// object_r is implicit in checkmodule, but not with CIL,
   2232 			// create it as part of base
   2233 			cil_println(indent, "(roletype " DEFAULT_OBJECT " %s)", key);
   2234 		}
   2235 
   2236 		if (type->flags & TYPE_FLAGS_PERMISSIVE) {
   2237 			cil_println(indent, "(typepermissive %s)", key);
   2238 		}
   2239 
   2240 		if (type->bounds > 0) {
   2241 			cil_println(indent, "(typebounds %s %s)", pdb->p_type_val_to_name[type->bounds - 1], key);
   2242 		}
   2243 		break;
   2244 	case TYPE_ATTRIB:
   2245 		if (scope == SCOPE_DECL) {
   2246 			cil_println(indent, "(typeattribute %s)", key);
   2247 		}
   2248 
   2249 		if (ebitmap_cardinality(&type->types) > 0) {
   2250 			cil_indent(indent);
   2251 			cil_printf("(typeattributeset %s (", key);
   2252 			ebitmap_to_cil(pdb, &type->types, SYM_TYPES);
   2253 			cil_printf("))\n");
   2254 		}
   2255 		break;
   2256 	default:
   2257 		log_err("Unknown flavor (%i) of type %s", type->flavor, key);
   2258 		rc = -1;
   2259 		goto exit;
   2260 	}
   2261 
   2262 	rc = 0;
   2263 
   2264 exit:
   2265 	return rc;
   2266 }
   2267 
   2268 static int user_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *UNUSED(decl_stack), char *key, void *datum,  int scope)
   2269 {
   2270 	struct user_datum *user = datum;
   2271 	struct ebitmap roles = user->roles.roles;
   2272 	struct mls_semantic_level level = user->dfltlevel;
   2273 	struct mls_semantic_range range = user->range;
   2274 	struct ebitmap_node *node;
   2275 	uint32_t i;
   2276 	int sens_offset = 1;
   2277 
   2278 	if (scope == SCOPE_DECL) {
   2279 		cil_println(indent, "(user %s)", key);
   2280 		// object_r is implicit in checkmodule, but not with CIL, create it
   2281 		// as part of base
   2282 		cil_println(indent, "(userrole %s " DEFAULT_OBJECT ")", key);
   2283 	}
   2284 
   2285 	ebitmap_for_each_bit(&roles, node, i) {
   2286 		if (!ebitmap_get_bit(&roles, i)) {
   2287 			continue;
   2288 		}
   2289 		cil_println(indent, "(userrole %s %s)", key, pdb->p_role_val_to_name[i]);
   2290 	}
   2291 
   2292 	if (block->flags & AVRULE_OPTIONAL) {
   2293 		// sensitivites in user statements in optionals do not have the
   2294 		// standard -1 offest
   2295 		sens_offset = 0;
   2296 	}
   2297 
   2298 	cil_indent(indent);
   2299 	cil_printf("(userlevel %s ", key);
   2300 	if (pdb->mls) {
   2301 		semantic_level_to_cil(pdb, sens_offset, &level);
   2302 	} else {
   2303 		cil_printf(DEFAULT_LEVEL);
   2304 	}
   2305 	cil_printf(")\n");
   2306 
   2307 	cil_indent(indent);
   2308 	cil_printf("(userrange %s (", key);
   2309 	if (pdb->mls) {
   2310 		semantic_level_to_cil(pdb, sens_offset, &range.level[0]);
   2311 		cil_printf(" ");
   2312 		semantic_level_to_cil(pdb, sens_offset, &range.level[1]);
   2313 	} else {
   2314 		cil_printf(DEFAULT_LEVEL " " DEFAULT_LEVEL);
   2315 	}
   2316 	cil_printf("))\n");
   2317 
   2318 
   2319 	return 0;
   2320 }
   2321 
   2322 static int boolean_to_cil(int indent, struct policydb *UNUSED(pdb), struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum,  int scope)
   2323 {
   2324 	struct cond_bool_datum *boolean = datum;
   2325 	const char *type;
   2326 
   2327 	if (scope == SCOPE_DECL) {
   2328 		if (boolean->flags & COND_BOOL_FLAGS_TUNABLE) {
   2329 			type = "tunable";
   2330 		} else {
   2331 			type = "boolean";
   2332 		}
   2333 
   2334 		cil_println(indent, "(%s %s %s)", type, key, boolean->state ? "true" : "false");
   2335 	}
   2336 
   2337 	return 0;
   2338 }
   2339 
   2340 static int sens_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum, int scope)
   2341 {
   2342 	struct level_datum *level = datum;
   2343 
   2344 	if (scope == SCOPE_DECL) {
   2345 		if (!level->isalias) {
   2346 			cil_println(indent, "(sensitivity %s)", key);
   2347 		} else {
   2348 			cil_println(indent, "(sensitivityalias %s)", key);
   2349 			cil_println(indent, "(sensitivityaliasactual %s %s)", key, pdb->p_sens_val_to_name[level->level->sens - 1]);
   2350 		}
   2351 	}
   2352 
   2353 	if (ebitmap_cardinality(&level->level->cat) > 0) {
   2354 		cil_indent(indent);
   2355 		cil_printf("(sensitivitycategory %s (", key);
   2356 		ebitmap_to_cil(pdb, &level->level->cat, SYM_CATS);
   2357 		cil_printf("))\n");
   2358 	}
   2359 
   2360 	return 0;
   2361 }
   2362 
   2363 static int sens_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order)
   2364 {
   2365 	struct ebitmap_node *node;
   2366 	uint32_t i;
   2367 
   2368 	if (ebitmap_cardinality(&order) == 0) {
   2369 		return 0;
   2370 	}
   2371 
   2372 	cil_indent(indent);
   2373 	cil_printf("(sensitivityorder (");
   2374 
   2375 	ebitmap_for_each_bit(&order, node, i) {
   2376 		if (!ebitmap_get_bit(&order, i)) {
   2377 			continue;
   2378 		}
   2379 		cil_printf("%s ", pdb->p_sens_val_to_name[i]);
   2380 	}
   2381 
   2382 	cil_printf("))\n");
   2383 
   2384 	return 0;
   2385 }
   2386 
   2387 static int cat_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *UNUSED(decl_stack), char *key, void *datum,  int scope)
   2388 {
   2389 	struct cat_datum *cat = datum;
   2390 
   2391 	if (scope == SCOPE_REQ) {
   2392 		return 0;
   2393 	}
   2394 
   2395 	if (!cat->isalias) {
   2396 		cil_println(indent, "(category %s)", key);
   2397 	} else {
   2398 		cil_println(indent, "(categoryalias %s)", key);
   2399 		cil_println(indent, "(categoryaliasactual %s %s)", key, pdb->p_cat_val_to_name[cat->s.value - 1]);
   2400 	}
   2401 
   2402 	return 0;
   2403 }
   2404 
   2405 static int cat_order_to_cil(int indent, struct policydb *pdb, struct ebitmap order)
   2406 {
   2407 	int rc = -1;
   2408 	struct ebitmap_node *node;
   2409 	uint32_t i;
   2410 
   2411 	if (ebitmap_cardinality(&order) == 0) {
   2412 		rc = 0;
   2413 		goto exit;
   2414 	}
   2415 
   2416 	cil_indent(indent);
   2417 	cil_printf("(categoryorder (");
   2418 
   2419 	ebitmap_for_each_bit(&order, node, i) {
   2420 		if (!ebitmap_get_bit(&order, i)) {
   2421 			continue;
   2422 		}
   2423 		cil_printf("%s ", pdb->p_cat_val_to_name[i]);
   2424 	}
   2425 
   2426 	cil_printf("))\n");
   2427 
   2428 	return 0;
   2429 exit:
   2430 	return rc;
   2431 }
   2432 
   2433 static int polcaps_to_cil(struct policydb *pdb)
   2434 {
   2435 	int rc = -1;
   2436 	struct ebitmap *map;
   2437 	struct ebitmap_node *node;
   2438 	uint32_t i;
   2439 	const char *name;
   2440 
   2441 	map = &pdb->policycaps;
   2442 
   2443 	ebitmap_for_each_bit(map, node, i) {
   2444 		if (!ebitmap_get_bit(map, i)) {
   2445 			continue;
   2446 		}
   2447 		name = sepol_polcap_getname(i);
   2448 		if (name == NULL) {
   2449 			log_err("Unknown policy capability id: %i", i);
   2450 			rc = -1;
   2451 			goto exit;
   2452 		}
   2453 
   2454 		cil_println(0, "(policycap %s)", name);
   2455 	}
   2456 
   2457 	return 0;
   2458 exit:
   2459 	return rc;
   2460 }
   2461 
   2462 static int level_to_cil(struct policydb *pdb, struct mls_level *level)
   2463 {
   2464 	struct ebitmap *map = &level->cat;
   2465 
   2466 	cil_printf("(%s", pdb->p_sens_val_to_name[level->sens - 1]);
   2467 
   2468 	if (ebitmap_cardinality(map) > 0) {
   2469 		cil_printf("(");
   2470 		ebitmap_to_cil(pdb, map, SYM_CATS);
   2471 		cil_printf(")");
   2472 	}
   2473 
   2474 	cil_printf(")");
   2475 
   2476 	return 0;
   2477 }
   2478 
   2479 static int context_to_cil(struct policydb *pdb, struct context_struct *con)
   2480 {
   2481 	cil_printf("(%s %s %s (",
   2482 		pdb->p_user_val_to_name[con->user - 1],
   2483 		pdb->p_role_val_to_name[con->role - 1],
   2484 		pdb->p_type_val_to_name[con->type - 1]);
   2485 
   2486 	if (pdb->mls) {
   2487 		level_to_cil(pdb, &con->range.level[0]);
   2488 		cil_printf(" ");
   2489 		level_to_cil(pdb, &con->range.level[1]);
   2490 	} else {
   2491 		cil_printf(DEFAULT_LEVEL);
   2492 		cil_printf(" ");
   2493 		cil_printf(DEFAULT_LEVEL);
   2494 	}
   2495 
   2496 	cil_printf("))");
   2497 
   2498 	return 0;
   2499 }
   2500 
   2501 static int ocontext_isid_to_cil(struct policydb *pdb, const char **sid_to_string, struct ocontext *isids)
   2502 {
   2503 	int rc = -1;
   2504 
   2505 	struct ocontext *isid;
   2506 
   2507 	struct sid_item {
   2508 		const char *sid_key;
   2509 		struct sid_item *next;
   2510 	};
   2511 
   2512 	struct sid_item *head = NULL;
   2513 	struct sid_item *item = NULL;
   2514 
   2515 	for (isid = isids; isid != NULL; isid = isid->next) {
   2516 		cil_println(0, "(sid %s)", sid_to_string[isid->sid[0]]);
   2517 		cil_printf("(sidcontext %s ", sid_to_string[isid->sid[0]]);
   2518 		context_to_cil(pdb, &isid->context[0]);
   2519 		cil_printf(")\n");
   2520 
   2521 		// get the sid names in the correct order (reverse from the isids
   2522 		// ocontext) for sidorder statement
   2523 		item = malloc(sizeof(*item));
   2524 		if (item == NULL) {
   2525 			log_err("Out of memory");
   2526 			rc = -1;
   2527 			goto exit;
   2528 		}
   2529 		item->sid_key = sid_to_string[isid->sid[0]];
   2530 		item->next = head;
   2531 		head = item;
   2532 	}
   2533 
   2534 	if (head != NULL) {
   2535 		cil_printf("(sidorder (");
   2536 		for (item = head; item != NULL; item = item->next) {
   2537 			cil_printf("%s ", item->sid_key);
   2538 		}
   2539 		cil_printf("))\n");
   2540 	}
   2541 
   2542 	rc = 0;
   2543 
   2544 exit:
   2545 	while(head) {
   2546 		item = head;
   2547 		head = item->next;
   2548 		free(item);
   2549 	}
   2550 	return rc;
   2551 }
   2552 
   2553 static int ocontext_selinux_isid_to_cil(struct policydb *pdb, struct ocontext *isids)
   2554 {
   2555 	int rc = -1;
   2556 
   2557 	// initial sid names aren't actually stored in the pp files, need to a have
   2558 	// a mapping, taken from the linux kernel
   2559 	static const char *selinux_sid_to_string[] = {
   2560 		"null",
   2561 		"kernel",
   2562 		"security",
   2563 		"unlabeled",
   2564 		"fs",
   2565 		"file",
   2566 		"file_labels",
   2567 		"init",
   2568 		"any_socket",
   2569 		"port",
   2570 		"netif",
   2571 		"netmsg",
   2572 		"node",
   2573 		"igmp_packet",
   2574 		"icmp_socket",
   2575 		"tcp_socket",
   2576 		"sysctl_modprobe",
   2577 		"sysctl",
   2578 		"sysctl_fs",
   2579 		"sysctl_kernel",
   2580 		"sysctl_net",
   2581 		"sysctl_net_unix",
   2582 		"sysctl_vm",
   2583 		"sysctl_dev",
   2584 		"kmod",
   2585 		"policy",
   2586 		"scmp_packet",
   2587 		"devnull",
   2588 		NULL
   2589 	};
   2590 
   2591 	rc = ocontext_isid_to_cil(pdb, selinux_sid_to_string, isids);
   2592 	if (rc != 0) {
   2593 		goto exit;
   2594 	}
   2595 
   2596 	return 0;
   2597 
   2598 exit:
   2599 	return rc;
   2600 }
   2601 
   2602 static int ocontext_selinux_fs_to_cil(struct policydb *UNUSED(pdb), struct ocontext *fss)
   2603 {
   2604 	if (fss != NULL) {
   2605 		log_err("Warning: 'fscon' statement unsupported in CIL. Dropping from output.");
   2606 	}
   2607 
   2608 	return 0;
   2609 }
   2610 
   2611 static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *portcons)
   2612 {
   2613 	int rc = -1;
   2614 	struct ocontext *portcon;
   2615 	const char *protocol;
   2616 	uint16_t high;
   2617 	uint16_t low;
   2618 
   2619 	for (portcon = portcons; portcon != NULL; portcon = portcon->next) {
   2620 
   2621 		switch (portcon->u.port.protocol) {
   2622 		case IPPROTO_TCP: protocol = "tcp"; break;
   2623 		case IPPROTO_UDP: protocol = "udp"; break;
   2624 		case IPPROTO_DCCP: protocol = "dccp"; break;
   2625 		default:
   2626 			log_err("Unknown portcon protocol: %i", portcon->u.port.protocol);
   2627 			rc = -1;
   2628 			goto exit;
   2629 		}
   2630 
   2631 		low = portcon->u.port.low_port;
   2632 		high = portcon->u.port.high_port;
   2633 
   2634 		if (low == high) {
   2635 			cil_printf("(portcon %s %i ", protocol, low);
   2636 		} else {
   2637 			cil_printf("(portcon %s (%i %i) ", protocol, low, high);
   2638 		}
   2639 
   2640 		context_to_cil(pdb, &portcon->context[0]);
   2641 
   2642 		cil_printf(")\n");
   2643 	}
   2644 
   2645 	return 0;
   2646 exit:
   2647 	return rc;
   2648 }
   2649 
   2650 static int ocontext_selinux_netif_to_cil(struct policydb *pdb, struct ocontext *netifs)
   2651 {
   2652 	struct ocontext *netif;
   2653 
   2654 	for (netif = netifs; netif != NULL; netif = netif->next) {
   2655 		cil_printf("(netifcon %s ", netif->u.name);
   2656 		context_to_cil(pdb, &netif->context[0]);
   2657 
   2658 		cil_printf(" ");
   2659 		context_to_cil(pdb, &netif->context[1]);
   2660 		cil_printf(")\n");
   2661 	}
   2662 
   2663 	return 0;
   2664 }
   2665 
   2666 static int ocontext_selinux_node_to_cil(struct policydb *pdb, struct ocontext *nodes)
   2667 {
   2668 	int rc = -1;
   2669 	struct ocontext *node;
   2670 	char addr[INET_ADDRSTRLEN];
   2671 	char mask[INET_ADDRSTRLEN];
   2672 
   2673 	for (node = nodes; node != NULL; node = node->next) {
   2674 		if (inet_ntop(AF_INET, &node->u.node.addr, addr, INET_ADDRSTRLEN) == NULL) {
   2675 			log_err("Nodecon address is invalid: %s", strerror(errno));
   2676 			rc = -1;
   2677 			goto exit;
   2678 		}
   2679 
   2680 		if (inet_ntop(AF_INET, &node->u.node.mask, mask, INET_ADDRSTRLEN) == NULL) {
   2681 			log_err("Nodecon mask is invalid: %s", strerror(errno));
   2682 			rc = -1;
   2683 			goto exit;
   2684 		}
   2685 
   2686 		cil_printf("(nodecon (%s) (%s) ", addr, mask);
   2687 
   2688 		context_to_cil(pdb, &node->context[0]);
   2689 
   2690 		cil_printf(")\n");
   2691 	}
   2692 
   2693 	return 0;
   2694 exit:
   2695 	return rc;
   2696 }
   2697 
   2698 static int ocontext_selinux_node6_to_cil(struct policydb *pdb, struct ocontext *nodes)
   2699 {
   2700 	int rc = -1;
   2701 	struct ocontext *node;
   2702 	char addr[INET6_ADDRSTRLEN];
   2703 	char mask[INET6_ADDRSTRLEN];
   2704 
   2705 	for (node = nodes; node != NULL; node = node->next) {
   2706 		if (inet_ntop(AF_INET6, &node->u.node6.addr, addr, INET6_ADDRSTRLEN) == NULL) {
   2707 			log_err("Nodecon address is invalid: %s", strerror(errno));
   2708 			rc = -1;
   2709 			goto exit;
   2710 		}
   2711 
   2712 		if (inet_ntop(AF_INET6, &node->u.node6.mask, mask, INET6_ADDRSTRLEN) == NULL) {
   2713 			log_err("Nodecon mask is invalid: %s", strerror(errno));
   2714 			rc = -1;
   2715 			goto exit;
   2716 		}
   2717 
   2718 		cil_printf("(nodecon (%s) (%s) ", addr, mask);
   2719 
   2720 		context_to_cil(pdb, &node->context[0]);
   2721 
   2722 		cil_printf(")\n");
   2723 	}
   2724 
   2725 	return 0;
   2726 exit:
   2727 	return rc;
   2728 }
   2729 
   2730 
   2731 static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses)
   2732 {
   2733 	int rc = -1;
   2734 	struct ocontext *fsuse;
   2735 	const char *behavior;
   2736 
   2737 
   2738 	for (fsuse = fsuses; fsuse != NULL; fsuse = fsuse->next) {
   2739 		switch (fsuse->v.behavior) {
   2740 		case SECURITY_FS_USE_XATTR: behavior = "xattr"; break;
   2741 		case SECURITY_FS_USE_TRANS: behavior = "trans"; break;
   2742 		case SECURITY_FS_USE_TASK:  behavior = "task"; break;
   2743 		default:
   2744 			log_err("Unknown fsuse behavior: %i", fsuse->v.behavior);
   2745 			rc = -1;
   2746 			goto exit;
   2747 		}
   2748 
   2749 		cil_printf("(fsuse %s %s ", behavior, fsuse->u.name);
   2750 
   2751 		context_to_cil(pdb, &fsuse->context[0]);
   2752 
   2753 		cil_printf(")\n");
   2754 
   2755 	}
   2756 
   2757 	return 0;
   2758 exit:
   2759 	return rc;
   2760 }
   2761 
   2762 
   2763 static int ocontext_xen_isid_to_cil(struct policydb *pdb, struct ocontext *isids)
   2764 {
   2765 	int rc = -1;
   2766 
   2767 	// initial sid names aren't actually stored in the pp files, need to a have
   2768 	// a mapping, taken from the xen kernel
   2769 	static const char *xen_sid_to_string[] = {
   2770 		"null",
   2771 		"xen",
   2772 		"dom0",
   2773 		"domio",
   2774 		"domxen",
   2775 		"unlabeled",
   2776 		"security",
   2777 		"ioport",
   2778 		"iomem",
   2779 		"irq",
   2780 		"device",
   2781 		NULL,
   2782 	};
   2783 
   2784 	rc = ocontext_isid_to_cil(pdb, xen_sid_to_string, isids);
   2785 	if (rc != 0) {
   2786 		goto exit;
   2787 	}
   2788 
   2789 	return 0;
   2790 
   2791 exit:
   2792 	return rc;
   2793 }
   2794 
   2795 static int ocontext_xen_pirq_to_cil(struct policydb *pdb, struct ocontext *pirqs)
   2796 {
   2797 	struct ocontext *pirq;
   2798 
   2799 	for (pirq = pirqs; pirq != NULL; pirq = pirq->next) {
   2800 		cil_printf("(pirqcon %i ", pirq->u.pirq);
   2801 		context_to_cil(pdb, &pirq->context[0]);
   2802 		cil_printf(")\n");
   2803 	}
   2804 
   2805 	return 0;
   2806 }
   2807 
   2808 static int ocontext_xen_ioport_to_cil(struct policydb *pdb, struct ocontext *ioports)
   2809 {
   2810 	struct ocontext *ioport;
   2811 	uint32_t low;
   2812 	uint32_t high;
   2813 
   2814 	for (ioport = ioports; ioport != NULL; ioport = ioport->next) {
   2815 		low = ioport->u.ioport.low_ioport;
   2816 		high = ioport->u.ioport.high_ioport;
   2817 
   2818 		if (low == high) {
   2819 			cil_printf("(ioportcon %i ", low);
   2820 		} else {
   2821 			cil_printf("(ioportcon (%i %i) ", low, high);
   2822 		}
   2823 
   2824 		context_to_cil(pdb, &ioport->context[0]);
   2825 
   2826 		cil_printf(")\n");
   2827 	}
   2828 
   2829 	return 0;
   2830 }
   2831 
   2832 static int ocontext_xen_iomem_to_cil(struct policydb *pdb, struct ocontext *iomems)
   2833 {
   2834 	struct ocontext *iomem;
   2835 	uint64_t low;
   2836 	uint64_t high;
   2837 
   2838 	for (iomem = iomems; iomem != NULL; iomem = iomem->next) {
   2839 		low = iomem->u.iomem.low_iomem;
   2840 		high = iomem->u.iomem.high_iomem;
   2841 
   2842 		if (low == high) {
   2843 			cil_printf("(iomemcon %#lX ", (unsigned long)low);
   2844 		} else {
   2845 			cil_printf("(iomemcon (%#lX %#lX) ", (unsigned long)low, (unsigned long)high);
   2846 		}
   2847 
   2848 		context_to_cil(pdb, &iomem->context[0]);
   2849 
   2850 		cil_printf(")\n");
   2851 	}
   2852 
   2853 	return 0;
   2854 }
   2855 
   2856 static int ocontext_xen_pcidevice_to_cil(struct policydb *pdb, struct ocontext *pcids)
   2857 {
   2858 	struct ocontext *pcid;
   2859 
   2860 	for (pcid = pcids; pcid != NULL; pcid = pcid->next) {
   2861 		cil_printf("(pcidevicecon %#lx ", (unsigned long)pcid->u.device);
   2862 		context_to_cil(pdb, &pcid->context[0]);
   2863 		cil_printf(")\n");
   2864 	}
   2865 
   2866 	return 0;
   2867 }
   2868 
   2869 static int ocontexts_to_cil(struct policydb *pdb)
   2870 {
   2871 	int rc = -1;
   2872 	int ocon;
   2873 
   2874 	static int (**ocon_funcs)(struct policydb *pdb, struct ocontext *ocon);
   2875 	static int (*ocon_selinux_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
   2876 		ocontext_selinux_isid_to_cil,
   2877 		ocontext_selinux_fs_to_cil,
   2878 		ocontext_selinux_port_to_cil,
   2879 		ocontext_selinux_netif_to_cil,
   2880 		ocontext_selinux_node_to_cil,
   2881 		ocontext_selinux_fsuse_to_cil,
   2882 		ocontext_selinux_node6_to_cil,
   2883 	};
   2884 	static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = {
   2885 		ocontext_xen_isid_to_cil,
   2886 		ocontext_xen_pirq_to_cil,
   2887 		ocontext_xen_ioport_to_cil,
   2888 		ocontext_xen_iomem_to_cil,
   2889 		ocontext_xen_pcidevice_to_cil,
   2890 		NULL,
   2891 		NULL,
   2892 	};
   2893 
   2894 	switch (pdb->target_platform) {
   2895 	case SEPOL_TARGET_SELINUX:
   2896 		ocon_funcs = ocon_selinux_funcs;
   2897 		break;
   2898 	case SEPOL_TARGET_XEN:
   2899 		ocon_funcs = ocon_xen_funcs;
   2900 		break;
   2901 	default:
   2902 		log_err("Unknown target platform: %i", pdb->target_platform);
   2903 		rc = -1;
   2904 		goto exit;
   2905 	}
   2906 
   2907 	for (ocon = 0; ocon < OCON_NUM; ocon++) {
   2908 		if (ocon_funcs[ocon] != NULL) {
   2909 			rc = ocon_funcs[ocon](pdb, pdb->ocontexts[ocon]);
   2910 			if (rc != 0) {
   2911 				goto exit;
   2912 			}
   2913 		}
   2914 	}
   2915 
   2916 	return 0;
   2917 exit:
   2918 	return rc;
   2919 }
   2920 
   2921 static int genfscon_to_cil(struct policydb *pdb)
   2922 {
   2923 	struct genfs *genfs;
   2924 	struct ocontext *ocon;
   2925 
   2926 	for (genfs = pdb->genfs; genfs != NULL; genfs = genfs->next) {
   2927 		for (ocon = genfs->head; ocon != NULL; ocon = ocon->next) {
   2928 			cil_printf("(genfscon %s %s ", genfs->fstype, ocon->u.name);
   2929 			context_to_cil(pdb, &ocon->context[0]);
   2930 			cil_printf(")\n");
   2931 		}
   2932 	}
   2933 
   2934 	return 0;
   2935 }
   2936 
   2937 static int level_string_to_cil(char *levelstr)
   2938 {
   2939 	int rc = -1;
   2940 	char *sens = NULL;
   2941 	char *cats = NULL;
   2942 	int matched;
   2943 	char *saveptr = NULL;
   2944 	char *token = NULL;
   2945 	char *ranged = NULL;
   2946 
   2947 	matched = tokenize(levelstr, ':', 2, &sens, &cats);
   2948 	if (matched < 1 || matched > 2) {
   2949 		log_err("Invalid level: %s", levelstr);
   2950 		rc = -1;
   2951 		goto exit;
   2952 	}
   2953 
   2954 	cil_printf("(%s", sens);
   2955 
   2956 	if (matched == 2) {
   2957 		cil_printf("(");
   2958 		token = strtok_r(cats, ",", &saveptr);
   2959 		while (token != NULL) {
   2960 			ranged = strchr(token, '.');
   2961 			if (ranged == NULL) {
   2962 				cil_printf("%s ", token);
   2963 			} else {
   2964 				*ranged = '\0';
   2965 				cil_printf("(range %s %s) ", token, ranged + 1);
   2966 			}
   2967 			token = strtok_r(NULL, ",", &saveptr);
   2968 		}
   2969 		cil_printf(")");
   2970 	}
   2971 
   2972 	cil_printf(")");
   2973 
   2974 	rc = 0;
   2975 exit:
   2976 	free(sens);
   2977 	free(cats);
   2978 	return rc;
   2979 }
   2980 
   2981 static int level_range_string_to_cil(char *levelrangestr)
   2982 {
   2983 	char *ranged = NULL;
   2984 	char *low;
   2985 	char *high;
   2986 
   2987 	ranged = strchr(levelrangestr, '-');
   2988 	if (ranged == NULL) {
   2989 		low = high = levelrangestr;
   2990 	} else {
   2991 		*ranged = '\0';
   2992 		low = levelrangestr;
   2993 		high = ranged + 1;
   2994 	}
   2995 
   2996 	level_string_to_cil(low);
   2997 	cil_printf(" ");
   2998 	level_string_to_cil(high);
   2999 
   3000 	return 0;
   3001 }
   3002 
   3003 static int context_string_to_cil(char *contextstr)
   3004 {
   3005 	int rc = -1;
   3006 	int matched;
   3007 	char *user = NULL;
   3008 	char *role = NULL;
   3009 	char *type = NULL;
   3010 	char *level = NULL;
   3011 
   3012 	matched = tokenize(contextstr, ':', 4, &user, &role, &type, &level);
   3013 	if (matched < 3 || matched > 4) {
   3014 		log_err("Invalid context: %s", contextstr);
   3015 		rc = -1;
   3016 		goto exit;
   3017 	}
   3018 
   3019 	cil_printf("(%s %s %s (", user, role, type);
   3020 
   3021 	if (matched == 3) {
   3022 		cil_printf(DEFAULT_LEVEL);
   3023 		cil_printf(" ");
   3024 		cil_printf(DEFAULT_LEVEL);
   3025 	} else {
   3026 		level_range_string_to_cil(level);
   3027 	}
   3028 
   3029 	cil_printf("))");
   3030 
   3031 	rc = 0;
   3032 
   3033 exit:
   3034 	free(user);
   3035 	free(role);
   3036 	free(type);
   3037 	free(level);
   3038 
   3039 	return rc;
   3040 }
   3041 
   3042 static int seusers_to_cil(struct sepol_module_package *mod_pkg)
   3043 {
   3044 	int rc = -1;
   3045 	char *seusers = sepol_module_package_get_seusers(mod_pkg);
   3046 	size_t seusers_len = sepol_module_package_get_seusers_len(mod_pkg);
   3047 	char *cur = seusers;
   3048 	char *end = seusers + seusers_len;
   3049 	char *line = NULL;
   3050 	char *user = NULL;
   3051 	char *seuser = NULL;
   3052 	char *level = NULL;
   3053 	char *tmp = NULL;
   3054 	int matched;
   3055 
   3056 	if (seusers_len == 0) {
   3057 		return 0;
   3058 	}
   3059 
   3060 	while ((rc = get_line(&cur, end, &line)) > 0) {
   3061 		tmp = line;
   3062 		while (isspace(*tmp)) {
   3063 			tmp++;
   3064 		}
   3065 
   3066 		if (tmp[0] == '#' || tmp[0] == '\0') {
   3067 			free(line);
   3068 			line = NULL;
   3069 			continue;
   3070 		}
   3071 
   3072 		matched = tokenize(tmp, ':', 3, &user, &seuser, &level);
   3073 
   3074 		if (matched < 2 || matched > 3) {
   3075 			log_err("Invalid seuser line: %s", line);
   3076 			rc = -1;
   3077 			goto exit;
   3078 		}
   3079 
   3080 		if (!strcmp(user, "__default__")) {
   3081 			cil_printf("(selinuxuserdefault %s (", seuser);
   3082 		} else {
   3083 			cil_printf("(selinuxuser %s %s (", user, seuser);
   3084 		}
   3085 
   3086 		switch (matched) {
   3087 		case 2:
   3088 			cil_printf("systemlow systemlow");
   3089 			break;
   3090 		case 3:
   3091 			level_range_string_to_cil(level);
   3092 			break;
   3093 		}
   3094 
   3095 		cil_printf("))\n");
   3096 
   3097 		free(user);
   3098 		free(seuser);
   3099 		free(level);
   3100 		free(line);
   3101 		user = seuser = level = NULL;
   3102 	}
   3103 
   3104 	if (rc == -1) {
   3105 		cil_printf("Failed to read seusers\n");
   3106 		goto exit;
   3107 	}
   3108 
   3109 	rc = 0;
   3110 exit:
   3111 	free(line);
   3112 	free(user);
   3113 	free(seuser);
   3114 	free(level);
   3115 
   3116 	return rc;
   3117 }
   3118 
   3119 static int netfilter_contexts_to_cil(struct sepol_module_package *mod_pkg)
   3120 {
   3121 	size_t netcons_len = sepol_module_package_get_netfilter_contexts_len(mod_pkg);
   3122 
   3123 	if (netcons_len > 0) {
   3124 		log_err("Warning: netfilter_contexts are unsupported in CIL. Dropping from output.");
   3125 	}
   3126 
   3127 	return 0;
   3128 }
   3129 
   3130 static int user_extra_to_cil(struct sepol_module_package *mod_pkg)
   3131 {
   3132 	int rc = -1;
   3133 	char *userx = sepol_module_package_get_user_extra(mod_pkg);
   3134 	size_t userx_len = sepol_module_package_get_user_extra_len(mod_pkg);
   3135 	char *cur = userx;
   3136 	char *end = userx + userx_len;
   3137 	char *line;
   3138 	int matched;
   3139 	char *user = NULL;
   3140 	char *prefix = NULL;
   3141 	int prefix_len = 0;
   3142 	char *user_str = NULL;
   3143 	char *prefix_str = NULL;
   3144 	char *eol = NULL;
   3145 	char *tmp = NULL;
   3146 
   3147 	if (userx_len == 0) {
   3148 		return 0;
   3149 	}
   3150 
   3151 	while ((rc = get_line(&cur, end, &line)) > 0) {
   3152 		tmp = line;
   3153 		while (isspace(*tmp)) {
   3154 			tmp++;
   3155 		}
   3156 
   3157 		if (tmp[0] == '#' || tmp[0] == '\0') {
   3158 			free(line);
   3159 			line = NULL;
   3160 			continue;
   3161 		}
   3162 
   3163 		matched = tokenize(tmp, ' ', 4, &user_str, &user, &prefix_str, &prefix);
   3164 		if (matched != 4) {
   3165 			rc = -1;
   3166 			log_err("Invalid user extra line: %s", line);
   3167 			goto exit;
   3168 		}
   3169 
   3170 		prefix_len = strlen(prefix);
   3171 		eol = prefix + prefix_len - 1;
   3172 		if (*eol != ';' || strcmp(user_str, "user") || strcmp(prefix_str, "prefix")) {
   3173 			rc = -1;
   3174 			log_err("Invalid user extra line: %s", line);
   3175 			goto exit;
   3176 		}
   3177 		*eol = '\0';
   3178 
   3179 		cil_println(0, "(userprefix %s %s)", user, prefix);
   3180 		free(user);
   3181 		free(prefix);
   3182 		free(line);
   3183 		free(user_str);
   3184 		free(prefix_str);
   3185 		user = prefix = line = user_str = prefix_str = NULL;
   3186 	}
   3187 
   3188 	if (rc == -1) {
   3189 		cil_printf("Failed to read user_extra\n");
   3190 		goto exit;
   3191 	}
   3192 
   3193 	rc = 0;
   3194 exit:
   3195 	free(line);
   3196 	free(user);
   3197 	free(prefix);
   3198 
   3199 	return rc;
   3200 }
   3201 
   3202 static int file_contexts_to_cil(struct sepol_module_package *mod_pkg)
   3203 {
   3204 	int rc = -1;
   3205 	char *fc = sepol_module_package_get_file_contexts(mod_pkg);
   3206 	size_t fc_len = sepol_module_package_get_file_contexts_len(mod_pkg);
   3207 	char *cur = fc;
   3208 	char *end = fc + fc_len;
   3209 	char *line = NULL;
   3210 	int matched;
   3211 	char *regex = NULL;
   3212 	char *mode = NULL;
   3213 	char *context = NULL;
   3214 	const char *cilmode;
   3215 	char *tmp = NULL;
   3216 
   3217 	if (fc_len == 0) {
   3218 		return 0;
   3219 	}
   3220 
   3221 	while ((rc = get_line(&cur, end, &line)) > 0) {
   3222 		tmp = line;
   3223 		while (isspace(*tmp)) {
   3224 			tmp++;
   3225 		}
   3226 
   3227 		if (tmp[0] == '#' || tmp[0] == '\0') {
   3228 			free(line);
   3229 			line = NULL;
   3230 			continue;
   3231 		}
   3232 
   3233 		matched = tokenize(tmp, ' ', 3, &regex, &mode, &context);
   3234 		if (matched < 2 || matched > 3) {
   3235 			rc = -1;
   3236 			log_err("Invalid file context line: %s", line);
   3237 			goto exit;
   3238 		}
   3239 
   3240 		if (matched == 2) {
   3241 			context = mode;
   3242 			mode = NULL;
   3243 		}
   3244 
   3245 		if (mode == NULL) {
   3246 			cilmode = "any";
   3247 		} else if (!strcmp(mode, "--")) {
   3248 			cilmode = "file";
   3249 		} else if (!strcmp(mode, "-d")) {
   3250 			cilmode = "dir";
   3251 		} else if (!strcmp(mode, "-c")) {
   3252 			cilmode = "char";
   3253 		} else if (!strcmp(mode, "-b")) {
   3254 			cilmode = "block";
   3255 		} else if (!strcmp(mode, "-s")) {
   3256 			cilmode = "socket";
   3257 		} else if (!strcmp(mode, "-p")) {
   3258 			cilmode = "pipe";
   3259 		} else if (!strcmp(mode, "-l")) {
   3260 			cilmode = "symlink";
   3261 		} else {
   3262 			rc = -1;
   3263 			log_err("Invalid mode in file context line: %s", line);
   3264 			goto exit;
   3265 		}
   3266 
   3267 		cil_printf("(filecon \"%s\" %s ", regex, cilmode);
   3268 
   3269 		if (!strcmp(context, "<<none>>")) {
   3270 			cil_printf("()");
   3271 		} else {
   3272 			context_string_to_cil(context);
   3273 		}
   3274 
   3275 		cil_printf(")\n");
   3276 
   3277 		free(regex);
   3278 		free(mode);
   3279 		free(context);
   3280 		free(line);
   3281 		regex = mode = context = line = NULL;
   3282 	}
   3283 
   3284 	if (rc == -1) {
   3285 		cil_printf("Failed to read file_contexts_to_cil\n");
   3286 		goto exit;
   3287 	}
   3288 
   3289 	rc = 0;
   3290 exit:
   3291 	free(line);
   3292 	free(regex);
   3293 	free(mode);
   3294 	free(context);
   3295 
   3296 	return rc;
   3297 }
   3298 
   3299 
   3300 static int (*func_to_cil[SYM_NUM])(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack, char *key, void *datum, int scope) = {
   3301 	NULL,	// commons, only stored in the global symtab, handled elsewhere
   3302 	class_to_cil,
   3303 	role_to_cil,
   3304 	type_to_cil,
   3305 	user_to_cil,
   3306 	boolean_to_cil,
   3307 	sens_to_cil,
   3308 	cat_to_cil
   3309 };
   3310 
   3311 static int typealiases_to_cil(int indent, struct policydb *pdb, struct avrule_block *UNUSED(block), struct stack *decl_stack)
   3312 {
   3313 	struct type_datum *alias_datum;
   3314 	char *alias_name;
   3315 	struct list_node *curr;
   3316 	struct avrule_decl *decl = stack_peek(decl_stack);
   3317 	struct list *alias_list = typealias_lists[decl->decl_id];
   3318 	int rc = -1;
   3319 
   3320 	if (alias_list == NULL) {
   3321 		return 0;
   3322 	}
   3323 
   3324 	for (curr = alias_list->head; curr != NULL; curr = curr->next) {
   3325 		alias_name = curr->data;
   3326 		alias_datum = hashtab_search(pdb->p_types.table, alias_name);
   3327 		if (alias_datum == NULL) {
   3328 			rc = -1;
   3329 			goto exit;
   3330 		}
   3331 
   3332 		cil_println(indent, "(typealias %s)", alias_name);
   3333 		cil_println(indent, "(typealiasactual %s %s)", alias_name, pdb->p_type_val_to_name[alias_datum->s.value - 1]);
   3334 	}
   3335 
   3336 	return 0;
   3337 
   3338 exit:
   3339 	return rc;
   3340 }
   3341 
   3342 static int declared_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
   3343 {
   3344 	int rc = -1;
   3345 	struct ebitmap map;
   3346 	struct ebitmap_node *node;
   3347 	unsigned int i;
   3348 	char * key;
   3349 	struct scope_datum *scope;
   3350 	int sym;
   3351 	void *datum;
   3352 	struct avrule_decl *decl = stack_peek(decl_stack);
   3353 
   3354 	for (sym = 0; sym < SYM_NUM; sym++) {
   3355 		if (func_to_cil[sym] == NULL) {
   3356 			continue;
   3357 		}
   3358 
   3359 		map = decl->declared.scope[sym];
   3360 		ebitmap_for_each_bit(&map, node, i) {
   3361 			if (!ebitmap_get_bit(&map, i)) {
   3362 				continue;
   3363 			}
   3364 			key = pdb->sym_val_to_name[sym][i];
   3365 			datum = hashtab_search(pdb->symtab[sym].table, key);
   3366 			if (datum == NULL) {
   3367 				rc = -1;
   3368 				goto exit;
   3369 			}
   3370 			scope = hashtab_search(pdb->scope[sym].table, key);
   3371 			if (scope == NULL) {
   3372 				rc = -1;
   3373 				goto exit;
   3374 			}
   3375 			rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, scope->scope);
   3376 			if (rc != 0) {
   3377 				goto exit;
   3378 			}
   3379 		}
   3380 
   3381 		if (sym == SYM_CATS) {
   3382 			rc = cat_order_to_cil(indent, pdb, map);
   3383 			if (rc != 0) {
   3384 				goto exit;
   3385 			}
   3386 		}
   3387 
   3388 		if (sym == SYM_LEVELS) {
   3389 			rc = sens_order_to_cil(indent, pdb, map);
   3390 			if (rc != 0) {
   3391 				goto exit;
   3392 			}
   3393 		}
   3394 
   3395 		if (sym == SYM_CLASSES) {
   3396 			rc = class_order_to_cil(indent, pdb, map);
   3397 			if (rc != 0) {
   3398 				goto exit;
   3399 			}
   3400 		}
   3401 	}
   3402 
   3403 	return 0;
   3404 exit:
   3405 	return rc;
   3406 }
   3407 
   3408 static int required_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
   3409 {
   3410 	int rc = -1;
   3411 	struct ebitmap map;
   3412 	struct ebitmap_node *node;
   3413 	unsigned int i;
   3414 	unsigned int j;
   3415 	char * key;
   3416 	int sym;
   3417 	void *datum;
   3418 	struct avrule_decl *decl = stack_peek(decl_stack);
   3419 	struct scope_datum *scope_datum;
   3420 
   3421 	for (sym = 0; sym < SYM_NUM; sym++) {
   3422 		if (func_to_cil[sym] == NULL) {
   3423 			continue;
   3424 		}
   3425 
   3426 		map = decl->required.scope[sym];
   3427 		ebitmap_for_each_bit(&map, node, i) {
   3428 			if (!ebitmap_get_bit(&map, i)) {
   3429 				continue;
   3430 			}
   3431 			key = pdb->sym_val_to_name[sym][i];
   3432 
   3433 			scope_datum = hashtab_search(pdb->scope[sym].table, key);
   3434 			if (scope_datum == NULL) {
   3435 				rc = -1;
   3436 				goto exit;
   3437 			}
   3438 			for (j = 0; j < scope_datum->decl_ids_len; j++) {
   3439 				if (scope_datum->decl_ids[j] == decl->decl_id) {
   3440 					break;
   3441 				}
   3442 			}
   3443 			if (j >= scope_datum->decl_ids_len) {
   3444 				// Symbols required in the global scope are also in the
   3445 				// required scope ebitmap of all avrule decls (i.e. required
   3446 				// in all optionals). So we need to look at the scopes of each
   3447 				// symbol in this avrule_decl to determine if it actually is
   3448 				// required in this decl, or if it's just required in the
   3449 				// global scope. If we got here, then this symbol is not
   3450 				// actually required in this scope, so skip it.
   3451 				continue;
   3452 			}
   3453 
   3454 			datum = hashtab_search(pdb->symtab[sym].table, key);
   3455 			if (datum == NULL) {
   3456 				rc = -1;
   3457 				goto exit;
   3458 			}
   3459 			rc = func_to_cil[sym](indent, pdb, block, decl_stack, key, datum, SCOPE_REQ);
   3460 			if (rc != 0) {
   3461 				goto exit;
   3462 			}
   3463 		}
   3464 	}
   3465 
   3466 	return 0;
   3467 exit:
   3468 	return rc;
   3469 }
   3470 
   3471 
   3472 static int additive_scopes_to_cil_map(char *key, void *data, void *arg)
   3473 {
   3474 	int rc = -1;
   3475 	struct map_args *args = arg;
   3476 
   3477 	rc = func_to_cil[args->sym_index](args->indent, args->pdb, args->block, args->decl_stack, key, data, SCOPE_REQ);
   3478 	if (rc != 0) {
   3479 		goto exit;
   3480 	}
   3481 
   3482 	return 0;
   3483 
   3484 exit:
   3485 	return rc;
   3486 }
   3487 
   3488 static int additive_scopes_to_cil(int indent, struct policydb *pdb, struct avrule_block *block, struct stack *decl_stack)
   3489 {
   3490 	int rc = -1;
   3491 	struct map_args args;
   3492 	args.pdb = pdb;
   3493 	args.block = block;
   3494 	args.decl_stack = decl_stack;
   3495 	args.indent = indent;
   3496 	struct avrule_decl *decl = stack_peek(decl_stack);
   3497 
   3498 	for (args.sym_index = 0; args.sym_index < SYM_NUM; args.sym_index++) {
   3499 		if (func_to_cil[args.sym_index] == NULL) {
   3500 			continue;
   3501 		}
   3502 		rc = hashtab_map(decl->symtab[args.sym_index].table, additive_scopes_to_cil_map, &args);
   3503 		if (rc != 0) {
   3504 			goto exit;
   3505 		}
   3506 	}
   3507 
   3508 	return 0;
   3509 
   3510 exit:
   3511 	return rc;
   3512 }
   3513 
   3514 static int is_scope_superset(struct scope_index *sup, struct scope_index *sub)
   3515 {
   3516 	// returns 1 if sup is a superset of sub, returns 0 otherwise
   3517 
   3518 	int rc = 0;
   3519 
   3520 	uint32_t i;
   3521 	struct ebitmap sup_map;
   3522 	struct ebitmap sub_map;
   3523 	struct ebitmap res;
   3524 
   3525 	ebitmap_init(&res);
   3526 
   3527 	for (i = 0; i < SYM_NUM; i++) {
   3528 		sup_map = sup->scope[i];
   3529 		sub_map = sub->scope[i];
   3530 
   3531 		ebitmap_and(&res, &sup_map, &sub_map);
   3532 		if (!ebitmap_cmp(&res, &sub_map)) {
   3533 			goto exit;
   3534 		}
   3535 		ebitmap_destroy(&res);
   3536 	}
   3537 
   3538 	if (sup->class_perms_len < sub->class_perms_len) {
   3539 		goto exit;
   3540 	}
   3541 
   3542 	for (i = 0; i < sub->class_perms_len; i++) {
   3543 		sup_map = sup->class_perms_map[i];
   3544 		sub_map = sub->class_perms_map[i];
   3545 
   3546 		ebitmap_and(&res, &sup_map, &sub_map);
   3547 		if (!ebitmap_cmp(&res, &sub_map)) {
   3548 			goto exit;
   3549 		}
   3550 		ebitmap_destroy(&res);
   3551 	}
   3552 
   3553 	rc = 1;
   3554 
   3555 exit:
   3556 
   3557 	ebitmap_destroy(&res);
   3558 	return rc;
   3559 }
   3560 
   3561 static int block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int indent)
   3562 {
   3563 	int rc = -1;
   3564 	struct avrule_decl *decl;
   3565 	struct list *type_attr_list = NULL;
   3566 	struct list *role_attr_list = NULL;
   3567 
   3568 	decl = block->branch_list;
   3569 
   3570 	rc = list_init(&type_attr_list);
   3571 	if (rc != 0) {
   3572 		goto exit;
   3573 	}
   3574 	rc = list_init(&role_attr_list);
   3575 	if (rc != 0) {
   3576 		goto exit;
   3577 	}
   3578 
   3579 	rc = typealiases_to_cil(indent, pdb, block, stack);
   3580 	if (rc != 0) {
   3581 		goto exit;
   3582 	}
   3583 
   3584 	rc = declared_scopes_to_cil(indent, pdb, block, stack);
   3585 	if (rc != 0) {
   3586 		goto exit;
   3587 	}
   3588 
   3589 	rc = required_scopes_to_cil(indent, pdb, block, stack);
   3590 	if (rc != 0) {
   3591 		goto exit;
   3592 	}
   3593 
   3594 	rc = additive_scopes_to_cil(indent, pdb, block, stack);
   3595 	if (rc != 0) {
   3596 		goto exit;
   3597 	}
   3598 
   3599 	rc = avrule_list_to_cil(indent, pdb, decl->avrules, type_attr_list);
   3600 	if (rc != 0) {
   3601 		goto exit;
   3602 	}
   3603 
   3604 	rc = role_trans_to_cil(indent, pdb, decl->role_tr_rules, role_attr_list, type_attr_list);
   3605 	if (rc != 0) {
   3606 		goto exit;
   3607 	}
   3608 
   3609 	rc = role_allows_to_cil(indent, pdb, decl->role_allow_rules, role_attr_list);
   3610 	if (rc != 0) {
   3611 		goto exit;
   3612 	}
   3613 
   3614 	rc = range_trans_to_cil(indent, pdb, decl->range_tr_rules, type_attr_list);
   3615 	if (rc != 0) {
   3616 		goto exit;
   3617 	}
   3618 
   3619 	rc = filename_trans_to_cil(indent, pdb, decl->filename_trans_rules, type_attr_list);
   3620 	if (rc != 0) {
   3621 		goto exit;
   3622 	}
   3623 
   3624 	rc = cond_list_to_cil(indent, pdb, decl->cond_list, type_attr_list);
   3625 	if (rc != 0) {
   3626 		goto exit;
   3627 	}
   3628 
   3629 	rc = cil_print_attr_list(indent, pdb, type_attr_list);
   3630 	if (rc != 0) {
   3631 		goto exit;
   3632 	}
   3633 	rc = cil_print_attr_list(indent, pdb, role_attr_list);
   3634 	if (rc != 0) {
   3635 		goto exit;
   3636 	}
   3637 
   3638 exit:
   3639 	attr_list_destroy(&type_attr_list);
   3640 	attr_list_destroy(&role_attr_list);
   3641 
   3642 	return rc;
   3643 }
   3644 
   3645 static int module_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack, int *indent)
   3646 {
   3647 	int rc = 0;
   3648 	struct avrule_decl *decl;
   3649 	struct avrule_decl *decl_tmp;
   3650 
   3651 	decl = block->branch_list;
   3652 	if (decl == NULL) {
   3653 		goto exit;
   3654 	}
   3655 
   3656 	if (decl->next != NULL) {
   3657 		log_err("Warning: 'else' blocks in optional statements are unsupported in CIL. Dropping from output.");
   3658 	}
   3659 
   3660 	if (block->flags & AVRULE_OPTIONAL) {
   3661 		while (stack->pos > 0) {
   3662 			decl_tmp = stack_peek(stack);
   3663 			if (is_scope_superset(&decl->required, &decl_tmp->required)) {
   3664 				break;
   3665 			}
   3666 
   3667 			stack_pop(stack);
   3668 			(*indent)--;
   3669 			cil_println(*indent, ")");
   3670 		}
   3671 
   3672 		cil_println(*indent, "(optional %s_optional_%i", pdb->name, decl->decl_id);
   3673 		(*indent)++;
   3674 	}
   3675 
   3676 	stack_push(stack, decl);
   3677 
   3678 	rc = block_to_cil(pdb, block, stack, *indent);
   3679 	if (rc != 0) {
   3680 		goto exit;
   3681 	}
   3682 
   3683 exit:
   3684 	return rc;
   3685 }
   3686 
   3687 static int global_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack)
   3688 {
   3689 	int rc = 0;
   3690 	struct avrule_decl *decl;
   3691 
   3692 	decl = block->branch_list;
   3693 	if (decl == NULL) {
   3694 		goto exit;
   3695 	}
   3696 
   3697 	if (decl->next != NULL) {
   3698 		log_err("Warning: 'else' not allowed in global block. Dropping from output.");
   3699 	}
   3700 
   3701 	stack_push(stack, decl);
   3702 
   3703 	// type aliases and commons are only stored in the global symtab.
   3704 	// However, to get scoping correct, we assume they are in the
   3705 	// global block
   3706 	rc = hashtab_map(pdb->p_commons.table, common_to_cil, NULL);
   3707 	if (rc != 0) {
   3708 		goto exit;
   3709 	}
   3710 
   3711 	rc = block_to_cil(pdb, block, stack, 0);
   3712 	if (rc != 0) {
   3713 		goto exit;
   3714 	}
   3715 
   3716 exit:
   3717 	return rc;
   3718 }
   3719 
   3720 static int blocks_to_cil(struct policydb *pdb)
   3721 {
   3722 	int rc = -1;
   3723 	struct avrule_block *block;
   3724 	int indent = 0;
   3725 	struct stack *stack = NULL;
   3726 
   3727 	rc = stack_init(&stack);
   3728 	if (rc != 0) {
   3729 		goto exit;
   3730 	}
   3731 
   3732 	block = pdb->global;
   3733 	rc = global_block_to_cil(pdb, block, stack);
   3734 	if (rc != 0) {
   3735 		goto exit;
   3736 	}
   3737 
   3738 	for (block = block->next; block != NULL; block = block->next) {
   3739 		rc = module_block_to_cil(pdb, block, stack, &indent);
   3740 		if (rc != 0) {
   3741 			goto exit;
   3742 		}
   3743 	}
   3744 
   3745 	while (indent > 0) {
   3746 		indent--;
   3747 		cil_println(indent, ")");
   3748 	}
   3749 
   3750 exit:
   3751 	stack_destroy(&stack);
   3752 
   3753 	return rc;
   3754 }
   3755 
   3756 static int linked_block_to_cil(struct policydb *pdb, struct avrule_block *block, struct stack *stack)
   3757 {
   3758 	int rc = 0;
   3759 	struct avrule_decl *decl;
   3760 
   3761 	decl = block->branch_list;
   3762 	if (decl == NULL) {
   3763 		goto exit;
   3764 	}
   3765 
   3766 	if (!decl->enabled) {
   3767 		if (decl->next != NULL) {
   3768 			decl = decl->next;
   3769 		} else {
   3770 			goto exit;
   3771 		}
   3772 	}
   3773 
   3774 	stack_push(stack, decl);
   3775 
   3776 	rc = block_to_cil(pdb, block, stack, 0);
   3777 	if (rc != 0) {
   3778 		goto exit;
   3779 	}
   3780 
   3781 	stack_pop(stack);
   3782 
   3783 exit:
   3784 	return rc;
   3785 }
   3786 
   3787 static int linked_blocks_to_cil(struct policydb *pdb)
   3788 {
   3789 	// Convert base module that has been linked to CIL
   3790 	// Since it is linked, all optional blocks have been resolved
   3791 	int rc = -1;
   3792 	struct avrule_block *block;
   3793 	struct stack *stack = NULL;
   3794 
   3795 	rc = stack_init(&stack);
   3796 	if (rc != 0) {
   3797 		goto exit;
   3798 	}
   3799 
   3800 	block = pdb->global;
   3801 	rc = global_block_to_cil(pdb, block, stack);
   3802 	if (rc != 0) {
   3803 		goto exit;
   3804 	}
   3805 
   3806 	for (block = block->next; block != NULL; block = block->next) {
   3807 		rc = linked_block_to_cil(pdb, block, stack);
   3808 		if (rc != 0) {
   3809 			goto exit;
   3810 		}
   3811 	}
   3812 
   3813 exit:
   3814 	stack_destroy(&stack);
   3815 
   3816 	return rc;
   3817 }
   3818 
   3819 static int handle_unknown_to_cil(struct policydb *pdb)
   3820 {
   3821 	int rc = -1;
   3822 	const char *hu;
   3823 
   3824 	switch (pdb->handle_unknown) {
   3825 	case SEPOL_DENY_UNKNOWN:
   3826 		hu = "deny";
   3827 		break;
   3828 	case SEPOL_REJECT_UNKNOWN:
   3829 		hu = "reject";
   3830 		break;
   3831 	case SEPOL_ALLOW_UNKNOWN:
   3832 		hu = "allow";
   3833 		break;
   3834 	default:
   3835 		log_err("Unknown value for handle-unknown: %i", pdb->handle_unknown);
   3836 		rc = -1;
   3837 		goto exit;
   3838 	}
   3839 
   3840 	cil_println(0, "(handleunknown %s)", hu);
   3841 
   3842 	return 0;
   3843 
   3844 exit:
   3845 	return rc;
   3846 }
   3847 
   3848 static int generate_mls(struct policydb *pdb)
   3849 {
   3850 	const char *mls_str = pdb->mls ? "true" : "false";
   3851 	cil_println(0, "(mls %s)", mls_str);
   3852 
   3853 	return 0;
   3854 }
   3855 
   3856 static int generate_default_level(void)
   3857 {
   3858 	cil_println(0, "(sensitivity s0)");
   3859 	cil_println(0, "(sensitivityorder (s0))");
   3860 	cil_println(0, "(level " DEFAULT_LEVEL " (s0))");
   3861 
   3862 	return 0;
   3863 }
   3864 
   3865 static int generate_default_object(void)
   3866 {
   3867 	cil_println(0, "(role " DEFAULT_OBJECT ")");
   3868 
   3869 	return 0;
   3870 }
   3871 
   3872 static int generate_builtin_roles(void)
   3873 {
   3874 	// due to inconsistentencies between policies and CIL not allowing
   3875 	// duplicate roles, some roles are always created, regardless of if they
   3876 	// are declared in modules or not
   3877 	cil_println(0, "(role auditadm_r)");
   3878 	cil_println(0, "(role secadm_r)");
   3879 
   3880 	return 0;
   3881 }
   3882 
   3883 static int generate_gen_require_attribute(void)
   3884 {
   3885 	cil_println(0, "(typeattribute " GEN_REQUIRE_ATTR ")");
   3886 	cil_println(0, "(roleattribute " GEN_REQUIRE_ATTR ")");
   3887 
   3888 	return 0;
   3889 }
   3890 
   3891 static int fix_module_name(struct policydb *pdb)
   3892 {
   3893 	char *letter;
   3894 	int rc = -1;
   3895 
   3896 	// The base module doesn't have its name set, but we use that for some
   3897 	// autogenerated names, like optionals and attributes, to prevent naming
   3898 	// collisions. However, they sometimes need to be fixed up.
   3899 
   3900 	// the base module isn't given a name, so just call it "base"
   3901 	if (pdb->policy_type == POLICY_BASE) {
   3902 		pdb->name = strdup("base");
   3903 		if (pdb->name == NULL) {
   3904 			log_err("Out of memory");
   3905 			rc = -1;
   3906 			goto exit;
   3907 		}
   3908 	}
   3909 
   3910 	// CIL is more restrictive in module names than checkmodule. Convert bad
   3911 	// characters to underscores
   3912 	for (letter = pdb->name; *letter != '\0'; letter++) {
   3913 		if (isalnum(*letter)) {
   3914 			continue;
   3915 		}
   3916 
   3917 		*letter = '_';
   3918 	}
   3919 
   3920 	return 0;
   3921 exit:
   3922 	return rc;
   3923 }
   3924 
   3925 int sepol_module_policydb_to_cil(FILE *fp, struct policydb *pdb, int linked)
   3926 {
   3927 	int rc = -1;
   3928 
   3929 	out_file = fp;
   3930 
   3931 	if (pdb == NULL) {
   3932 		rc = 0;
   3933 		goto exit;
   3934 	}
   3935 
   3936 	if (pdb->policy_type != SEPOL_POLICY_BASE &&
   3937 		pdb->policy_type != SEPOL_POLICY_MOD) {
   3938 		log_err("Policy pakcage is not a base or module");
   3939 		rc = -1;
   3940 		goto exit;
   3941 	}
   3942 
   3943 	rc = fix_module_name(pdb);
   3944 	if (rc != 0) {
   3945 		goto exit;
   3946 	}
   3947 
   3948 	if (pdb->policy_type == SEPOL_POLICY_BASE && !pdb->mls) {
   3949 		// If this is a base non-mls policy, we need to define a default level
   3950 		// range that can be used for contexts by other non-mls modules, since
   3951 		// CIL requires that all contexts have a range, even if they are
   3952 		// ignored as in non-mls policies
   3953 		rc = generate_default_level();
   3954 		if (rc != 0) {
   3955 			goto exit;
   3956 		}
   3957 	}
   3958 
   3959 	if (pdb->policy_type == SEPOL_POLICY_BASE) {
   3960 		// object_r is implicit in checkmodule, but not with CIL, create it
   3961 		// as part of base
   3962 		rc = generate_default_object();
   3963 		if (rc != 0) {
   3964 			goto exit;
   3965 		}
   3966 
   3967 		rc = generate_builtin_roles();
   3968 		if (rc != 0) {
   3969 			goto exit;
   3970 		}
   3971 
   3972 		// default attribute to be used to mimic gen_require in CIL
   3973 		rc = generate_gen_require_attribute();
   3974 		if (rc != 0) {
   3975 			goto exit;
   3976 		}
   3977 
   3978 		// handle_unknown is used from only the base module
   3979 		rc = handle_unknown_to_cil(pdb);
   3980 		if (rc != 0) {
   3981 			goto exit;
   3982 		}
   3983 
   3984 		// mls is used from only the base module
   3985 		rc = generate_mls(pdb);
   3986 		if (rc != 0) {
   3987 			goto exit;
   3988 		}
   3989 	}
   3990 
   3991 	rc = role_list_create(pdb->p_roles.table);
   3992 	if (rc != 0) {
   3993 		goto exit;
   3994 	}
   3995 
   3996 	rc = typealias_list_create(pdb);
   3997 	if (rc != 0) {
   3998 		goto exit;
   3999 	}
   4000 
   4001 	rc = polcaps_to_cil(pdb);
   4002 	if (rc != 0) {
   4003 		goto exit;
   4004 	}
   4005 
   4006 	rc = ocontexts_to_cil(pdb);
   4007 	if (rc != 0) {
   4008 		goto exit;
   4009 	}
   4010 
   4011 	rc = genfscon_to_cil(pdb);
   4012 	if (rc != 0) {
   4013 		goto exit;
   4014 	}
   4015 
   4016 	// now print everything that is scoped
   4017 	if (linked) {
   4018 		rc = linked_blocks_to_cil(pdb);
   4019 	} else {
   4020 		rc = blocks_to_cil(pdb);
   4021 	}
   4022 	if (rc != 0) {
   4023 		goto exit;
   4024 	}
   4025 
   4026 	rc = 0;
   4027 
   4028 exit:
   4029 	role_list_destroy();
   4030 	typealias_list_destroy();
   4031 
   4032 	return rc;
   4033 }
   4034 
   4035 int sepol_module_package_to_cil(FILE *fp, struct sepol_module_package *mod_pkg)
   4036 {
   4037 	int rc = -1;
   4038 	struct sepol_policydb *pdb;
   4039 
   4040 	out_file = fp;
   4041 
   4042 	pdb = sepol_module_package_get_policy(mod_pkg);
   4043 	if (pdb == NULL) {
   4044 		log_err("Failed to get policydb");
   4045 		rc = -1;
   4046 		goto exit;
   4047 	}
   4048 
   4049 	rc = sepol_module_policydb_to_cil(fp, &pdb->p, 0);
   4050 	if (rc != 0) {
   4051 		goto exit;
   4052 	}
   4053 
   4054 	rc = seusers_to_cil(mod_pkg);
   4055 	if (rc != 0) {
   4056 		goto exit;
   4057 	}
   4058 
   4059 	rc = netfilter_contexts_to_cil(mod_pkg);
   4060 	if (rc != 0) {
   4061 		goto exit;
   4062 	}
   4063 
   4064 	rc = user_extra_to_cil(mod_pkg);
   4065 	if (rc != 0) {
   4066 		goto exit;
   4067 	}
   4068 
   4069 	rc = file_contexts_to_cil(mod_pkg);
   4070 	if (rc != 0) {
   4071 		goto exit;
   4072 	}
   4073 
   4074 	rc = 0;
   4075 
   4076 exit:
   4077 	return rc;
   4078 }
   4079 
   4080 static int fp_to_buffer(FILE *fp, char **data, size_t *data_len)
   4081 {
   4082 	int rc = -1;
   4083 	char *d = NULL;
   4084 	size_t d_len = 0;
   4085 	size_t read_len = 0;
   4086 	size_t max_len = 1 << 17; // start at 128KB, this is enough to hold about half of all the existing pp files
   4087 
   4088 	d = malloc(max_len);
   4089 	if (d == NULL) {
   4090 		log_err("Out of memory");
   4091 		rc = -1;
   4092 		goto exit;
   4093 	}
   4094 
   4095 	while ((read_len = fread(d + d_len, 1, max_len - d_len, fp)) > 0) {
   4096 		d_len += read_len;
   4097 		if (d_len == max_len) {
   4098 			max_len *= 2;
   4099 			d = realloc(d, max_len);
   4100 			if (d == NULL) {
   4101 				log_err("Out of memory");
   4102 				rc = -1;
   4103 				goto exit;
   4104 			}
   4105 		}
   4106 	}
   4107 
   4108 	if (ferror(fp) != 0) {
   4109 		log_err("Failed to read pp file");
   4110 		rc = -1;
   4111 		goto exit;
   4112 	}
   4113 
   4114 	*data = d;
   4115 	*data_len = d_len;
   4116 
   4117 	return 0;
   4118 
   4119 exit:
   4120 	free(d);
   4121 	return rc;
   4122 }
   4123 
   4124 int sepol_ppfile_to_module_package(FILE *fp, struct sepol_module_package **mod_pkg)
   4125 {
   4126 	int rc = -1;
   4127 	FILE *f = NULL;
   4128 	struct sepol_policy_file *pf = NULL;
   4129 	struct sepol_module_package *pkg = NULL;
   4130 	char *data = NULL;
   4131 	size_t data_len;
   4132 	int fd;
   4133 	struct stat sb;
   4134 
   4135 	rc = sepol_policy_file_create(&pf);
   4136 	if (rc != 0) {
   4137 		log_err("Failed to create policy file");
   4138 		goto exit;
   4139 	}
   4140 
   4141 	fd = fileno(fp);
   4142 	if (fstat(fd, &sb) == -1) {
   4143 		rc = -1;
   4144 		goto exit;
   4145 	}
   4146 
   4147 	if (S_ISFIFO(sb.st_mode) || S_ISSOCK(sb.st_mode)) {
   4148 		// libsepol fails when trying to read a policy package from a pipe or a
   4149 		// socket due its use of lseek. In this case, read the data into a
   4150 		// buffer and provide that to libsepol
   4151 		rc = fp_to_buffer(fp, &data, &data_len);
   4152 		if (rc != 0) {
   4153 			goto exit;
   4154 		}
   4155 
   4156 		sepol_policy_file_set_mem(pf, data, data_len);
   4157 	} else {
   4158 		sepol_policy_file_set_fp(pf, fp);
   4159 	}
   4160 
   4161 	rc = sepol_module_package_create(&pkg);
   4162 	if (rc != 0) {
   4163 		log_err("Failed to create module package");
   4164 		goto exit;
   4165 	}
   4166 
   4167 	rc = sepol_module_package_read(pkg, pf, 0);
   4168 	if (rc != 0) {
   4169 		log_err("Failed to read policy package");
   4170 		goto exit;
   4171 	}
   4172 
   4173 	*mod_pkg = pkg;
   4174 
   4175 exit:
   4176 	free(data);
   4177 
   4178 	sepol_policy_file_free(pf);
   4179 	if (f != NULL) {
   4180 		fclose(f);
   4181 	}
   4182 
   4183 	if (rc != 0) {
   4184 		sepol_module_package_free(pkg);
   4185 	}
   4186 
   4187 	return rc;
   4188 }
   4189