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