
/* Author : Stephen Smalley, <sds@tycho.nsa.gov> */

/*
 * Updated: Trusted Computer Solutions, Inc. <dgoeddel@trustedcs.com>
 *
 *	Support for enhanced MLS infrastructure.
 *
 * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com>
 *
 * 	Added conditional policy language extensions
 * 
 * Updated: Red Hat, Inc.  James Morris <jmorris@redhat.com>
 *      Fine-grained netlink support
 *      IPv6 support
 *      Code cleanup
 *
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
 * Copyright (C) 2003 - 2005 Tresys Technology, LLC
 * Copyright (C) 2003 - 2007 Red Hat, Inc.
 * Copyright (C) 2017 Mellanox Technologies Inc.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/* FLASK */

/*
 * Implementation of the policy database.
 */

#include <assert.h>
#include <stdlib.h>

#include <sepol/policydb/policydb.h>
#include <sepol/policydb/expand.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/avrule_block.h>
#include <sepol/policydb/util.h>

#include "kernel_to_common.h"
#include "private.h"
#include "debug.h"
#include "mls.h"
#include "policydb_validate.h"

#define POLICYDB_TARGET_SZ   ARRAY_SIZE(policydb_target_strings)
const char * const policydb_target_strings[] = { POLICYDB_STRING, POLICYDB_XEN_STRING };

/* These need to be updated if SYM_NUM or OCON_NUM changes */
static const struct policydb_compat_info policydb_compat[] = {
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_BOUNDARY,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_XEN_PCIDEVICE + 1,
	 .target_platform = SEPOL_TARGET_XEN,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_XEN_DEVICETREE,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_XEN_DEVICETREE + 1,
	 .target_platform = SEPOL_TARGET_XEN,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_BASE,
	 .sym_num = SYM_NUM - 3,
	 .ocon_num = OCON_FSUSE + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_BOOL,
	 .sym_num = SYM_NUM - 2,
	 .ocon_num = OCON_FSUSE + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_IPV6,
	 .sym_num = SYM_NUM - 2,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_NLCLASS,
	 .sym_num = SYM_NUM - 2,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_MLS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_AVTAB,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_RANGETRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_POLCAP,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_PERMISSIVE,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
        {
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_BOUNDARY,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_FILENAME_TRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_ROLETRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_DEFAULT_TYPE,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_CONSTRAINT_NAMES,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_XPERMS_IOCTL,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_INFINIBAND,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_IBENDPORT + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_GLBLUB,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_IBENDPORT + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_KERN,
	 .version = POLICYDB_VERSION_COMP_FTRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_IBENDPORT + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_BASE,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_MLS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_POLCAP,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_ROLETRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_NODE6 + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_INFINIBAND,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_IBENDPORT + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_GLBLUB,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_IBENDPORT + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_BASE,
	 .version = MOD_POLICYDB_VERSION_SELF_TYPETRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = OCON_IBENDPORT + 1,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_BASE,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_MLS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_MLS_USERS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_POLCAP,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_PERMISSIVE,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	 },
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_BOUNDARY_ALIAS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_FILENAME_TRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_ROLETRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_ROLEATTRIB,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_TUNABLE_SEP,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_DEFAULT_TYPE,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_CONSTRAINT_NAMES,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_INFINIBAND,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_GLBLUB,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
	{
	 .type = POLICY_MOD,
	 .version = MOD_POLICYDB_VERSION_SELF_TYPETRANS,
	 .sym_num = SYM_NUM,
	 .ocon_num = 0,
	 .target_platform = SEPOL_TARGET_SELINUX,
	},
};

#if 0
static char *symtab_name[SYM_NUM] = {
	"common prefixes",
	"classes",
	"roles",
	"types",
	"users",
	"bools" mls_symtab_names cond_symtab_names
};
#endif

static const unsigned int symtab_sizes[SYM_NUM] = {
	2,
	32,
	16,
	512,
	128,
	16,
	16,
	16,
};

const struct policydb_compat_info *policydb_lookup_compat(unsigned int version,
						          unsigned int type,
						          unsigned int target_platform)
{
	unsigned int i;
	const struct policydb_compat_info *info = NULL;

	for (i = 0; i < sizeof(policydb_compat) / sizeof(*info); i++) {
		if (policydb_compat[i].version == version &&
		    policydb_compat[i].type == type &&
		    policydb_compat[i].target_platform == target_platform) {
			info = &policydb_compat[i];
			break;
		}
	}
	return info;
}

void type_set_init(type_set_t * x)
{
	memset(x, 0, sizeof(type_set_t));
	ebitmap_init(&x->types);
	ebitmap_init(&x->negset);
}

void type_set_destroy(type_set_t * x)
{
	if (x != NULL) {
		ebitmap_destroy(&x->types);
		ebitmap_destroy(&x->negset);
	}
}

void role_set_init(role_set_t * x)
{
	memset(x, 0, sizeof(role_set_t));
	ebitmap_init(&x->roles);
}

void role_set_destroy(role_set_t * x)
{
	ebitmap_destroy(&x->roles);
}

void role_datum_init(role_datum_t * x)
{
	memset(x, 0, sizeof(role_datum_t));
	ebitmap_init(&x->dominates);
	type_set_init(&x->types);
	ebitmap_init(&x->cache);
	ebitmap_init(&x->roles);
}

void role_datum_destroy(role_datum_t * x)
{
	if (x != NULL) {
		ebitmap_destroy(&x->dominates);
		type_set_destroy(&x->types);
		ebitmap_destroy(&x->cache);
		ebitmap_destroy(&x->roles);
	}
}

void type_datum_init(type_datum_t * x)
{
	memset(x, 0, sizeof(*x));
	ebitmap_init(&x->types);
}

void type_datum_destroy(type_datum_t * x)
{
	if (x != NULL) {
		ebitmap_destroy(&x->types);
	}
}

void user_datum_init(user_datum_t * x)
{
	memset(x, 0, sizeof(user_datum_t));
	role_set_init(&x->roles);
	mls_semantic_range_init(&x->range);
	mls_semantic_level_init(&x->dfltlevel);
	ebitmap_init(&x->cache);
	mls_range_init(&x->exp_range);
	mls_level_init(&x->exp_dfltlevel);
}

void user_datum_destroy(user_datum_t * x)
{
	if (x != NULL) {
		role_set_destroy(&x->roles);
		mls_semantic_range_destroy(&x->range);
		mls_semantic_level_destroy(&x->dfltlevel);
		ebitmap_destroy(&x->cache);
		mls_range_destroy(&x->exp_range);
		mls_level_destroy(&x->exp_dfltlevel);
	}
}

void level_datum_init(level_datum_t * x)
{
	memset(x, 0, sizeof(level_datum_t));
}

void level_datum_destroy(level_datum_t * x __attribute__ ((unused)))
{
	/* the mls_level_t referenced by the level_datum is managed
	 * separately for now, so there is nothing to destroy */
	return;
}

void cat_datum_init(cat_datum_t * x)
{
	memset(x, 0, sizeof(cat_datum_t));
}

void cat_datum_destroy(cat_datum_t * x __attribute__ ((unused)))
{
	/* it's currently a simple struct - really nothing to destroy */
	return;
}

void class_perm_node_init(class_perm_node_t * x)
{
	memset(x, 0, sizeof(class_perm_node_t));
}

void avrule_init(avrule_t * x)
{
	memset(x, 0, sizeof(avrule_t));
	type_set_init(&x->stypes);
	type_set_init(&x->ttypes);
}

void avrule_destroy(avrule_t * x)
{
	class_perm_node_t *cur, *next;

	if (x == NULL) {
		return;
	}
	type_set_destroy(&x->stypes);
	type_set_destroy(&x->ttypes);

	free(x->source_filename);

	next = x->perms;
	while (next) {
		cur = next;
		next = cur->next;
		free(cur);
	}

	free(x->xperms);
}

void role_trans_rule_init(role_trans_rule_t * x)
{
	memset(x, 0, sizeof(*x));
	role_set_init(&x->roles);
	type_set_init(&x->types);
	ebitmap_init(&x->classes);
}

static void role_trans_rule_destroy(role_trans_rule_t * x)
{
	if (x != NULL) {
		role_set_destroy(&x->roles);
		type_set_destroy(&x->types);
		ebitmap_destroy(&x->classes);
	}
}

void role_trans_rule_list_destroy(role_trans_rule_t * x)
{
	while (x != NULL) {
		role_trans_rule_t *next = x->next;
		role_trans_rule_destroy(x);
		free(x);
		x = next;
	}
}

void filename_trans_rule_init(filename_trans_rule_t * x)
{
	memset(x, 0, sizeof(*x));
	type_set_init(&x->stypes);
	type_set_init(&x->ttypes);
}

static void filename_trans_rule_destroy(filename_trans_rule_t * x)
{
	if (!x)
		return;
	type_set_destroy(&x->stypes);
	type_set_destroy(&x->ttypes);
	free(x->name);
}

void filename_trans_rule_list_destroy(filename_trans_rule_t * x)
{
	filename_trans_rule_t *next;
	while (x) {
		next = x->next;
		filename_trans_rule_destroy(x);
		free(x);
		x = next;
	}
}

void role_allow_rule_init(role_allow_rule_t * x)
{
	memset(x, 0, sizeof(role_allow_rule_t));
	role_set_init(&x->roles);
	role_set_init(&x->new_roles);
}

void role_allow_rule_destroy(role_allow_rule_t * x)
{
	role_set_destroy(&x->roles);
	role_set_destroy(&x->new_roles);
}

void role_allow_rule_list_destroy(role_allow_rule_t * x)
{
	while (x != NULL) {
		role_allow_rule_t *next = x->next;
		role_allow_rule_destroy(x);
		free(x);
		x = next;
	}
}

void range_trans_rule_init(range_trans_rule_t * x)
{
	type_set_init(&x->stypes);
	type_set_init(&x->ttypes);
	ebitmap_init(&x->tclasses);
	mls_semantic_range_init(&x->trange);
	x->next = NULL;
}

void range_trans_rule_destroy(range_trans_rule_t * x)
{
	type_set_destroy(&x->stypes);
	type_set_destroy(&x->ttypes);
	ebitmap_destroy(&x->tclasses);
	mls_semantic_range_destroy(&x->trange);
}

void range_trans_rule_list_destroy(range_trans_rule_t * x)
{
	while (x != NULL) {
		range_trans_rule_t *next = x->next;
		range_trans_rule_destroy(x);
		free(x);
		x = next;
	}
}

void avrule_list_destroy(avrule_t * x)
{
	avrule_t *next, *cur;

	if (!x)
		return;

	next = x;
	while (next) {
		cur = next;
		next = next->next;
		avrule_destroy(cur);
		free(cur);
	}
}

/* 
 * Initialize the role table by implicitly adding role 'object_r'.  If
 * the policy is a module, set object_r's scope to be SCOPE_REQ,
 * otherwise set it to SCOPE_DECL.
 */
static int roles_init(policydb_t * p)
{
	char *key = 0;
	int rc;
	role_datum_t *role;

	role = calloc(1, sizeof(role_datum_t));
	if (!role) {
		rc = -ENOMEM;
		goto out;
	}
	key = strdup(OBJECT_R);
	if (!key) {
		rc = -ENOMEM;
		goto out_free_role;
	}
	rc = symtab_insert(p, SYM_ROLES, key, role,
			   (p->policy_type ==
			    POLICY_MOD ? SCOPE_REQ : SCOPE_DECL), 1,
			   &role->s.value);
	if (rc)
		goto out_free_key;
	if (role->s.value != OBJECT_R_VAL) {
		rc = -EINVAL;
		goto out_free_role;
	}
      out:
	return rc;

      out_free_key:
	free(key);
      out_free_role:
	free(role);
	goto out;
}

ignore_unsigned_overflow_
static inline unsigned long
partial_name_hash(unsigned long c, unsigned long prevhash)
{
	return (prevhash + (c << 4) + (c >> 4)) * 11;
}

static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)
{
	const filename_trans_key_t *ft = (const filename_trans_key_t *)k;
	unsigned long hash;
	unsigned int byte_num;
	unsigned char focus;

	hash = ft->ttype ^ ft->tclass;

	byte_num = 0;
	while ((focus = ft->name[byte_num++]))
		hash = partial_name_hash(focus, hash);
	return hash & (h->size - 1);
}

static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),
			  const_hashtab_key_t k1, const_hashtab_key_t k2)
{
	const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1;
	const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;
	int v;

	v = spaceship_cmp(ft1->ttype, ft2->ttype);
	if (v)
		return v;

	v = spaceship_cmp(ft1->tclass, ft2->tclass);
	if (v)
		return v;

	return strcmp(ft1->name, ft2->name);

}

static unsigned int rangetr_hash(hashtab_t h, const_hashtab_key_t k)
{
	const struct range_trans *key = (const struct range_trans *)k;
	return (key->source_type + (key->target_type << 3) +
		(key->target_class << 5)) & (h->size - 1);
}

static int rangetr_cmp(hashtab_t h __attribute__ ((unused)),
		       const_hashtab_key_t k1, const_hashtab_key_t k2)
{
	const struct range_trans *key1 = (const struct range_trans *)k1;
	const struct range_trans *key2 = (const struct range_trans *)k2;
	int v;

	v = spaceship_cmp(key1->source_type, key2->source_type);
	if (v)
		return v;

	v = spaceship_cmp(key1->target_type, key2->target_type);
	if (v)
		return v;

	v = spaceship_cmp(key1->target_class, key2->target_class);

	return v;
}

/*
 * Initialize a policy database structure.
 */
int policydb_init(policydb_t * p)
{
	int i, rc;

	memset(p, 0, sizeof(policydb_t));

	for (i = 0; i < SYM_NUM; i++) {
		p->sym_val_to_name[i] = NULL;
		rc = symtab_init(&p->symtab[i], symtab_sizes[i]);
		if (rc)
			goto err;
	}

	/* initialize the module stuff */
	for (i = 0; i < SYM_NUM; i++) {
		if (symtab_init(&p->scope[i], symtab_sizes[i])) {
			goto err;
		}
	}
	if ((p->global = avrule_block_create()) == NULL ||
	    (p->global->branch_list = avrule_decl_create(1)) == NULL) {
		goto err;
	}
	p->decl_val_to_struct = NULL;

	rc = avtab_init(&p->te_avtab);
	if (rc)
		goto err;

	rc = roles_init(p);
	if (rc)
		goto err;

	rc = cond_policydb_init(p);
	if (rc)
		goto err;

	p->filename_trans = hashtab_create(filenametr_hash, filenametr_cmp, (1 << 10));
	if (!p->filename_trans) {
		rc = -ENOMEM;
		goto err;
	}

	p->range_tr = hashtab_create(rangetr_hash, rangetr_cmp, 256);
	if (!p->range_tr) {
		rc = -ENOMEM;
		goto err;
	}

	ebitmap_init(&p->policycaps);
	ebitmap_init(&p->permissive_map);

	return 0;
err:
	hashtab_destroy(p->filename_trans);
	hashtab_destroy(p->range_tr);
	for (i = 0; i < SYM_NUM; i++) {
		hashtab_destroy(p->symtab[i].table);
		hashtab_destroy(p->scope[i].table);
	}
	avrule_block_list_destroy(p->global);
	return rc;
}

int policydb_role_cache(hashtab_key_t key
			__attribute__ ((unused)), hashtab_datum_t datum,
			void *arg)
{
	policydb_t *p;
	role_datum_t *role;

	role = (role_datum_t *) datum;
	p = (policydb_t *) arg;

	ebitmap_destroy(&role->cache);
	if (type_set_expand(&role->types, &role->cache, p, 1)) {
		return -1;
	}

	return 0;
}

int policydb_user_cache(hashtab_key_t key
			__attribute__ ((unused)), hashtab_datum_t datum,
			void *arg)
{
	policydb_t *p;
	user_datum_t *user;

	user = (user_datum_t *) datum;
	p = (policydb_t *) arg;

	ebitmap_destroy(&user->cache);
	if (role_set_expand(&user->roles, &user->cache, p, NULL, NULL)) {
		return -1;
	}

	/* we do not expand user's MLS info in kernel policies because the
	 * semantic representation is not present and we do not expand user's
	 * MLS info in module policies because all of the necessary mls
	 * information is not present */
	if (p->policy_type != POLICY_KERN && p->policy_type != POLICY_MOD) {
		mls_range_destroy(&user->exp_range);
		if (mls_semantic_range_expand(&user->range,
					      &user->exp_range, p, NULL)) {
			return -1;
		}

		mls_level_destroy(&user->exp_dfltlevel);
		if (mls_semantic_level_expand(&user->dfltlevel,
					      &user->exp_dfltlevel, p, NULL)) {
			return -1;
		}
	}

	return 0;
}

/*
 * The following *_index functions are used to
 * define the val_to_name and val_to_struct arrays
 * in a policy database structure.  The val_to_name
 * arrays are used when converting security context
 * structures into string representations.  The
 * val_to_struct arrays are used when the attributes
 * of a class, role, or user are needed.
 */

static int common_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	common_datum_t *comdatum;

	comdatum = (common_datum_t *) datum;
	p = (policydb_t *) datap;
	if (!value_isvalid(comdatum->s.value, p->p_commons.nprim))
		return -EINVAL;
	if (p->p_common_val_to_name[comdatum->s.value - 1] != NULL)
		return -EINVAL;
	p->p_common_val_to_name[comdatum->s.value - 1] = (char *)key;

	return 0;
}

static int class_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	class_datum_t *cladatum;

	cladatum = (class_datum_t *) datum;
	p = (policydb_t *) datap;
	if (!value_isvalid(cladatum->s.value, p->p_classes.nprim))
		return -EINVAL;
	if (p->p_class_val_to_name[cladatum->s.value - 1] != NULL)
		return -EINVAL;
	p->p_class_val_to_name[cladatum->s.value - 1] = (char *)key;
	p->class_val_to_struct[cladatum->s.value - 1] = cladatum;

	return 0;
}

static int role_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	role_datum_t *role;

	role = (role_datum_t *) datum;
	p = (policydb_t *) datap;
	if (!value_isvalid(role->s.value, p->p_roles.nprim))
		return -EINVAL;
	if (p->p_role_val_to_name[role->s.value - 1] != NULL)
		return -EINVAL;
	p->p_role_val_to_name[role->s.value - 1] = (char *)key;
	p->role_val_to_struct[role->s.value - 1] = role;

	return 0;
}

static int type_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	type_datum_t *typdatum;

	typdatum = (type_datum_t *) datum;
	p = (policydb_t *) datap;

	if (typdatum->primary) {
		if (!value_isvalid(typdatum->s.value, p->p_types.nprim))
			return -EINVAL;
		if (p->p_type_val_to_name[typdatum->s.value - 1] != NULL)
			return -EINVAL;
		p->p_type_val_to_name[typdatum->s.value - 1] = (char *)key;
		p->type_val_to_struct[typdatum->s.value - 1] = typdatum;
	}

	return 0;
}

static int user_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	user_datum_t *usrdatum;

	usrdatum = (user_datum_t *) datum;
	p = (policydb_t *) datap;

	if (!value_isvalid(usrdatum->s.value, p->p_users.nprim))
		return -EINVAL;
	if (p->p_user_val_to_name[usrdatum->s.value - 1] != NULL)
		return -EINVAL;
	p->p_user_val_to_name[usrdatum->s.value - 1] = (char *)key;
	p->user_val_to_struct[usrdatum->s.value - 1] = usrdatum;

	return 0;
}

static int sens_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	level_datum_t *levdatum;

	levdatum = (level_datum_t *) datum;
	p = (policydb_t *) datap;

	if (!levdatum->isalias) {
		if (!value_isvalid(levdatum->level->sens, p->p_levels.nprim))
			return -EINVAL;
		if (p->p_sens_val_to_name[levdatum->level->sens - 1] != NULL)
			return -EINVAL;
		p->p_sens_val_to_name[levdatum->level->sens - 1] = (char *)key;
	}

	return 0;
}

static int cat_index(hashtab_key_t key, hashtab_datum_t datum, void *datap)
{
	policydb_t *p;
	cat_datum_t *catdatum;

	catdatum = (cat_datum_t *) datum;
	p = (policydb_t *) datap;

	if (!catdatum->isalias) {
		if (!value_isvalid(catdatum->s.value, p->p_cats.nprim))
			return -EINVAL;
		if (p->p_cat_val_to_name[catdatum->s.value - 1] != NULL)
			return -EINVAL;
		p->p_cat_val_to_name[catdatum->s.value - 1] = (char *)key;
	}

	return 0;
}

static int (*index_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
				void *datap) = {
common_index, class_index, role_index, type_index, user_index,
	    cond_index_bool, sens_index, cat_index,};

/*
 * Define the common val_to_name array and the class
 * val_to_name and val_to_struct arrays in a policy
 * database structure.  
 */
int policydb_index_classes(policydb_t * p)
{
	free(p->p_common_val_to_name);
	p->p_common_val_to_name = (char **)
	    calloc(p->p_commons.nprim, sizeof(char *));
	if (!p->p_common_val_to_name)
		return -1;

	if (hashtab_map(p->p_commons.table, common_index, p))
		return -1;

	free(p->class_val_to_struct);
	p->class_val_to_struct = (class_datum_t **)
	    calloc(p->p_classes.nprim, sizeof(class_datum_t *));
	if (!p->class_val_to_struct)
		return -1;

	free(p->p_class_val_to_name);
	p->p_class_val_to_name = (char **)
	    calloc(p->p_classes.nprim, sizeof(char *));
	if (!p->p_class_val_to_name)
		return -1;

	if (hashtab_map(p->p_classes.table, class_index, p))
		return -1;

	return 0;
}

int policydb_index_bools(policydb_t * p)
{

	if (cond_init_bool_indexes(p) == -1)
		return -1;
	p->p_bool_val_to_name = (char **)
	    calloc(p->p_bools.nprim, sizeof(char *));
	if (!p->p_bool_val_to_name)
		return -1;
	if (hashtab_map(p->p_bools.table, cond_index_bool, p))
		return -1;
	return 0;
}

static int policydb_index_decls(sepol_handle_t * handle, policydb_t * p)
{
	avrule_block_t *curblock;
	avrule_decl_t *decl;
	unsigned int num_decls = 0;

	free(p->decl_val_to_struct);

	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
		for (decl = curblock->branch_list; decl != NULL;
		     decl = decl->next) {
			num_decls++;
		}
	}

	p->decl_val_to_struct =
	    calloc(num_decls, sizeof(*(p->decl_val_to_struct)));
	if (!p->decl_val_to_struct) {
		return -1;
	}

	for (curblock = p->global; curblock != NULL; curblock = curblock->next) {
		for (decl = curblock->branch_list; decl != NULL;
		     decl = decl->next) {
			if (!value_isvalid(decl->decl_id, num_decls)) {
				ERR(handle, "invalid decl ID %u", decl->decl_id);
				return -1;
			}
			if (p->decl_val_to_struct[decl->decl_id - 1] != NULL) {
				ERR(handle, "duplicated decl ID %u", decl->decl_id);
				return -1;
			}
			p->decl_val_to_struct[decl->decl_id - 1] = decl;
		}
	}

	return 0;
}

/*
 * Define the other val_to_name and val_to_struct arrays
 * in a policy database structure.  
 */
int policydb_index_others(sepol_handle_t * handle,
			  policydb_t * p, unsigned verbose)
{
	int i;

	if (verbose) {
		INFO(handle,
		     "security:  %d users, %d roles, %d types, %d bools",
		     p->p_users.nprim, p->p_roles.nprim, p->p_types.nprim,
		     p->p_bools.nprim);

		if (p->mls)
			INFO(handle, "security: %d sens, %d cats",
			     p->p_levels.nprim, p->p_cats.nprim);

		INFO(handle, "security:  %d classes, %d rules, %d cond rules",
		     p->p_classes.nprim, p->te_avtab.nel, p->te_cond_avtab.nel);
	}
#if 0
	avtab_hash_eval(&p->te_avtab, "rules");
	for (i = 0; i < SYM_NUM; i++)
		hashtab_hash_eval(p->symtab[i].table, symtab_name[i]);
#endif

	free(p->role_val_to_struct);
	p->role_val_to_struct = (role_datum_t **)
	    calloc(p->p_roles.nprim, sizeof(role_datum_t *));
	if (!p->role_val_to_struct)
		return -1;

	free(p->user_val_to_struct);
	p->user_val_to_struct = (user_datum_t **)
	    calloc(p->p_users.nprim, sizeof(user_datum_t *));
	if (!p->user_val_to_struct)
		return -1;

	free(p->type_val_to_struct);
	p->type_val_to_struct = (type_datum_t **)
	    calloc(p->p_types.nprim, sizeof(type_datum_t *));
	if (!p->type_val_to_struct)
		return -1;

	if (cond_init_bool_indexes(p))
		return -1;

	for (i = SYM_ROLES; i < SYM_NUM; i++) {
		free(p->sym_val_to_name[i]);
		p->sym_val_to_name[i] = NULL;
		if (p->symtab[i].nprim) {
			p->sym_val_to_name[i] = (char **)
			    calloc(p->symtab[i].nprim, sizeof(char *));
			if (!p->sym_val_to_name[i])
				return -1;
			if (hashtab_map(p->symtab[i].table, index_f[i], p))
				return -1;
		}
	}

	/* This pre-expands the roles and users for context validity checking */
	if (hashtab_map(p->p_roles.table, policydb_role_cache, p))
		return -1;

	if (hashtab_map(p->p_users.table, policydb_user_cache, p))
		return -1;

	return 0;
}

/*
 * The following *_destroy functions are used to
 * free any memory allocated for each kind of
 * symbol data in the policy database.
 */

static int perm_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			__attribute__ ((unused)))
{
	if (key)
		free(key);
	free(datum);
	return 0;
}

static int common_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			  __attribute__ ((unused)))
{
	common_datum_t *comdatum;

	if (key)
		free(key);
	comdatum = (common_datum_t *) datum;
	(void)hashtab_map(comdatum->permissions.table, perm_destroy, 0);
	hashtab_destroy(comdatum->permissions.table);
	free(datum);
	return 0;
}

static int class_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			 __attribute__ ((unused)))
{
	class_datum_t *cladatum;
	constraint_node_t *constraint, *ctemp;

	if (key)
		free(key);
	cladatum = (class_datum_t *) datum;
	if (cladatum == NULL) {
		return 0;
	}
	(void)hashtab_map(cladatum->permissions.table, perm_destroy, 0);
	hashtab_destroy(cladatum->permissions.table);
	constraint = cladatum->constraints;
	while (constraint) {
		constraint_expr_destroy(constraint->expr);
		ctemp = constraint;
		constraint = constraint->next;
		free(ctemp);
	}

	constraint = cladatum->validatetrans;
	while (constraint) {
		constraint_expr_destroy(constraint->expr);
		ctemp = constraint;
		constraint = constraint->next;
		free(ctemp);
	}

	if (cladatum->comkey)
		free(cladatum->comkey);
	free(datum);
	return 0;
}

static int role_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			__attribute__ ((unused)))
{
	free(key);
	role_datum_destroy((role_datum_t *) datum);
	free(datum);
	return 0;
}

static int type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			__attribute__ ((unused)))
{
	free(key);
	type_datum_destroy((type_datum_t *) datum);
	free(datum);
	return 0;
}

static int user_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			__attribute__ ((unused)))
{
	free(key);
	user_datum_destroy((user_datum_t *) datum);
	free(datum);
	return 0;
}

static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
			__attribute__ ((unused)))
{
	level_datum_t *levdatum;

	if (key)
		free(key);
	levdatum = (level_datum_t *) datum;
	mls_level_destroy(levdatum->level);
	free(levdatum->level);
	level_datum_destroy(levdatum);
	free(levdatum);
	return 0;
}

static int cat_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
		       __attribute__ ((unused)))
{
	if (key)
		free(key);
	cat_datum_destroy((cat_datum_t *) datum);
	free(datum);
	return 0;
}

static int (*destroy_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
				  void *datap) = {
common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,
	    cond_destroy_bool, sens_destroy, cat_destroy,};

static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum,
			      void *p __attribute__ ((unused)))
{
	filename_trans_key_t *ft = (filename_trans_key_t *)key;
	filename_trans_datum_t *fd = datum, *next;

	free(ft->name);
	free(key);
	do {
		next = fd->next;
		ebitmap_destroy(&fd->stypes);
		free(fd);
		fd = next;
	} while (fd);
	return 0;
}

static int range_tr_destroy(hashtab_key_t key, hashtab_datum_t datum,
			    void *p __attribute__ ((unused)))
{
	struct mls_range *rt = (struct mls_range *)datum;
	free(key);
	ebitmap_destroy(&rt->level[0].cat);
	ebitmap_destroy(&rt->level[1].cat);
	free(datum);
	return 0;
}

static void ocontext_selinux_free(ocontext_t **ocontexts)
{
	ocontext_t *c, *ctmp;
	int i;

	for (i = 0; i < OCON_NUM; i++) {
		c = ocontexts[i];
		while (c) {
			ctmp = c;
			c = c->next;
			context_destroy(&ctmp->context[0]);
			context_destroy(&ctmp->context[1]);
			if (i == OCON_ISID || i == OCON_FS || i == OCON_NETIF
				|| i == OCON_FSUSE)
				free(ctmp->u.name);
			else if (i == OCON_IBENDPORT)
				free(ctmp->u.ibendport.dev_name);
			free(ctmp);
		}
	}
}

static void ocontext_xen_free(ocontext_t **ocontexts)
{
	ocontext_t *c, *ctmp;
	int i;

	for (i = 0; i < OCON_NUM; i++) {
		c = ocontexts[i];
		while (c) {
			ctmp = c;
			c = c->next;
			context_destroy(&ctmp->context[0]);
			context_destroy(&ctmp->context[1]);
			if (i == OCON_ISID || i == OCON_XEN_DEVICETREE)
				free(ctmp->u.name);
			free(ctmp);
		}
	}
}

/*
 * Free any memory allocated by a policy database structure.
 */
void policydb_destroy(policydb_t * p)
{
	ocontext_t *c, *ctmp;
	genfs_t *g, *gtmp;
	unsigned int i;
	role_allow_t *ra, *lra = NULL;
	role_trans_t *tr, *ltr = NULL;

	if (!p)
		return;

	ebitmap_destroy(&p->policycaps);

	ebitmap_destroy(&p->permissive_map);

	symtabs_destroy(p->symtab);

	for (i = 0; i < SYM_NUM; i++) {
		if (p->sym_val_to_name[i])
			free(p->sym_val_to_name[i]);
	}

	if (p->class_val_to_struct)
		free(p->class_val_to_struct);
	if (p->role_val_to_struct)
		free(p->role_val_to_struct);
	if (p->user_val_to_struct)
		free(p->user_val_to_struct);
	if (p->type_val_to_struct)
		free(p->type_val_to_struct);
	free(p->decl_val_to_struct);

	for (i = 0; i < SYM_NUM; i++) {
		(void)hashtab_map(p->scope[i].table, scope_destroy, 0);
		hashtab_destroy(p->scope[i].table);
	}
	avrule_block_list_destroy(p->global);
	free(p->name);
	free(p->version);

	avtab_destroy(&p->te_avtab);

	if (p->target_platform == SEPOL_TARGET_SELINUX)
		ocontext_selinux_free(p->ocontexts);
	else if (p->target_platform == SEPOL_TARGET_XEN)
		ocontext_xen_free(p->ocontexts);

	g = p->genfs;
	while (g) {
		free(g->fstype);
		c = g->head;
		while (c) {
			ctmp = c;
			c = c->next;
			context_destroy(&ctmp->context[0]);
			free(ctmp->u.name);
			free(ctmp);
		}
		gtmp = g;
		g = g->next;
		free(gtmp);
	}
	cond_policydb_destroy(p);

	for (tr = p->role_tr; tr; tr = tr->next) {
		if (ltr)
			free(ltr);
		ltr = tr;
	}
	if (ltr)
		free(ltr);

	for (ra = p->role_allow; ra; ra = ra->next) {
		if (lra)
			free(lra);
		lra = ra;
	}
	if (lra)
		free(lra);

	hashtab_map(p->filename_trans, filenametr_destroy, NULL);
	hashtab_destroy(p->filename_trans);

	hashtab_map(p->range_tr, range_tr_destroy, NULL);
	hashtab_destroy(p->range_tr);

	if (p->type_attr_map) {
		for (i = 0; i < p->p_types.nprim; i++) {
			ebitmap_destroy(&p->type_attr_map[i]);
		}
		free(p->type_attr_map);
	}

	if (p->attr_type_map) {
		for (i = 0; i < p->p_types.nprim; i++) {
			ebitmap_destroy(&p->attr_type_map[i]);
		}
		free(p->attr_type_map);
	}

	return;
}

void symtabs_destroy(symtab_t * symtab)
{
	int i;
	for (i = 0; i < SYM_NUM; i++) {
		(void)hashtab_map(symtab[i].table, destroy_f[i], 0);
		hashtab_destroy(symtab[i].table);
	}
}

int scope_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
		  __attribute__ ((unused)))
{
	scope_datum_t *cur = (scope_datum_t *) datum;
	free(key);
	if (cur != NULL) {
		free(cur->decl_ids);
	}
	free(cur);
	return 0;
}

/*
 * Load the initial SIDs specified in a policy database
 * structure into a SID table.
 */
int policydb_load_isids(policydb_t * p, sidtab_t * s)
{
	ocontext_t *head, *c;

	if (sepol_sidtab_init(s)) {
		ERR(NULL, "out of memory on SID table init");
		return -1;
	}

	head = p->ocontexts[OCON_ISID];
	for (c = head; c; c = c->next) {
		if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) {
			ERR(NULL, "unable to load initial SID %s", c->u.name);
			return -1;
		}
	}

	return 0;
}

/* Declare a symbol for a certain avrule_block context.  Insert it
 * into a symbol table for a policy.  This function will handle
 * inserting the appropriate scope information in addition to
 * inserting the symbol into the hash table.
 *
 * arguments:
 *   policydb_t *pol       module policy to modify
 *   uint32_t sym          the symbole table for insertion (SYM_*)
 *   hashtab_key_t key     the key for the symbol - not cloned
 *   hashtab_datum_t data  the data for the symbol - not cloned
 *   scope                 scope of this symbol, either SCOPE_REQ or SCOPE_DECL
 *   avrule_decl_id        identifier for this symbol's encapsulating declaration
 *   value (out)           assigned value to the symbol (if value is not NULL)
 *
 * returns:
 *   0                     success
 *   1                     success, but symbol already existed as a requirement
 *                         (datum was not inserted and needs to be free()d)
 *   -1                    general error
 *   -2                    scope conflicted
 *   -ENOMEM               memory error
 *   error codes from hashtab_insert
 */
int symtab_insert(policydb_t * pol, uint32_t sym,
		  hashtab_key_t key, hashtab_datum_t datum,
		  uint32_t scope, uint32_t avrule_decl_id, uint32_t * value)
{
	int rc, retval = 0;
	unsigned int i;
	scope_datum_t *scope_datum;

	/* check if the symbol is already there.  multiple
	 * declarations of non-roles/non-users are illegal, but
	 * multiple requires are allowed. */

	/* FIX ME - the failures after the hashtab_insert will leave
	 * the policy in a inconsistent state. */
	rc = hashtab_insert(pol->symtab[sym].table, key, datum);
	if (rc == SEPOL_OK) {
		/* if no value is passed in the symbol is not primary
		 * (i.e. aliases) */
		if (value)
			*value = ++pol->symtab[sym].nprim;
	} else if (rc == SEPOL_EEXIST) {
		retval = 1;	/* symbol not added -- need to free() later */
	} else {
		return rc;
	}

	/* get existing scope information; if there is not one then
	 * create it */
	scope_datum =
	    (scope_datum_t *) hashtab_search(pol->scope[sym].table, key);
	if (scope_datum == NULL) {
		hashtab_key_t key2 = strdup((char *)key);
		if (!key2)
			return -ENOMEM;
		if ((scope_datum = malloc(sizeof(*scope_datum))) == NULL) {
			free(key2);
			return -ENOMEM;
		}
		scope_datum->scope = scope;
		scope_datum->decl_ids = NULL;
		scope_datum->decl_ids_len = 0;
		if ((rc =
		     hashtab_insert(pol->scope[sym].table, key2,
				    scope_datum)) != 0) {
			free(key2);
			free(scope_datum);
			return rc;
		}
	} else if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_DECL) {
		/* disallow multiple declarations for non-roles/users */
		if (sym != SYM_ROLES && sym != SYM_USERS) {
			return -2;
		}
		/* Further confine that a role attribute can't have the same
		 * name as another regular role, and a role attribute can't
		 * be declared more than once. */
		if (sym == SYM_ROLES) {
			role_datum_t *base_role;
			role_datum_t *cur_role = (role_datum_t *)datum;
		
			base_role = (role_datum_t *)
					hashtab_search(pol->symtab[sym].table,
						       key);
			assert(base_role != NULL);

			if (!((base_role->flavor == ROLE_ROLE) &&
			    (cur_role->flavor == ROLE_ROLE))) {
				/* Only regular roles are allowed to have
				 * multiple declarations. */
				return -2;
			}
		}
	} else if (scope_datum->scope == SCOPE_REQ && scope == SCOPE_DECL) {
		scope_datum->scope = SCOPE_DECL;
	}

	/* search through the pre-existing list to avoid adding duplicates */
	for (i = 0; i < scope_datum->decl_ids_len; i++) {
		if (scope_datum->decl_ids[i] == avrule_decl_id) {
			/* already there, so don't modify its scope */
			return retval;
		}
	}

	if (add_i_to_a(avrule_decl_id,
		       &scope_datum->decl_ids_len,
		       &scope_datum->decl_ids) == -1) {
		return -ENOMEM;
	}

	if (scope_datum->scope == SCOPE_DECL && scope == SCOPE_REQ) {
		/* Need to keep the decl at the end of the list */
		uint32_t len, tmp;
		len = scope_datum->decl_ids_len;
		if (len < 2) {
			/* This should be impossible here */
			return -1;
		}
		tmp = scope_datum->decl_ids[len-2];
		scope_datum->decl_ids[len-2] = scope_datum->decl_ids[len-1];
		scope_datum->decl_ids[len-1] = tmp;
	}

	return retval;
}

static int type_set_or(type_set_t * dst, const type_set_t * a, const type_set_t * b)
{
	type_set_init(dst);

	if (ebitmap_or(&dst->types, &a->types, &b->types)) {
		return -1;
	}
	if (ebitmap_or(&dst->negset, &a->negset, &b->negset)) {
		return -1;
	}

	dst->flags |= a->flags;
	dst->flags |= b->flags;

	return 0;
}

int type_set_cpy(type_set_t * dst, const type_set_t * src)
{
	type_set_init(dst);

	dst->flags = src->flags;
	if (ebitmap_cpy(&dst->types, &src->types))
		return -1;
	if (ebitmap_cpy(&dst->negset, &src->negset))
		return -1;

	return 0;
}

int type_set_or_eq(type_set_t * dst, const type_set_t * other)
{
	int ret;
	type_set_t tmp;

	if (type_set_or(&tmp, dst, other))
		return -1;
	type_set_destroy(dst);
	ret = type_set_cpy(dst, &tmp);
	type_set_destroy(&tmp);

	return ret;
}

/***********************************************************************/
/* everything below is for policy reads */

/* The following are read functions for module structures */

static int role_set_read(role_set_t * r, struct policy_file *fp)
{
	uint32_t buf[1];
	int rc;

	if (ebitmap_read(&r->roles, fp))
		return -1;
	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	r->flags = le32_to_cpu(buf[0]);

	return 0;
}

static int type_set_read(type_set_t * t, struct policy_file *fp)
{
	uint32_t buf[1];
	int rc;

	if (ebitmap_read(&t->types, fp))
		return -1;
	if (ebitmap_read(&t->negset, fp))
		return -1;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	t->flags = le32_to_cpu(buf[0]);

	return 0;
}

/*
 * Read a MLS range structure from a policydb binary 
 * representation file.
 */
static int mls_read_range_helper(mls_range_t * r, struct policy_file *fp)
{
	uint32_t buf[2], items;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		goto out;

	items = le32_to_cpu(buf[0]);
	if (items > ARRAY_SIZE(buf)) {
		ERR(fp->handle, "range overflow");
		rc = -EINVAL;
		goto out;
	}
	rc = next_entry(buf, fp, sizeof(uint32_t) * items);
	if (rc < 0) {
		ERR(fp->handle, "truncated range");
		goto out;
	}
	r->level[0].sens = le32_to_cpu(buf[0]);
	if (items > 1)
		r->level[1].sens = le32_to_cpu(buf[1]);
	else
		r->level[1].sens = r->level[0].sens;

	rc = ebitmap_read(&r->level[0].cat, fp);
	if (rc) {
		ERR(fp->handle, "error reading low categories");
		goto out;
	}
	if (items > 1) {
		rc = ebitmap_read(&r->level[1].cat, fp);
		if (rc) {
			ERR(fp->handle, "error reading high categories");
			goto bad_high;
		}
	} else {
		rc = ebitmap_cpy(&r->level[1].cat, &r->level[0].cat);
		if (rc) {
			ERR(fp->handle, "out of memory");
			goto bad_high;
		}
	}

	rc = 0;
      out:
	return rc;
      bad_high:
	ebitmap_destroy(&r->level[0].cat);
	goto out;
}

/*
 * Read a semantic MLS level structure from a policydb binary 
 * representation file.
 */
static int mls_read_semantic_level_helper(mls_semantic_level_t * l,
					  struct policy_file *fp)
{
	uint32_t buf[2], ncat;
	unsigned int i;
	mls_semantic_cat_t *cat;
	int rc;

	mls_semantic_level_init(l);

	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
	if (rc < 0) {
		ERR(fp->handle, "truncated level");
		goto bad;
	}
	l->sens = le32_to_cpu(buf[0]);

	ncat = le32_to_cpu(buf[1]);
	for (i = 0; i < ncat; i++) {
		cat = (mls_semantic_cat_t *) malloc(sizeof(mls_semantic_cat_t));
		if (!cat) {
			ERR(fp->handle, "out of memory");
			goto bad;
		}

		mls_semantic_cat_init(cat);
		cat->next = l->cat;
		l->cat = cat;

		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
		if (rc < 0) {
			ERR(fp->handle, "error reading level categories");
			goto bad;
		}
		cat->low = le32_to_cpu(buf[0]);
		cat->high = le32_to_cpu(buf[1]);
	}

	return 0;

      bad:
	return -EINVAL;
}

/*
 * Read a semantic MLS range structure from a policydb binary 
 * representation file.
 */
static int mls_read_semantic_range_helper(mls_semantic_range_t * r,
					  struct policy_file *fp)
{
	int rc;

	rc = mls_read_semantic_level_helper(&r->level[0], fp);
	if (rc)
		return rc;

	rc = mls_read_semantic_level_helper(&r->level[1], fp);

	return rc;
}

static int mls_level_to_semantic(mls_level_t * l, mls_semantic_level_t * sl)
{
	unsigned int i;
	ebitmap_node_t *cnode;
	mls_semantic_cat_t *open_cat = NULL;

	mls_semantic_level_init(sl);
	sl->sens = l->sens;
	ebitmap_for_each_bit(&l->cat, cnode, i) {
		if (ebitmap_node_get_bit(cnode, i)) {
			if (open_cat)
				continue;
			open_cat = (mls_semantic_cat_t *)
			    malloc(sizeof(mls_semantic_cat_t));
			if (!open_cat)
				return -1;

			mls_semantic_cat_init(open_cat);
			open_cat->low = i + 1;
			open_cat->next = sl->cat;
			sl->cat = open_cat;
		} else {
			if (!open_cat)
				continue;
			open_cat->high = i;
			open_cat = NULL;
		}
	}
	if (open_cat)
		open_cat->high = i;

	return 0;
}

static int mls_range_to_semantic(mls_range_t * r, mls_semantic_range_t * sr)
{
	if (mls_level_to_semantic(&r->level[0], &sr->level[0]))
		return -1;

	if (mls_level_to_semantic(&r->level[1], &sr->level[1]))
		return -1;

	return 0;
}

/*
 * Read and validate a security context structure
 * from a policydb binary representation file.
 */
static int context_read_and_validate(context_struct_t * c,
				     policydb_t * p, struct policy_file *fp)
{
	uint32_t buf[3];
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
	if (rc < 0) {
		ERR(fp->handle, "context truncated");
		return -1;
	}
	c->user = le32_to_cpu(buf[0]);
	c->role = le32_to_cpu(buf[1]);
	c->type = le32_to_cpu(buf[2]);
	if ((p->policy_type == POLICY_KERN
	     && p->policyvers >= POLICYDB_VERSION_MLS)
	    || (p->policy_type == POLICY_BASE
		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS)) {
		if (mls_read_range_helper(&c->range, fp)) {
			ERR(fp->handle, "error reading MLS range "
			    "of context");
			return -1;
		}
	}

	if (!policydb_context_isvalid(p, c)) {
		ERR(fp->handle, "invalid security context");
		context_destroy(c);
		return -1;
	}
	return 0;
}

/*
 * The following *_read functions are used to
 * read the symbol data from a policy database
 * binary representation file.
 */

static int perm_read(policydb_t * p
		     __attribute__ ((unused)), hashtab_t h,
		     struct policy_file *fp, uint32_t nprim)
{
	char *key = 0;
	perm_datum_t *perdatum;
	uint32_t buf[2];
	size_t len;
	int rc;

	perdatum = calloc(1, sizeof(perm_datum_t));
	if (!perdatum)
		return -1;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if(str_read(&key, fp, len))
		goto bad;

	perdatum->s.value = le32_to_cpu(buf[1]);
	if (!value_isvalid(perdatum->s.value, nprim))
		goto bad;

	if (hashtab_insert(h, key, perdatum))
		goto bad;

	return 0;

      bad:
	perm_destroy(key, perdatum, NULL);
	return -1;
}

static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
{
	char *key = 0;
	common_datum_t *comdatum;
	uint32_t buf[4];
	size_t len, nel;
	unsigned int i;
	int rc;

	comdatum = calloc(1, sizeof(common_datum_t));
	if (!comdatum)
		return -1;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		goto bad;

	comdatum->s.value = le32_to_cpu(buf[1]);

	if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE))
		goto bad;
	comdatum->permissions.nprim = le32_to_cpu(buf[2]);
	if (comdatum->permissions.nprim > PERM_SYMTAB_SIZE)
		goto bad;
	nel = le32_to_cpu(buf[3]);

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	for (i = 0; i < nel; i++) {
		if (perm_read(p, comdatum->permissions.table, fp, comdatum->permissions.nprim))
			goto bad;
	}

	if (hashtab_insert(h, key, comdatum))
		goto bad;

	return 0;

      bad:
	common_destroy(key, comdatum, NULL);
	return -1;
}

static int read_cons_helper(policydb_t * p, constraint_node_t ** nodep,
			    unsigned int ncons,
			    int allowxtarget, struct policy_file *fp)
{
	constraint_node_t *c, *lc;
	constraint_expr_t *e, *le;
	uint32_t buf[3];
	size_t nexpr;
	unsigned int i, j;
	int rc, depth;

	lc = NULL;
	for (i = 0; i < ncons; i++) {
		c = calloc(1, sizeof(constraint_node_t));
		if (!c)
			return -1;

		if (lc)
			lc->next = c;
		else
			*nodep = c;

		rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
		if (rc < 0)
			return -1;
		c->permissions = le32_to_cpu(buf[0]);
		nexpr = le32_to_cpu(buf[1]);
		le = NULL;
		depth = -1;
		for (j = 0; j < nexpr; j++) {
			e = malloc(sizeof(constraint_expr_t));
			if (!e)
				return -1;
			if (constraint_expr_init(e) == -1) {
				free(e);
				return -1;
			}
			if (le) {
				le->next = e;
			} else {
				c->expr = e;
			}

			rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
			if (rc < 0)
				return -1;
			e->expr_type = le32_to_cpu(buf[0]);
			e->attr = le32_to_cpu(buf[1]);
			e->op = le32_to_cpu(buf[2]);

			switch (e->expr_type) {
			case CEXPR_NOT:
				if (depth < 0)
					return -1;
				break;
			case CEXPR_AND:
			case CEXPR_OR:
				if (depth < 1)
					return -1;
				depth--;
				break;
			case CEXPR_ATTR:
				if (depth == (CEXPR_MAXDEPTH - 1))
					return -1;
				depth++;
				break;
			case CEXPR_NAMES:
				if (!allowxtarget && (e->attr & CEXPR_XTARGET))
					return -1;
				if (depth == (CEXPR_MAXDEPTH - 1))
					return -1;
				depth++;
				if (ebitmap_read(&e->names, fp))
					return -1;
				if (p->policy_type != POLICY_KERN &&
				    type_set_read(e->type_names, fp))
					return -1;
				else if (p->policy_type == POLICY_KERN &&
					 p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
					 type_set_read(e->type_names, fp))
					return -1;
				break;
			default:
				return -1;
			}
			le = e;
		}
		if (depth != 0)
			return -1;
		lc = c;
	}

	return 0;
}

static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
{
	char *key = 0;
	class_datum_t *cladatum;
	uint32_t buf[6];
	size_t len, len2, ncons, nel;
	unsigned int i;
	int rc;

	cladatum = (class_datum_t *) calloc(1, sizeof(class_datum_t));
	if (!cladatum)
		return -1;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 6);
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		goto bad;
	len2 = le32_to_cpu(buf[1]);
	if (is_saturated(len2))
		goto bad;
	cladatum->s.value = le32_to_cpu(buf[2]);

	if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE))
		goto bad;
	cladatum->permissions.nprim = le32_to_cpu(buf[3]);
	if (cladatum->permissions.nprim > PERM_SYMTAB_SIZE)
		goto bad;
	nel = le32_to_cpu(buf[4]);

	ncons = le32_to_cpu(buf[5]);

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	if (len2) {
		cladatum->comkey = malloc(len2 + 1);
		if (!cladatum->comkey)
			goto bad;
		rc = next_entry(cladatum->comkey, fp, len2);
		if (rc < 0)
			goto bad;
		cladatum->comkey[len2] = 0;

		cladatum->comdatum = hashtab_search(p->p_commons.table,
						    cladatum->comkey);
		if (!cladatum->comdatum) {
			ERR(fp->handle, "unknown common %s", cladatum->comkey);
			goto bad;
		}
	}
	for (i = 0; i < nel; i++) {
		if (perm_read(p, cladatum->permissions.table, fp, cladatum->permissions.nprim))
			goto bad;
	}

	if (read_cons_helper(p, &cladatum->constraints, ncons, 0, fp))
		goto bad;

	if ((p->policy_type == POLICY_KERN
	     && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
	    || (p->policy_type == POLICY_BASE
		&& p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
		/* grab the validatetrans rules */
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			goto bad;
		ncons = le32_to_cpu(buf[0]);
		if (read_cons_helper(p, &cladatum->validatetrans, ncons, 1, fp))
			goto bad;
	}

	if ((p->policy_type == POLICY_KERN &&
	     p->policyvers >= POLICYDB_VERSION_NEW_OBJECT_DEFAULTS) ||
	    (p->policy_type == POLICY_BASE &&
	     p->policyvers >= MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS)) {
		rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
		if (rc < 0)
			goto bad;
		cladatum->default_user = le32_to_cpu(buf[0]);
		cladatum->default_role = le32_to_cpu(buf[1]);
		cladatum->default_range = le32_to_cpu(buf[2]);
	}

	if ((p->policy_type == POLICY_KERN &&
	     p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) ||
	    (p->policy_type == POLICY_BASE &&
	     p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) {
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			goto bad;
		cladatum->default_type = le32_to_cpu(buf[0]);
	}

	if (hashtab_insert(h, key, cladatum))
		goto bad;

	return 0;

      bad:
	class_destroy(key, cladatum, NULL);
	return -1;
}

static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
{
	char *key = 0;
	role_datum_t *role;
	uint32_t buf[3];
	size_t len;
	int rc, to_read = 2;

	role = calloc(1, sizeof(role_datum_t));
	if (!role)
		return -1;

	if (policydb_has_boundary_feature(p))
		to_read = 3;

	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		goto bad;

	role->s.value = le32_to_cpu(buf[1]);
	if (policydb_has_boundary_feature(p))
		role->bounds = le32_to_cpu(buf[2]);

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	if (ebitmap_read(&role->dominates, fp))
		goto bad;

	if (p->policy_type == POLICY_KERN) {
		if (ebitmap_read(&role->types.types, fp))
			goto bad;
	} else {
		if (type_set_read(&role->types, fp))
			goto bad;
	}
	
	if (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) {
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			goto bad;

		role->flavor = le32_to_cpu(buf[0]);

		if (ebitmap_read(&role->roles, fp))
			goto bad;
	}

	if (strcmp(key, OBJECT_R) == 0) {
		if (role->s.value != OBJECT_R_VAL) {
			ERR(fp->handle, "role %s has wrong value %d",
			    OBJECT_R, role->s.value);
			role_destroy(key, role, NULL);
			return -1;
		}
		role_destroy(key, role, NULL);
		return 0;
	}

	if (hashtab_insert(h, key, role))
		goto bad;

	return 0;

      bad:
	role_destroy(key, role, NULL);
	return -1;
}

static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
{
	char *key = 0;
	type_datum_t *typdatum;
	uint32_t buf[5];
	size_t len;
	int rc, to_read;
	int pos = 0;

	typdatum = calloc(1, sizeof(type_datum_t));
	if (!typdatum)
		return -1;

	if (policydb_has_boundary_feature(p)) {
		if (p->policy_type != POLICY_KERN
		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS)
			to_read = 5;
		else
			to_read = 4;
	}
	else if (p->policy_type == POLICY_KERN)
		to_read = 3;
	else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
		to_read = 5;
	else
		to_read = 4;

	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[pos]);
	if (zero_or_saturated(len))
		goto bad;

	typdatum->s.value = le32_to_cpu(buf[++pos]);
	if (policydb_has_boundary_feature(p)) {
		uint32_t properties;

		if (p->policy_type != POLICY_KERN
		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) {
			typdatum->primary = le32_to_cpu(buf[++pos]);
			properties = le32_to_cpu(buf[++pos]);
		}
		else {
			properties = le32_to_cpu(buf[++pos]);

			if (properties & TYPEDATUM_PROPERTY_PRIMARY)
				typdatum->primary = 1;
		}

		if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE)
			typdatum->flavor = TYPE_ATTRIB;
		if (properties & TYPEDATUM_PROPERTY_ALIAS
		    && p->policy_type != POLICY_KERN)
			typdatum->flavor = TYPE_ALIAS;
		if (properties & TYPEDATUM_PROPERTY_PERMISSIVE
		    && p->policy_type != POLICY_KERN)
			typdatum->flags |= TYPE_FLAGS_PERMISSIVE;

		typdatum->bounds = le32_to_cpu(buf[++pos]);
	} else {
		typdatum->primary = le32_to_cpu(buf[++pos]);
		if (p->policy_type != POLICY_KERN) {
			typdatum->flavor = le32_to_cpu(buf[++pos]);
			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
				typdatum->flags = le32_to_cpu(buf[++pos]);
		}
	}

	if (p->policy_type != POLICY_KERN) {
		if (ebitmap_read(&typdatum->types, fp))
			goto bad;
	}

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	if (hashtab_insert(h, key, typdatum))
		goto bad;

	return 0;

      bad:
	type_destroy(key, typdatum, NULL);
	return -1;
}

static int role_trans_read(policydb_t *p, struct policy_file *fp)
{
	role_trans_t **t = &p->role_tr;
	unsigned int i;
	uint32_t buf[3], nel;
	role_trans_t *tr, *ltr;
	int rc;
	int new_roletr = (p->policy_type == POLICY_KERN &&
			  p->policyvers >= POLICYDB_VERSION_ROLETRANS);

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	ltr = NULL;
	for (i = 0; i < nel; i++) {
		tr = calloc(1, sizeof(struct role_trans));
		if (!tr) {
			return -1;
		}
		if (ltr) {
			ltr->next = tr;
		} else {
			*t = tr;
		}
		rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
		if (rc < 0)
			return -1;
		tr->role = le32_to_cpu(buf[0]);
		tr->type = le32_to_cpu(buf[1]);
		tr->new_role = le32_to_cpu(buf[2]);
		if (new_roletr) {
			rc = next_entry(buf, fp, sizeof(uint32_t));
			if (rc < 0)
				return -1;
			tr->tclass = le32_to_cpu(buf[0]);
		} else
			tr->tclass = p->process_class;
		ltr = tr;
	}
	return 0;
}

static int role_allow_read(role_allow_t ** r, struct policy_file *fp)
{
	unsigned int i;
	uint32_t buf[2], nel;
	role_allow_t *ra, *lra;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	lra = NULL;
	for (i = 0; i < nel; i++) {
		ra = calloc(1, sizeof(struct role_allow));
		if (!ra) {
			return -1;
		}
		if (lra) {
			lra->next = ra;
		} else {
			*r = ra;
		}
		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
		if (rc < 0)
			return -1;
		ra->role = le32_to_cpu(buf[0]);
		ra->new_role = le32_to_cpu(buf[1]);
		lra = ra;
	}
	return 0;
}

int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,
			      uint32_t tclass, const char *name,
			      char **name_alloc, uint32_t otype,
			      uint32_t *present_otype)
{
	filename_trans_key_t *ft, key;
	filename_trans_datum_t *datum, *last;

	key.ttype = ttype;
	key.tclass = tclass;
	key.name = (char *)name;

	last = NULL;
	datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key);
	while (datum) {
		if (ebitmap_get_bit(&datum->stypes, stype - 1)) {
			if (present_otype)
				*present_otype = datum->otype;
			return SEPOL_EEXIST;
		}
		if (datum->otype == otype)
			break;
		last = datum;
		datum = datum->next;
	}
	if (!datum) {
		datum = malloc(sizeof(*datum));
		if (!datum)
			return SEPOL_ENOMEM;

		ebitmap_init(&datum->stypes);
		datum->otype = otype;
		datum->next = NULL;

		if (last) {
			last->next = datum;
		} else {
			char *name_dup;

			if (name_alloc) {
				name_dup = *name_alloc;
				*name_alloc = NULL;
			} else {
				name_dup = strdup(name);
				if (!name_dup) {
					free(datum);
					return SEPOL_ENOMEM;
				}
			}

			ft = malloc(sizeof(*ft));
			if (!ft) {
				free(name_dup);
				free(datum);
				return SEPOL_ENOMEM;
			}

			ft->ttype = ttype;
			ft->tclass = tclass;
			ft->name = name_dup;

			if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
					   (hashtab_datum_t)datum)) {
				free(name_dup);
				free(datum);
				free(ft);
				return SEPOL_ENOMEM;
			}
		}
	}

	p->filename_trans_count++;
	return ebitmap_set_bit(&datum->stypes, stype - 1, 1);
}

static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp)
{
	uint32_t buf[4], len, stype, ttype, tclass, otype;
	char *name = NULL;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		return -1;

	name = calloc(len + 1, sizeof(*name));
	if (!name)
		return -1;

	rc = next_entry(name, fp, len);
	if (rc < 0)
		goto err;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
	if (rc < 0)
		goto err;

	stype = le32_to_cpu(buf[0]);
	if (stype == 0)
		goto err;

	ttype  = le32_to_cpu(buf[1]);
	tclass = le32_to_cpu(buf[2]);
	otype  = le32_to_cpu(buf[3]);

	rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name,
				       otype, NULL);
	if (rc) {
		if (rc != SEPOL_EEXIST)
			goto err;
		/*
		 * Some old policies were wrongly generated with
		 * duplicate filename transition rules.  For backward
		 * compatibility, do not reject such policies, just
		 * ignore the duplicate.
		 */
	}
	free(name);
	return 0;
err:
	free(name);
	return -1;
}

static int filename_trans_check_datum(filename_trans_datum_t *datum)
{
	ebitmap_t stypes, otypes;
	int rc = -1;

	ebitmap_init(&stypes);
	ebitmap_init(&otypes);

	while (datum) {
		if (ebitmap_get_bit(&otypes, datum->otype))
			goto out;

		if (ebitmap_set_bit(&otypes, datum->otype, 1))
			goto out;

		if (ebitmap_match_any(&stypes, &datum->stypes))
			goto out;

		if (ebitmap_union(&stypes, &datum->stypes))
			goto out;

		datum = datum->next;
	}
	rc = 0;
out:
	ebitmap_destroy(&stypes);
	ebitmap_destroy(&otypes);
	return rc;
}

static int filename_trans_read_one(policydb_t *p, struct policy_file *fp)
{
	filename_trans_key_t *ft = NULL;
	filename_trans_datum_t **dst, *datum, *first = NULL;
	unsigned int i;
	uint32_t buf[3], len, ttype, tclass, ndatum;
	char *name = NULL;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		return -1;

	name = calloc(len + 1, sizeof(*name));
	if (!name)
		return -1;

	rc = next_entry(name, fp, len);
	if (rc < 0)
		goto err;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
	if (rc < 0)
		goto err;

	ttype = le32_to_cpu(buf[0]);
	tclass = le32_to_cpu(buf[1]);
	ndatum = le32_to_cpu(buf[2]);
	if (ndatum == 0)
		goto err;

	dst = &first;
	for (i = 0; i < ndatum; i++) {
		datum = malloc(sizeof(*datum));
		if (!datum)
			goto err;

		datum->next = NULL;
		*dst = datum;

		/* ebitmap_read() will at least init the bitmap */
		rc = ebitmap_read(&datum->stypes, fp);
		if (rc < 0)
			goto err;

		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			goto err;

		datum->otype = le32_to_cpu(buf[0]);

		p->filename_trans_count += ebitmap_cardinality(&datum->stypes);

		dst = &datum->next;
	}

	if (ndatum > 1 && filename_trans_check_datum(first))
		goto err;

	ft = malloc(sizeof(*ft));
	if (!ft)
		goto err;

	ft->ttype = ttype;
	ft->tclass = tclass;
	ft->name = name;

	rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft,
			    (hashtab_datum_t)first);
	if (rc)
		goto err;

	return 0;
err:
	free(ft);
	free(name);
	while (first) {
		datum = first;
		first = first->next;

		ebitmap_destroy(&datum->stypes);
		free(datum);
	}
	return -1;
}

static int filename_trans_read(policydb_t *p, struct policy_file *fp)
{
	unsigned int i;
	uint32_t buf[1], nel;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);

	if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {
		for (i = 0; i < nel; i++) {
			rc = filename_trans_read_one_compat(p, fp);
			if (rc < 0)
				return -1;
		}
	} else {
		for (i = 0; i < nel; i++) {
			rc = filename_trans_read_one(p, fp);
			if (rc < 0)
				return -1;
		}
	}
	return 0;
}

static int ocontext_read_xen(const struct policydb_compat_info *info,
	policydb_t *p, struct policy_file *fp)
{
	unsigned int i, j;
	size_t nel, len;
	ocontext_t *l, *c;
	uint32_t buf[8];
	int rc;

	for (i = 0; i < info->ocon_num; i++) {
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			return -1;
		nel = le32_to_cpu(buf[0]);
		l = NULL;
		for (j = 0; j < nel; j++) {
			c = calloc(1, sizeof(ocontext_t));
			if (!c)
				return -1;
			if (l)
				l->next = c;
			else
				p->ocontexts[i] = c;
			l = c;
			switch (i) {
			case OCON_XEN_ISID:
				rc = next_entry(buf, fp, sizeof(uint32_t));
				if (rc < 0)
					return -1;
				c->sid[0] = le32_to_cpu(buf[0]);
				if (is_saturated(c->sid[0]))
					return -1;
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_XEN_PIRQ:
				rc = next_entry(buf, fp, sizeof(uint32_t));
				if (rc < 0)
					return -1;
				c->u.pirq = le32_to_cpu(buf[0]);
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_XEN_IOPORT:
				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
				if (rc < 0)
					return -1;
				c->u.ioport.low_ioport = le32_to_cpu(buf[0]);
				c->u.ioport.high_ioport = le32_to_cpu(buf[1]);
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_XEN_IOMEM:
				if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
					uint64_t b64[2];
					rc = next_entry(b64, fp, sizeof(uint64_t) * 2);
					if (rc < 0)
						return -1;
					c->u.iomem.low_iomem = le64_to_cpu(b64[0]);
					c->u.iomem.high_iomem = le64_to_cpu(b64[1]);
				} else {
					rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
					if (rc < 0)
						return -1;
					c->u.iomem.low_iomem = le32_to_cpu(buf[0]);
					c->u.iomem.high_iomem = le32_to_cpu(buf[1]);
				}
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_XEN_PCIDEVICE:
				rc = next_entry(buf, fp, sizeof(uint32_t));
				if (rc < 0)
					return -1;
				c->u.device = le32_to_cpu(buf[0]);
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_XEN_DEVICETREE:
				rc = next_entry(buf, fp, sizeof(uint32_t));
				if (rc < 0)
					return -1;
				len = le32_to_cpu(buf[0]);
				if (zero_or_saturated(len))
					return -1;

				c->u.name = malloc(len + 1);
				if (!c->u.name)
					return -1;
				rc = next_entry(c->u.name, fp, len);
				if (rc < 0)
					return -1;
				c->u.name[len] = 0;
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			default:
				/* should never get here */
				ERR(fp->handle, "Unknown Xen ocontext");
				return -1;
			}
		}
	}
	return 0;
}
static int ocontext_read_selinux(const struct policydb_compat_info *info,
			 policydb_t * p, struct policy_file *fp)
{
	unsigned int i, j;
	size_t nel, len;
	ocontext_t *l, *c;
	uint32_t buf[8];
	int rc;

	for (i = 0; i < info->ocon_num; i++) {
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			return -1;
		nel = le32_to_cpu(buf[0]);
		l = NULL;
		for (j = 0; j < nel; j++) {
			c = calloc(1, sizeof(ocontext_t));
			if (!c) {
				return -1;
			}
			if (l) {
				l->next = c;
			} else {
				p->ocontexts[i] = c;
			}
			l = c;
			switch (i) {
			case OCON_ISID:
				rc = next_entry(buf, fp, sizeof(uint32_t));
				if (rc < 0)
					return -1;
				c->sid[0] = le32_to_cpu(buf[0]);
				if (is_saturated(c->sid[0]))
					return -1;
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_FS:
			case OCON_NETIF:
				rc = next_entry(buf, fp, sizeof(uint32_t));
				if (rc < 0)
					return -1;
				len = le32_to_cpu(buf[0]);
				if (zero_or_saturated(len) || len > 63)
					return -1;
				c->u.name = malloc(len + 1);
				if (!c->u.name)
					return -1;
				rc = next_entry(c->u.name, fp, len);
				if (rc < 0)
					return -1;
				c->u.name[len] = 0;
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				if (context_read_and_validate
				    (&c->context[1], p, fp))
					return -1;
				break;
			case OCON_IBPKEY: {
				uint32_t pkey_lo, pkey_hi;

				rc = next_entry(buf, fp, sizeof(uint32_t) * 4);
				if (rc < 0)
					return -1;

				pkey_lo = le32_to_cpu(buf[2]);
				pkey_hi = le32_to_cpu(buf[3]);

				if (pkey_lo > UINT16_MAX || pkey_hi > UINT16_MAX)
					return -1;

				c->u.ibpkey.low_pkey  = pkey_lo;
				c->u.ibpkey.high_pkey = pkey_hi;

				/* we want c->u.ibpkey.subnet_prefix in network
				 * (big-endian) order, just memcpy it */
				memcpy(&c->u.ibpkey.subnet_prefix, buf,
				       sizeof(c->u.ibpkey.subnet_prefix));

				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			}
			case OCON_IBENDPORT: {
				uint32_t port;

				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
				if (rc < 0)
					return -1;
				len = le32_to_cpu(buf[0]);
				if (len == 0 || len > IB_DEVICE_NAME_MAX - 1)
					return -1;

				port = le32_to_cpu(buf[1]);
				if (port > UINT8_MAX || port == 0)
					return -1;

				c->u.ibendport.dev_name = malloc(len + 1);
				if (!c->u.ibendport.dev_name)
					return -1;
				rc = next_entry(c->u.ibendport.dev_name, fp, len);
				if (rc < 0)
					return -1;
				c->u.ibendport.dev_name[len] = 0;
				c->u.ibendport.port = port;
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			}
			case OCON_PORT:
				rc = next_entry(buf, fp, sizeof(uint32_t) * 3);
				if (rc < 0)
					return -1;
				c->u.port.protocol = le32_to_cpu(buf[0]);
				c->u.port.low_port = le32_to_cpu(buf[1]);
				c->u.port.high_port = le32_to_cpu(buf[2]);
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_NODE:
				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
				if (rc < 0)
					return -1;
				c->u.node.addr = buf[0]; /* network order */
				c->u.node.mask = buf[1]; /* network order */
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_FSUSE:
				rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
				if (rc < 0)
					return -1;
				c->v.behavior = le32_to_cpu(buf[0]);
				len = le32_to_cpu(buf[1]);
				if (zero_or_saturated(len))
					return -1;
				c->u.name = malloc(len + 1);
				if (!c->u.name)
					return -1;
				rc = next_entry(c->u.name, fp, len);
				if (rc < 0)
					return -1;
				c->u.name[len] = 0;
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
			case OCON_NODE6:{
				int k;

				rc = next_entry(buf, fp, sizeof(uint32_t) * 8);
				if (rc < 0)
					return -1;
				for (k = 0; k < 4; k++)
					 /* network order */
					c->u.node6.addr[k] = buf[k];
				for (k = 0; k < 4; k++)
					/* network order */
					c->u.node6.mask[k] = buf[k + 4];
				if (context_read_and_validate
				    (&c->context[0], p, fp))
					return -1;
				break;
				}
			default:{
				ERR(fp->handle, "Unknown SELinux ocontext");
				return -1;
				}
			}
		}
	}
	return 0;
}

static int ocontext_read(const struct policydb_compat_info *info,
	policydb_t *p, struct policy_file *fp)
{
	int rc = -1;
	switch (p->target_platform) {
	case SEPOL_TARGET_SELINUX:
		rc = ocontext_read_selinux(info, p, fp);
		break;
	case SEPOL_TARGET_XEN:
		rc = ocontext_read_xen(info, p, fp);
		break;
	default:
		ERR(fp->handle, "Unknown target");
	}
	return rc;
}

static int genfs_read(policydb_t * p, struct policy_file *fp)
{
	uint32_t buf[1];
	size_t nel, nel2, len, len2;
	genfs_t *genfs_p, *newgenfs, *genfs;
	size_t i, j;
	ocontext_t *l, *c, *newc = NULL;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		goto bad;
	nel = le32_to_cpu(buf[0]);
	genfs_p = NULL;
	for (i = 0; i < nel; i++) {
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			goto bad;
		len = le32_to_cpu(buf[0]);
		if (zero_or_saturated(len))
			goto bad;
		newgenfs = calloc(1, sizeof(genfs_t));
		if (!newgenfs)
			goto bad;
		newgenfs->fstype = malloc(len + 1);
		if (!newgenfs->fstype) {
			free(newgenfs);
			goto bad;
		}
		rc = next_entry(newgenfs->fstype, fp, len);
		if (rc < 0) {
			free(newgenfs->fstype);
			free(newgenfs);
			goto bad;
		}
		newgenfs->fstype[len] = 0;
		for (genfs_p = NULL, genfs = p->genfs; genfs;
		     genfs_p = genfs, genfs = genfs->next) {
			if (strcmp(newgenfs->fstype, genfs->fstype) == 0) {
				ERR(fp->handle, "dup genfs fstype %s",
				    newgenfs->fstype);
				free(newgenfs->fstype);
				free(newgenfs);
				goto bad;
			}
			if (strcmp(newgenfs->fstype, genfs->fstype) < 0)
				break;
		}
		newgenfs->next = genfs;
		if (genfs_p)
			genfs_p->next = newgenfs;
		else
			p->genfs = newgenfs;
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			goto bad;
		nel2 = le32_to_cpu(buf[0]);
		for (j = 0; j < nel2; j++) {
			newc = calloc(1, sizeof(ocontext_t));
			if (!newc) {
				goto bad;
			}
			rc = next_entry(buf, fp, sizeof(uint32_t));
			if (rc < 0)
				goto bad;
			len = le32_to_cpu(buf[0]);
			if (zero_or_saturated(len))
				goto bad;
			newc->u.name = malloc(len + 1);
			if (!newc->u.name) {
				goto bad;
			}
			rc = next_entry(newc->u.name, fp, len);
			if (rc < 0)
				goto bad;
			newc->u.name[len] = 0;
			rc = next_entry(buf, fp, sizeof(uint32_t));
			if (rc < 0)
				goto bad;
			newc->v.sclass = le32_to_cpu(buf[0]);
			if (context_read_and_validate(&newc->context[0], p, fp))
				goto bad;
			for (l = NULL, c = newgenfs->head; c;
			     l = c, c = c->next) {
				if (!strcmp(newc->u.name, c->u.name) &&
				    (!c->v.sclass || !newc->v.sclass ||
				     newc->v.sclass == c->v.sclass)) {
					ERR(fp->handle, "dup genfs entry "
					    "(%s,%s)", newgenfs->fstype,
					    c->u.name);
					goto bad;
				}
				len = strlen(newc->u.name);
				len2 = strlen(c->u.name);
				if (len > len2)
					break;
			}
			newc->next = c;
			if (l)
				l->next = newc;
			else
				newgenfs->head = newc;
			/* clear newc after a new owner has the pointer */
			newc = NULL;
		}
	}

	return 0;

      bad:
	if (newc) {
		context_destroy(&newc->context[0]);
		context_destroy(&newc->context[1]);
		free(newc->u.name);
		free(newc);
	}
	return -1;
}

/*
 * Read a MLS level structure from a policydb binary 
 * representation file.
 */
static int mls_read_level(mls_level_t * lp, struct policy_file *fp)
{
	uint32_t buf[1];
	int rc;

	mls_level_init(lp);

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0) {
		ERR(fp->handle, "truncated level");
		goto bad;
	}
	lp->sens = le32_to_cpu(buf[0]);

	if (ebitmap_read(&lp->cat, fp)) {
		ERR(fp->handle, "error reading level categories");
		goto bad;
	}
	return 0;

      bad:
	return -EINVAL;
}

static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp)
{
	char *key = 0;
	user_datum_t *usrdatum;
	uint32_t buf[3];
	size_t len;
	int rc, to_read = 2;

	usrdatum = calloc(1, sizeof(user_datum_t));
	if (!usrdatum)
		return -1;

	if (policydb_has_boundary_feature(p))
		to_read = 3;

	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		goto bad;

	usrdatum->s.value = le32_to_cpu(buf[1]);
	if (policydb_has_boundary_feature(p))
		usrdatum->bounds = le32_to_cpu(buf[2]);

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	if (p->policy_type == POLICY_KERN) {
		if (ebitmap_read(&usrdatum->roles.roles, fp))
			goto bad;
	} else {
		if (role_set_read(&usrdatum->roles, fp))
			goto bad;
	}

	/* users were not allowed in mls modules before version
	 * MOD_POLICYDB_VERSION_MLS_USERS, but they could have been
	 * required - the mls fields will be empty.  user declarations in
	 * non-mls modules will also have empty mls fields */
	if ((p->policy_type == POLICY_KERN
	     && p->policyvers >= POLICYDB_VERSION_MLS)
	    || (p->policy_type == POLICY_MOD
		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)
	    || (p->policy_type == POLICY_BASE
		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS)) {
		if (mls_read_range_helper(&usrdatum->exp_range, fp))
			goto bad;
		if (mls_read_level(&usrdatum->exp_dfltlevel, fp))
			goto bad;
		if (p->policy_type != POLICY_KERN) {
			if (mls_range_to_semantic(&usrdatum->exp_range,
						  &usrdatum->range))
				goto bad;
			if (mls_level_to_semantic(&usrdatum->exp_dfltlevel,
						  &usrdatum->dfltlevel))
				goto bad;
		}
	} else if ((p->policy_type == POLICY_MOD
		    && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)
		   || (p->policy_type == POLICY_BASE
		       && p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS)) {
		if (mls_read_semantic_range_helper(&usrdatum->range, fp))
			goto bad;
		if (mls_read_semantic_level_helper(&usrdatum->dfltlevel, fp))
			goto bad;
	}

	if (hashtab_insert(h, key, usrdatum))
		goto bad;

	return 0;

      bad:
	user_destroy(key, usrdatum, NULL);
	return -1;
}

static int sens_read(policydb_t * p
		     __attribute__ ((unused)), hashtab_t h,
		     struct policy_file *fp)
{
	char *key = 0;
	level_datum_t *levdatum;
	uint32_t buf[2], len;
	int rc;

	levdatum = malloc(sizeof(level_datum_t));
	if (!levdatum)
		return -1;
	level_datum_init(levdatum);

	rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(len))
		goto bad;

	levdatum->isalias = le32_to_cpu(buf[1]);

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	levdatum->level = malloc(sizeof(mls_level_t));
	if (!levdatum->level || mls_read_level(levdatum->level, fp))
		goto bad;

	if (hashtab_insert(h, key, levdatum))
		goto bad;

	return 0;

      bad:
	sens_destroy(key, levdatum, NULL);
	return -1;
}

static int cat_read(policydb_t * p
		    __attribute__ ((unused)), hashtab_t h,
		    struct policy_file *fp)
{
	char *key = 0;
	cat_datum_t *catdatum;
	uint32_t buf[3], len;
	int rc;

	catdatum = malloc(sizeof(cat_datum_t));
	if (!catdatum)
		return -1;
	cat_datum_init(catdatum);

	rc = next_entry(buf, fp, (sizeof(uint32_t) * 3));
	if (rc < 0)
		goto bad;

	len = le32_to_cpu(buf[0]);
	if(zero_or_saturated(len))
		goto bad;

	catdatum->s.value = le32_to_cpu(buf[1]);
	catdatum->isalias = le32_to_cpu(buf[2]);

	key = malloc(len + 1);
	if (!key)
		goto bad;
	rc = next_entry(key, fp, len);
	if (rc < 0)
		goto bad;
	key[len] = 0;

	if (hashtab_insert(h, key, catdatum))
		goto bad;

	return 0;

      bad:
	cat_destroy(key, catdatum, NULL);
	return -1;
}

static int (*read_f[SYM_NUM]) (policydb_t * p, hashtab_t h,
			       struct policy_file * fp) = {
common_read, class_read, role_read, type_read, user_read,
	    cond_read_bool, sens_read, cat_read,};

/************** module reading functions below **************/

static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp)
{
	unsigned int i;
	uint32_t buf[2], len;
	class_perm_node_t *cur, *tail = NULL;
	avrule_t *avrule;
	int rc;

	avrule = (avrule_t *) malloc(sizeof(avrule_t));
	if (!avrule)
		return NULL;

	avrule_init(avrule);

	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
	if (rc < 0)
		goto bad;

	avrule->specified = le32_to_cpu(buf[0]);
	avrule->flags = le32_to_cpu(buf[1]);

	if (type_set_read(&avrule->stypes, fp))
		goto bad;

	if (type_set_read(&avrule->ttypes, fp))
		goto bad;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		goto bad;
	len = le32_to_cpu(buf[0]);

	for (i = 0; i < len; i++) {
		cur = (class_perm_node_t *) malloc(sizeof(class_perm_node_t));
		if (!cur)
			goto bad;
		class_perm_node_init(cur);

		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
		if (rc < 0) {
			free(cur);
			goto bad;
		}

		cur->tclass = le32_to_cpu(buf[0]);
		cur->data = le32_to_cpu(buf[1]);

		if (!tail) {
			avrule->perms = cur;
		} else {
			tail->next = cur;
		}
		tail = cur;
	}

	if (avrule->specified & AVRULE_XPERMS) {
		uint8_t buf8;
		size_t nel = ARRAY_SIZE(avrule->xperms->perms);
		uint32_t buf32[nel];

		if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) {
			ERR(fp->handle,
			    "module policy version %u does not support ioctl"
			    " extended permissions rules and one was specified",
			    p->policyvers);
			goto bad;
		}

		if (p->target_platform != SEPOL_TARGET_SELINUX) {
			ERR(fp->handle,
			    "Target platform %s does not support ioctl"
			    " extended permissions rules and one was specified",
			    policydb_target_strings[p->target_platform]);
			goto bad;
		}

		avrule->xperms = calloc(1, sizeof(*avrule->xperms));
		if (!avrule->xperms)
			goto bad;

		rc = next_entry(&buf8, fp, sizeof(uint8_t));
		if (rc < 0) {
			ERR(fp->handle, "truncated entry");
			goto bad;
		}
		avrule->xperms->specified = buf8;
		rc = next_entry(&buf8, fp, sizeof(uint8_t));
		if (rc < 0) {
			ERR(fp->handle, "truncated entry");
			goto bad;
		}
		avrule->xperms->driver = buf8;
		rc = next_entry(buf32, fp, sizeof(uint32_t)*nel);
		if (rc < 0) {
			ERR(fp->handle, "truncated entry");
			goto bad;
		}
		for (i = 0; i < nel; i++)
			avrule->xperms->perms[i] = le32_to_cpu(buf32[i]);
	}

	return avrule;
      bad:
	if (avrule) {
		avrule_destroy(avrule);
		free(avrule);
	}
	return NULL;
}

static int range_read(policydb_t * p, struct policy_file *fp)
{
	uint32_t buf[2], nel;
	range_trans_t *rt = NULL;
	struct mls_range *r = NULL;
	range_trans_rule_t *rtr = NULL, *lrtr = NULL;
	unsigned int i;
	int new_rangetr = (p->policy_type == POLICY_KERN &&
			   p->policyvers >= POLICYDB_VERSION_RANGETRANS);
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	for (i = 0; i < nel; i++) {
		rt = calloc(1, sizeof(range_trans_t));
		if (!rt)
			return -1;
		rc = next_entry(buf, fp, (sizeof(uint32_t) * 2));
		if (rc < 0)
			goto err;
		rt->source_type = le32_to_cpu(buf[0]);
		if (!value_isvalid(rt->source_type, p->p_types.nprim))
			goto err;
		rt->target_type = le32_to_cpu(buf[1]);
		if (!value_isvalid(rt->target_type, p->p_types.nprim))
			goto err;
		if (new_rangetr) {
			rc = next_entry(buf, fp, (sizeof(uint32_t)));
			if (rc < 0)
				goto err;
			rt->target_class = le32_to_cpu(buf[0]);
			if (!value_isvalid(rt->target_class, p->p_classes.nprim))
				goto err;
		} else
			rt->target_class = p->process_class;
		r = calloc(1, sizeof(*r));
		if (!r)
			goto err;
		if (mls_read_range_helper(r, fp))
			goto err;

		if (p->policy_type == POLICY_KERN) {
			rc = hashtab_insert(p->range_tr, (hashtab_key_t)rt, r);
			if (rc)
				goto err;
			rt = NULL;
			r = NULL;
			continue;
		}

		/* Module policy: convert to range_trans_rule and discard. */
		rtr = malloc(sizeof(range_trans_rule_t));
		if (!rtr)
			goto err;
		range_trans_rule_init(rtr);

		if (ebitmap_set_bit(&rtr->stypes.types, rt->source_type - 1, 1))
			goto err;

		if (ebitmap_set_bit(&rtr->ttypes.types, rt->target_type - 1, 1))
			goto err;

		if (ebitmap_set_bit(&rtr->tclasses, rt->target_class - 1, 1))
			goto err;

		if (mls_range_to_semantic(r, &rtr->trange))
			goto err;

		if (lrtr)
			lrtr->next = rtr;
		else
			p->global->enabled->range_tr_rules = rtr;

		free(rt);
		rt = NULL;
		free(r);
		r = NULL;
		lrtr = rtr;
	}

	return 0;
err:
	free(rt);
	if (r) {
		mls_range_destroy(r);
		free(r);
	}
	if (rtr) {
		range_trans_rule_destroy(rtr);
		free(rtr);
	}
	return -1;
}

int avrule_read_list(policydb_t * p, avrule_t ** avrules,
		     struct policy_file *fp)
{
	unsigned int i;
	avrule_t *cur, *tail;
	uint32_t buf[1], len;
	int rc;

	*avrules = tail = NULL;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0) {
		return -1;
	}
	len = le32_to_cpu(buf[0]);

	for (i = 0; i < len; i++) {
		cur = avrule_read(p, fp);
		if (!cur) {
			return -1;
		}

		if (!tail) {
			*avrules = cur;
		} else {
			tail->next = cur;
		}
		tail = cur;
	}

	return 0;
}

static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r,
				struct policy_file *fp)
{
	uint32_t buf[1], nel;
	unsigned int i;
	role_trans_rule_t *tr, *ltr;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	ltr = NULL;
	for (i = 0; i < nel; i++) {
		tr = malloc(sizeof(role_trans_rule_t));
		if (!tr) {
			return -1;
		}
		role_trans_rule_init(tr);

		if (ltr) {
			ltr->next = tr;
		} else {
			*r = tr;
		}

		if (role_set_read(&tr->roles, fp))
			return -1;

		if (type_set_read(&tr->types, fp))
			return -1;

		if (p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS) {
			if (ebitmap_read(&tr->classes, fp))
				return -1;
		} else {
			if (!p->process_class)
				return -1;
			if (ebitmap_set_bit(&tr->classes, p->process_class - 1, 1))
				return -1;
		}

		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			return -1;
		tr->new_role = le32_to_cpu(buf[0]);
		ltr = tr;
	}

	return 0;
}

static int role_allow_rule_read(role_allow_rule_t ** r, struct policy_file *fp)
{
	unsigned int i;
	uint32_t buf[1], nel;
	role_allow_rule_t *ra, *lra;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	lra = NULL;
	for (i = 0; i < nel; i++) {
		ra = malloc(sizeof(role_allow_rule_t));
		if (!ra) {
			return -1;
		}
		role_allow_rule_init(ra);

		if (lra) {
			lra->next = ra;
		} else {
			*r = ra;
		}

		if (role_set_read(&ra->roles, fp))
			return -1;

		if (role_set_read(&ra->new_roles, fp))
			return -1;

		lra = ra;
	}
	return 0;
}

static int filename_trans_rule_read(policydb_t *p, filename_trans_rule_t **r,
				    struct policy_file *fp)
{
	uint32_t buf[3], nel, i, len;
	unsigned int entries;
	filename_trans_rule_t *ftr, *lftr;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	lftr = NULL;
	for (i = 0; i < nel; i++) {
		ftr = malloc(sizeof(*ftr));
		if (!ftr)
			return -1;

		filename_trans_rule_init(ftr);

		if (lftr)
			lftr->next = ftr;
		else
			*r = ftr;
		lftr = ftr;

		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0)
			return -1;

		len = le32_to_cpu(buf[0]);
		if (zero_or_saturated(len))
			return -1;

		ftr->name = malloc(len + 1);
		if (!ftr->name)
			return -1;

		rc = next_entry(ftr->name, fp, len);
		if (rc)
			return -1;
		ftr->name[len] = 0;

		if (type_set_read(&ftr->stypes, fp))
			return -1;

		if (type_set_read(&ftr->ttypes, fp))
			return -1;

		if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS)
			entries = 3;
		else
			entries = 2;

		rc = next_entry(buf, fp, sizeof(uint32_t) * entries);
		if (rc < 0)
			return -1;
		ftr->tclass = le32_to_cpu(buf[0]);
		ftr->otype = le32_to_cpu(buf[1]);
		if (p->policyvers >= MOD_POLICYDB_VERSION_SELF_TYPETRANS)
			ftr->flags = le32_to_cpu(buf[2]);
	}

	return 0;
}

static int range_trans_rule_read(range_trans_rule_t ** r,
				 struct policy_file *fp)
{
	uint32_t buf[1], nel;
	unsigned int i;
	range_trans_rule_t *rt, *lrt = NULL;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	nel = le32_to_cpu(buf[0]);
	for (i = 0; i < nel; i++) {
		rt = malloc(sizeof(range_trans_rule_t));
		if (!rt) {
			return -1;
		}
		range_trans_rule_init(rt);

		if (lrt)
			lrt->next = rt;
		else
			*r = rt;

		if (type_set_read(&rt->stypes, fp))
			return -1;

		if (type_set_read(&rt->ttypes, fp))
			return -1;

		if (ebitmap_read(&rt->tclasses, fp))
			return -1;

		if (mls_read_semantic_range_helper(&rt->trange, fp))
			return -1;

		lrt = rt;
	}

	return 0;
}

static int scope_index_read(scope_index_t * scope_index,
			    unsigned int num_scope_syms, struct policy_file *fp)
{
	unsigned int i;
	uint32_t buf[1];
	int rc;

	for (i = 0; i < num_scope_syms; i++) {
		if (ebitmap_read(scope_index->scope + i, fp) < 0) {
			return -1;
		}
	}
	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	scope_index->class_perms_len = le32_to_cpu(buf[0]);
	if (is_saturated(scope_index->class_perms_len))
		return -1;
	if (scope_index->class_perms_len == 0) {
		scope_index->class_perms_map = NULL;
		return 0;
	}
	if ((scope_index->class_perms_map =
	     calloc(scope_index->class_perms_len,
		    sizeof(*scope_index->class_perms_map))) == NULL) {
		return -1;
	}
	for (i = 0; i < scope_index->class_perms_len; i++) {
		if (ebitmap_read(scope_index->class_perms_map + i, fp) < 0) {
			return -1;
		}
	}
	return 0;
}

static int avrule_decl_read(policydb_t * p, avrule_decl_t * decl,
			    unsigned int num_scope_syms, struct policy_file *fp)
{
	uint32_t buf[2], nprim, nel;
	unsigned int i, j;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
	if (rc < 0)
		return -1;
	decl->decl_id = le32_to_cpu(buf[0]);
	decl->enabled = le32_to_cpu(buf[1]);
	if (cond_read_list(p, &decl->cond_list, fp) == -1 ||
	    avrule_read_list(p, &decl->avrules, fp) == -1 ||
	    role_trans_rule_read(p, &decl->role_tr_rules, fp) == -1 ||
	    role_allow_rule_read(&decl->role_allow_rules, fp) == -1) {
		return -1;
	}

	if (p->policyvers >= MOD_POLICYDB_VERSION_FILENAME_TRANS &&
	    filename_trans_rule_read(p, &decl->filename_trans_rules, fp))
		return -1;

	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
	    range_trans_rule_read(&decl->range_tr_rules, fp) == -1) {
		return -1;
	}
	if (scope_index_read(&decl->required, num_scope_syms, fp) == -1 ||
	    scope_index_read(&decl->declared, num_scope_syms, fp) == -1) {
		return -1;
	}

	for (i = 0; i < num_scope_syms; i++) {
		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
		if (rc < 0) 
			return -1;
		nprim = le32_to_cpu(buf[0]);
		if (is_saturated(nprim))
			return -1;
		nel = le32_to_cpu(buf[1]);
		for (j = 0; j < nel; j++) {
			if (read_f[i] (p, decl->symtab[i].table, fp)) {
				return -1;
			}
		}
		decl->symtab[i].nprim = nprim;
	}
	return 0;
}

static int avrule_block_read(policydb_t * p,
			     avrule_block_t ** block,
			     unsigned int num_scope_syms,
			     struct policy_file *fp)
{
	avrule_block_t *last_block = NULL, *curblock;
	uint32_t buf[1], num_blocks, nel;
	int rc;

	assert(*block == NULL);

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		return -1;
	num_blocks = le32_to_cpu(buf[0]);
	nel = num_blocks;
	while (num_blocks > 0) {
		avrule_decl_t *last_decl = NULL, *curdecl;
		uint32_t num_decls;
		if ((curblock = calloc(1, sizeof(*curblock))) == NULL) {
			return -1;
		}
		rc = next_entry(buf, fp, sizeof(uint32_t));
		if (rc < 0) {
			free(curblock);
			return -1;
		}
		/* if this is the first block its non-optional, else its optional */
		if (num_blocks != nel)
			curblock->flags |= AVRULE_OPTIONAL;

		num_decls = le32_to_cpu(buf[0]);
		while (num_decls > 0) {
			if ((curdecl = avrule_decl_create(0)) == NULL) {
				avrule_block_destroy(curblock);
				return -1;
			}
			if (avrule_decl_read(p, curdecl, num_scope_syms, fp) ==
			    -1) {
				avrule_decl_destroy(curdecl);
				avrule_block_destroy(curblock);
				return -1;
			}
			if (curdecl->enabled) {
				if (curblock->enabled != NULL) {
					/* probably a corrupt file */
					avrule_decl_destroy(curdecl);
					avrule_block_destroy(curblock);
					return -1;
				}
				curblock->enabled = curdecl;
			}
			/* one must be careful to reconstruct the
			 * decl chain in its correct order */
			if (curblock->branch_list == NULL) {
				curblock->branch_list = curdecl;
			} else {
				assert(last_decl);
				last_decl->next = curdecl;
			}
			last_decl = curdecl;
			num_decls--;
		}

		if (*block == NULL) {
			*block = curblock;
		} else {
			assert(last_block);
			last_block->next = curblock;
		}
		last_block = curblock;

		num_blocks--;
	}

	return 0;
}

static int scope_read(policydb_t * p, int symnum, struct policy_file *fp)
{
	scope_datum_t *scope = NULL;
	uint32_t buf[2];
	char *key = NULL;
	size_t key_len;
	unsigned int i;
	hashtab_t h = p->scope[symnum].table;
	int rc;

	rc = next_entry(buf, fp, sizeof(uint32_t));
	if (rc < 0)
		goto cleanup;
	key_len = le32_to_cpu(buf[0]);
	if (zero_or_saturated(key_len))
		goto cleanup;
	key = malloc(key_len + 1);
	if (!key)
		goto cleanup;
	rc = next_entry(key, fp, key_len);
	if (rc < 0)
		goto cleanup;
	key[key_len] = '\0';

	/* ensure that there already exists a symbol with this key */
	if (hashtab_search(p->symtab[symnum].table, key) == NULL) {
		goto cleanup;
	}

	if ((scope = calloc(1, sizeof(*scope))) == NULL) {
		goto cleanup;
	}
	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
	if (rc < 0)
		goto cleanup;
	scope->scope = le32_to_cpu(buf[0]);
	scope->decl_ids_len = le32_to_cpu(buf[1]);
	if (zero_or_saturated(scope->decl_ids_len)) {
		ERR(fp->handle, "invalid scope with no declaration");
		goto cleanup;
	}
	if ((scope->decl_ids =
	     calloc(scope->decl_ids_len, sizeof(uint32_t))) == NULL) {
		goto cleanup;
	}
	rc = next_entry(scope->decl_ids, fp, sizeof(uint32_t) * scope->decl_ids_len);
	if (rc < 0)
		goto cleanup;
	for (i = 0; i < scope->decl_ids_len; i++) {
		scope->decl_ids[i] = le32_to_cpu(scope->decl_ids[i]);
	}

	if (strcmp(key, "object_r") == 0 && h == p->p_roles_scope.table) {
		/* object_r was already added to this table in roles_init() */
		scope_destroy(key, scope, NULL);
	} else {
		if (hashtab_insert(h, key, scope)) {
			goto cleanup;
		}
	}

	return 0;

      cleanup:
	scope_destroy(key, scope, NULL);
	return -1;
}

static sepol_security_class_t policydb_string_to_security_class(
	struct policydb *policydb,
	const char *class_name)
{
	class_datum_t *tclass_datum;

	tclass_datum = hashtab_search(policydb->p_classes.table,
				      class_name);
	if (!tclass_datum)
		return 0;
	return tclass_datum->s.value;
}

static sepol_access_vector_t policydb_string_to_av_perm(
	struct policydb *policydb,
	sepol_security_class_t tclass,
	const char *perm_name)
{
	class_datum_t *tclass_datum;
	perm_datum_t *perm_datum;

	if (!tclass || tclass > policydb->p_classes.nprim)
		return 0;
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	perm_datum = (perm_datum_t *)
			hashtab_search(tclass_datum->permissions.table,
			perm_name);
	if (perm_datum != NULL)
		return UINT32_C(1) << (perm_datum->s.value - 1);

	if (tclass_datum->comdatum == NULL)
		return 0;

	perm_datum = (perm_datum_t *)
			hashtab_search(tclass_datum->comdatum->permissions.table,
			perm_name);

	if (perm_datum != NULL)
		return UINT32_C(1) << (perm_datum->s.value - 1);

	return 0;
}


/*
 * Read the configuration data from a policy database binary
 * representation file into a policy database structure.
 */
int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose)
{

	unsigned int i, j, r_policyvers;
	uint32_t buf[5];
	size_t len, nprim, nel;
	char *policydb_str;
	const struct policydb_compat_info *info;
	unsigned int policy_type, bufindex;
	ebitmap_node_t *tnode;
	int rc;

	/* Read the magic number and string length. */
	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
	if (rc < 0)
		return POLICYDB_ERROR;
	for (i = 0; i < 2; i++)
		buf[i] = le32_to_cpu(buf[i]);

	if (buf[0] == POLICYDB_MAGIC) {
		policy_type = POLICY_KERN;
	} else if (buf[0] == POLICYDB_MOD_MAGIC) {
		policy_type = POLICY_MOD;
	} else {
		ERR(fp->handle, "policydb magic number %#08x does not "
		    "match expected magic number %#08x or %#08x",
		    buf[0], POLICYDB_MAGIC, POLICYDB_MOD_MAGIC);
		return POLICYDB_ERROR;
	}

	len = buf[1];
	if (len == 0 || len > POLICYDB_STRING_MAX_LENGTH) {
		ERR(fp->handle, "policydb string length %s ", len ? "too long" : "zero");
		return POLICYDB_ERROR;
	}

	policydb_str = malloc(len + 1);
	if (!policydb_str) {
		ERR(fp->handle, "unable to allocate memory for policydb "
		    "string of length %zu", len);
		return POLICYDB_ERROR;
	}
	rc = next_entry(policydb_str, fp, len);
	if (rc < 0) {
		ERR(fp->handle, "truncated policydb string identifier");
		free(policydb_str);
		return POLICYDB_ERROR;
	}
	policydb_str[len] = 0;

	if (policy_type == POLICY_KERN) {
		for (i = 0; i < POLICYDB_TARGET_SZ; i++) {
			if ((strcmp(policydb_str, policydb_target_strings[i])
				== 0)) {
				policydb_set_target_platform(p, i);
				break;
			}
		}

		if (i == POLICYDB_TARGET_SZ) {
			ERR(fp->handle, "cannot find a valid target for policy "
				"string %s", policydb_str);
			free(policydb_str);
			return POLICYDB_ERROR;
		}
	} else {
		if (strcmp(policydb_str, POLICYDB_MOD_STRING)) {
			ERR(fp->handle, "invalid string identifier %s",
				policydb_str);
			free(policydb_str);
			return POLICYDB_ERROR;
		}
	}

	/* Done with policydb_str. */
	free(policydb_str);
	policydb_str = NULL;

	/* Read the version, config, and table sizes (and policy type if it's a module). */
	if (policy_type == POLICY_KERN)
		nel = 4;
	else
		nel = 5;

	rc = next_entry(buf, fp, sizeof(uint32_t) * nel);
	if (rc < 0)
		return POLICYDB_ERROR;
	for (i = 0; i < nel; i++)
		buf[i] = le32_to_cpu(buf[i]);

	bufindex = 0;

	if (policy_type == POLICY_MOD) {
		/* We know it's a module but not whether it's a base
		   module or regular binary policy module.  buf[0]
		   tells us which. */
		policy_type = buf[bufindex];
		if (policy_type != POLICY_MOD && policy_type != POLICY_BASE) {
			ERR(fp->handle, "unknown module type: %#08x",
			    policy_type);
			return POLICYDB_ERROR;
		}
		bufindex++;
	}

	r_policyvers = buf[bufindex];
	if (policy_type == POLICY_KERN) {
		if (r_policyvers < POLICYDB_VERSION_MIN ||
		    r_policyvers > POLICYDB_VERSION_MAX) {
			ERR(fp->handle, "policydb version %d does not match "
			    "my version range %d-%d", buf[bufindex],
			    POLICYDB_VERSION_MIN, POLICYDB_VERSION_MAX);
			return POLICYDB_ERROR;
		}
	} else if (policy_type == POLICY_BASE || policy_type == POLICY_MOD) {
		if (r_policyvers < MOD_POLICYDB_VERSION_MIN ||
		    r_policyvers > MOD_POLICYDB_VERSION_MAX) {
			ERR(fp->handle, "policydb module version %d does "
			    "not match my version range %d-%d",
			    buf[bufindex], MOD_POLICYDB_VERSION_MIN,
			    MOD_POLICYDB_VERSION_MAX);
			return POLICYDB_ERROR;
		}
	} else {
		assert(0);
	}
	bufindex++;

	/* Set the policy type and version from the read values. */
	p->policy_type = policy_type;
	p->policyvers = r_policyvers;

	if (buf[bufindex] & POLICYDB_CONFIG_MLS) {
		p->mls = 1;
	} else {
		p->mls = 0;
	}

	p->handle_unknown = buf[bufindex] & POLICYDB_CONFIG_UNKNOWN_MASK;

	bufindex++;

	info = policydb_lookup_compat(r_policyvers, policy_type,
					p->target_platform);
	if (!info) {
		ERR(fp->handle, "unable to find policy compat info "
		    "for version %d", r_policyvers);
		goto bad;
	}

	if (buf[bufindex] != info->sym_num
	    || buf[bufindex + 1] != info->ocon_num) {
		ERR(fp->handle,
		    "policydb table sizes (%d,%d) do not " "match mine (%d,%d)",
		    buf[bufindex], buf[bufindex + 1], info->sym_num,
		    info->ocon_num);
		goto bad;
	}

	if (p->policy_type == POLICY_MOD) {
		/* Get the module name and version */
		if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
			goto bad;
		}
		len = le32_to_cpu(buf[0]);
		if (zero_or_saturated(len))
			goto bad;
		if ((p->name = malloc(len + 1)) == NULL) {
			goto bad;
		}
		if ((rc = next_entry(p->name, fp, len)) < 0) {
			goto bad;
		}
		p->name[len] = '\0';
		if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
			goto bad;
		}
		len = le32_to_cpu(buf[0]);
		if (zero_or_saturated(len))
			goto bad;
		if ((p->version = malloc(len + 1)) == NULL) {
			goto bad;
		}
		if ((rc = next_entry(p->version, fp, len)) < 0) {
			goto bad;
		}
		p->version[len] = '\0';
	}

	if ((p->policyvers >= POLICYDB_VERSION_POLCAP &&
	     p->policy_type == POLICY_KERN) ||
	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
	     p->policy_type == POLICY_BASE) ||
	    (p->policyvers >= MOD_POLICYDB_VERSION_POLCAP &&
	     p->policy_type == POLICY_MOD)) {
		if (ebitmap_read(&p->policycaps, fp))
			goto bad;
	}

	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
	    p->policy_type == POLICY_KERN) {
		if (ebitmap_read(&p->permissive_map, fp))
			goto bad;
	}

	for (i = 0; i < info->sym_num; i++) {
		rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
		if (rc < 0)
			goto bad;
		nprim = le32_to_cpu(buf[0]);
		if (is_saturated(nprim))
			goto bad;
		nel = le32_to_cpu(buf[1]);
		if (nel && !nprim) {
			ERR(fp->handle, "unexpected items in symbol table with no symbol");
			goto bad;
		}
		for (j = 0; j < nel; j++) {
			if (read_f[i] (p, p->symtab[i].table, fp))
				goto bad;
		}

		p->symtab[i].nprim = nprim;
	}

	switch (p->target_platform) {
	case SEPOL_TARGET_SELINUX:
		p->process_class = policydb_string_to_security_class(p, "process");
		p->dir_class = policydb_string_to_security_class(p, "dir");
		break;
	case SEPOL_TARGET_XEN:
		p->process_class = policydb_string_to_security_class(p, "domain");
		break;
	default:
		break;
	}

	if (policy_type == POLICY_KERN) {
		if (avtab_read(&p->te_avtab, fp, r_policyvers))
			goto bad;
		if (r_policyvers >= POLICYDB_VERSION_BOOL)
			if (cond_read_list(p, &p->cond_list, fp))
				goto bad;
		if (role_trans_read(p, fp))
			goto bad;
		if (role_allow_read(&p->role_allow, fp))
			goto bad;
		if (r_policyvers >= POLICYDB_VERSION_FILENAME_TRANS &&
		    filename_trans_read(p, fp))
			goto bad;
	} else {
		/* first read the AV rule blocks, then the scope tables */
		avrule_block_destroy(p->global);
		p->global = NULL;
		if (avrule_block_read(p, &p->global, info->sym_num, fp) == -1) {
			goto bad;
		}
		if (p->global == NULL) {
			ERR(fp->handle, "no avrule block in policy");
			goto bad;
		}
		for (i = 0; i < info->sym_num; i++) {
			if ((rc = next_entry(buf, fp, sizeof(uint32_t))) < 0) {
				goto bad;
			}
			nel = le32_to_cpu(buf[0]);
			for (j = 0; j < nel; j++) {
				if (scope_read(p, i, fp))
					goto bad;
			}
		}

	}

	if (policydb_index_decls(fp->handle, p))
		goto bad;

	if (policydb_index_classes(p))
		goto bad;

	switch (p->target_platform) {
	case SEPOL_TARGET_SELINUX:
		/* fall through */
	case SEPOL_TARGET_XEN:
		p->process_trans = policydb_string_to_av_perm(p, p->process_class,
							      "transition");
		p->process_trans_dyntrans = p->process_trans |
			policydb_string_to_av_perm(p, p->process_class,
						   "dyntransition");
		break;
	default:
		break;
	}

	if (policydb_index_others(fp->handle, p, verbose))
		goto bad;

	if (ocontext_read(info, p, fp) == -1) {
		goto bad;
	}

	if (genfs_read(p, fp) == -1) {
		goto bad;
	}

	if ((p->policy_type == POLICY_KERN
	     && p->policyvers >= POLICYDB_VERSION_MLS)
	    || (p->policy_type == POLICY_BASE
		&& p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS)) {
		if (range_read(p, fp)) {
			goto bad;
		}
	}

	if (policy_type == POLICY_KERN) {
		p->type_attr_map = calloc(p->p_types.nprim, sizeof(ebitmap_t));
		p->attr_type_map = calloc(p->p_types.nprim, sizeof(ebitmap_t));
		if (!p->type_attr_map || !p->attr_type_map)
			goto bad;
		for (i = 0; i < p->p_types.nprim; i++) {
			if (r_policyvers >= POLICYDB_VERSION_AVTAB) {
				if (ebitmap_read(&p->type_attr_map[i], fp))
					goto bad;
				ebitmap_for_each_positive_bit(&p->type_attr_map[i],
							 tnode, j) {
					if (i == j)
						continue;

					if (j >= p->p_types.nprim)
						goto bad;

					if (ebitmap_set_bit
					    (&p->attr_type_map[j], i, 1))
						goto bad;
				}
			}
			/* add the type itself as the degenerate case */
			if (ebitmap_set_bit(&p->type_attr_map[i], i, 1))
				goto bad;
			if (p->type_val_to_struct[i] && p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
				if (ebitmap_set_bit(&p->attr_type_map[i], i, 1))
					goto bad;
			}
		}
	}

	if (policydb_validate(fp->handle, p))
		goto bad;

	return POLICYDB_SUCCESS;
      bad:
	return POLICYDB_ERROR;
}

int policydb_reindex_users(policydb_t * p)
{
	unsigned int i = SYM_USERS;

	if (p->user_val_to_struct)
		free(p->user_val_to_struct);
	if (p->sym_val_to_name[i])
		free(p->sym_val_to_name[i]);

	p->user_val_to_struct = (user_datum_t **)
	    calloc(p->p_users.nprim, sizeof(user_datum_t *));
	if (!p->user_val_to_struct)
		return -1;

	p->sym_val_to_name[i] = (char **)
	    calloc(p->symtab[i].nprim, sizeof(char *));
	if (!p->sym_val_to_name[i])
		return -1;

	if (hashtab_map(p->symtab[i].table, index_f[i], p))
		return -1;

	/* Expand user roles for context validity checking */
	if (hashtab_map(p->p_users.table, policydb_user_cache, p))
		return -1;

	return 0;
}

void policy_file_init(policy_file_t *pf)
{
	memset(pf, 0, sizeof(policy_file_t));
}

int policydb_set_target_platform(policydb_t *p, int platform)
{
	if (platform == SEPOL_TARGET_SELINUX)
		p->target_platform = SEPOL_TARGET_SELINUX;
	else if (platform == SEPOL_TARGET_XEN)
		p->target_platform = SEPOL_TARGET_XEN;
	else
		return -1;

	return 0;
}

int policydb_sort_ocontexts(policydb_t *p)
{
	return sort_ocontexts(p);
}
