
/* Author : Stephen Smalley, <sds@epoch.ncsc.mil> */

/*
 * 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: Joshua Brindle <jbrindle@tresys.com> and Jason Tang <jtang@tresys.org>
 *
 *	Module writing support
 *
 * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
 * Copyright (C) 2003-2005 Tresys Technology, LLC
 *
 *  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
 */
#include <assert.h>
#include <stdlib.h>

#include <sepol/policydb/ebitmap.h>
#include <sepol/policydb/avtab.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/expand.h>
#include <sepol/policydb/flask.h>

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

struct policy_data {
	struct policy_file *fp;
	struct policydb *p;
};

static int avrule_write_list(avrule_t * avrules, struct policy_file *fp);

static int ebitmap_write(ebitmap_t * e, struct policy_file *fp)
{
	ebitmap_node_t *n;
	uint32_t buf[32], bit, count;
	uint64_t map;
	size_t items;

	buf[0] = cpu_to_le32(MAPSIZE);
	buf[1] = cpu_to_le32(e->highbit);

	count = 0;
	for (n = e->node; n; n = n->next)
		count++;
	buf[2] = cpu_to_le32(count);

	items = put_entry(buf, sizeof(uint32_t), 3, fp);
	if (items != 3)
		return POLICYDB_ERROR;

	for (n = e->node; n; n = n->next) {
		bit = cpu_to_le32(n->startbit);
		items = put_entry(&bit, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		map = cpu_to_le64(n->map);
		items = put_entry(&map, sizeof(uint64_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;

	}

	return POLICYDB_SUCCESS;
}

/* Ordering of datums in the original avtab format in the policy file. */
static uint16_t spec_order[] = {
	AVTAB_ALLOWED,
	AVTAB_AUDITDENY,
	AVTAB_AUDITALLOW,
	AVTAB_TRANSITION,
	AVTAB_CHANGE,
	AVTAB_MEMBER
};

static int avtab_write_item(policydb_t * p,
			    avtab_ptr_t cur, struct policy_file *fp,
			    unsigned merge, unsigned commit, uint32_t * nel)
{
	avtab_ptr_t node;
	uint8_t buf8;
	uint16_t buf16[4];
	uint32_t buf32[10], lookup, val;
	size_t items, items2;
	unsigned set;
	unsigned int oldvers = (p->policy_type == POLICY_KERN
				&& p->policyvers < POLICYDB_VERSION_AVTAB);
	unsigned int i;

	if (oldvers) {
		/* Generate the old avtab format.
		   Requires merging similar entries if uncond avtab. */
		if (merge) {
			if (cur->merged)
				return POLICYDB_SUCCESS;	/* already merged by prior merge */
		}

		items = 1;	/* item 0 is used for the item count */
		val = cur->key.source_type;
		buf32[items++] = cpu_to_le32(val);
		val = cur->key.target_type;
		buf32[items++] = cpu_to_le32(val);
		val = cur->key.target_class;
		buf32[items++] = cpu_to_le32(val);

		val = cur->key.specified & ~AVTAB_ENABLED;
		if (cur->key.specified & AVTAB_ENABLED)
			val |= AVTAB_ENABLED_OLD;
		set = 1;

		if (merge) {
			/* Merge specifier values for all similar (av or type)
			   entries that have the same key. */
			if (val & AVTAB_AV)
				lookup = AVTAB_AV;
			else if (val & AVTAB_TYPE)
				lookup = AVTAB_TYPE;
			else
				return POLICYDB_ERROR;
			for (node = avtab_search_node_next(cur, lookup);
			     node;
			     node = avtab_search_node_next(node, lookup)) {
				val |= (node->key.specified & ~AVTAB_ENABLED);
				set++;
				if (node->key.specified & AVTAB_ENABLED)
					val |= AVTAB_ENABLED_OLD;
			}
		}

		if (!(val & (AVTAB_AV | AVTAB_TYPE))) {
			ERR(fp->handle, "null entry");
			return POLICYDB_ERROR;
		}
		if ((val & AVTAB_AV) && (val & AVTAB_TYPE)) {
			ERR(fp->handle, "entry has both access "
			    "vectors and types");
			return POLICYDB_ERROR;
		}

		buf32[items++] = cpu_to_le32(val);

		if (merge) {
			/* Include datums for all similar (av or type)
			   entries that have the same key. */
			for (i = 0;
			     i < (sizeof(spec_order) / sizeof(spec_order[0]));
			     i++) {
				if (val & spec_order[i]) {
					if (cur->key.specified & spec_order[i])
						node = cur;
					else {
						node =
						    avtab_search_node_next(cur,
									   spec_order
									   [i]);
						if (nel)
							(*nel)--;	/* one less node */
					}

					if (!node) {
						ERR(fp->handle, "missing node");
						return POLICYDB_ERROR;
					}
					buf32[items++] =
					    cpu_to_le32(node->datum.data);
					set--;
					node->merged = 1;
				}
			}
		} else {
			buf32[items++] = cpu_to_le32(cur->datum.data);
			cur->merged = 1;
			set--;
		}

		if (set) {
			ERR(fp->handle, "data count wrong");
			return POLICYDB_ERROR;
		}

		buf32[0] = cpu_to_le32(items - 1);

		if (commit) {
			/* Commit this item to the policy file. */
			items2 = put_entry(buf32, sizeof(uint32_t), items, fp);
			if (items != items2)
				return POLICYDB_ERROR;
		}

		return POLICYDB_SUCCESS;
	}

	/* Generate the new avtab format. */
	buf16[0] = cpu_to_le16(cur->key.source_type);
	buf16[1] = cpu_to_le16(cur->key.target_type);
	buf16[2] = cpu_to_le16(cur->key.target_class);
	buf16[3] = cpu_to_le16(cur->key.specified);
	items = put_entry(buf16, sizeof(uint16_t), 4, fp);
	if (items != 4)
		return POLICYDB_ERROR;
	if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) &&
			(cur->key.specified & AVTAB_XPERMS)) {
		ERR(fp->handle, "policy version %u does not support ioctl extended"
				"permissions rules and one was specified", p->policyvers);
		return POLICYDB_ERROR;
	}

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

	if (cur->key.specified & AVTAB_XPERMS) {
		buf8 = cur->datum.xperms->specified;
		items = put_entry(&buf8, sizeof(uint8_t),1,fp);
		if (items != 1)
			return POLICYDB_ERROR;
		buf8 = cur->datum.xperms->driver;
		items = put_entry(&buf8, sizeof(uint8_t),1,fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (i = 0; i < ARRAY_SIZE(cur->datum.xperms->perms); i++)
			buf32[i] = cpu_to_le32(cur->datum.xperms->perms[i]);
		items = put_entry(buf32, sizeof(uint32_t),8,fp);
		if (items != 8)
			return POLICYDB_ERROR;
	} else {
		buf32[0] = cpu_to_le32(cur->datum.data);
		items = put_entry(buf32, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static inline void avtab_reset_merged(avtab_t * a)
{
	unsigned int i;
	avtab_ptr_t cur;
	for (i = 0; i < a->nslot; i++) {
		for (cur = a->htable[i]; cur; cur = cur->next)
			cur->merged = 0;
	}
}

static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp)
{
	unsigned int i;
	int rc;
	avtab_t expa;
	avtab_ptr_t cur;
	uint32_t nel;
	size_t items;
	unsigned int oldvers = (p->policy_type == POLICY_KERN
				&& p->policyvers < POLICYDB_VERSION_AVTAB);

	if (oldvers) {
		/* Old avtab format.
		   First, we need to expand attributes.  Then, we need to
		   merge similar entries, so we need to track merged nodes 
		   and compute the final nel. */
		if (avtab_init(&expa))
			return POLICYDB_ERROR;
		if (expand_avtab(p, a, &expa)) {
			rc = -1;
			goto out;
		}
		a = &expa;
		avtab_reset_merged(a);
		nel = a->nel;
	} else {
		/* New avtab format.  nel is good to go. */
		nel = cpu_to_le32(a->nel);
		items = put_entry(&nel, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	for (i = 0; i < a->nslot; i++) {
		for (cur = a->htable[i]; cur; cur = cur->next) {
			/* If old format, compute final nel.
			   If new format, write out the items. */
			if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) {
				rc = -1;
				goto out;
			}
		}
	}

	if (oldvers) {
		/* Old avtab format.
		   Write the computed nel value, then write the items. */
		nel = cpu_to_le32(nel);
		items = put_entry(&nel, sizeof(uint32_t), 1, fp);
		if (items != 1) {
			rc = -1;
			goto out;
		}
		avtab_reset_merged(a);
		for (i = 0; i < a->nslot; i++) {
			for (cur = a->htable[i]; cur; cur = cur->next) {
				if (avtab_write_item(p, cur, fp, 1, 1, NULL)) {
					rc = -1;
					goto out;
				}
			}
		}
	}

	rc = 0;
      out:
	if (oldvers)
		avtab_destroy(&expa);
	return rc;
}

/*
 * Write a semantic MLS level structure to a policydb binary 
 * representation file.
 */
static int mls_write_semantic_level_helper(mls_semantic_level_t * l,
					   struct policy_file *fp)
{
	uint32_t buf[2], ncat = 0;
	size_t items;
	mls_semantic_cat_t *cat;

	for (cat = l->cat; cat; cat = cat->next)
		ncat++;

	buf[0] = cpu_to_le32(l->sens);
	buf[1] = cpu_to_le32(ncat);
	items = put_entry(buf, sizeof(uint32_t), 2, fp);
	if (items != 2)
		return POLICYDB_ERROR;

	for (cat = l->cat; cat; cat = cat->next) {
		buf[0] = cpu_to_le32(cat->low);
		buf[1] = cpu_to_le32(cat->high);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

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

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

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

	return rc;
}

/*
 * Write a MLS level structure to a policydb binary 
 * representation file.
 */
static int mls_write_level(mls_level_t * l, struct policy_file *fp)
{
	uint32_t sens;
	size_t items;

	sens = cpu_to_le32(l->sens);
	items = put_entry(&sens, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	if (ebitmap_write(&l->cat, fp))
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

/*
 * Write a MLS range structure to a policydb binary 
 * representation file.
 */
static int mls_write_range_helper(mls_range_t * r, struct policy_file *fp)
{
	uint32_t buf[3];
	size_t items, items2;
	int eq;

	eq = mls_level_eq(&r->level[1], &r->level[0]);

	items = 1;		/* item 0 is used for the item count */
	buf[items++] = cpu_to_le32(r->level[0].sens);
	if (!eq)
		buf[items++] = cpu_to_le32(r->level[1].sens);
	buf[0] = cpu_to_le32(items - 1);

	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items2 != items)
		return POLICYDB_ERROR;

	if (ebitmap_write(&r->level[0].cat, fp))
		return POLICYDB_ERROR;
	if (!eq)
		if (ebitmap_write(&r->level[1].cat, fp))
			return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int sens_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	level_datum_t *levdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	levdatum = (level_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(levdatum->isalias);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (mls_write_level(levdatum->level, fp))
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int cat_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	cat_datum_t *catdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	catdatum = (cat_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(catdatum->s.value);
	buf[items++] = cpu_to_le32(catdatum->isalias);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int role_trans_write(policydb_t *p, struct policy_file *fp)
{
	role_trans_t *r = p->role_tr;
	role_trans_t *tr;
	uint32_t buf[3];
	size_t nel, items;
	int new_roletr = (p->policy_type == POLICY_KERN &&
			  p->policyvers >= POLICYDB_VERSION_ROLETRANS);
	int warning_issued = 0;

	nel = 0;
	for (tr = r; tr; tr = tr->next)
		if(new_roletr || tr->tclass == SECCLASS_PROCESS)
			nel++;

	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (tr = r; tr; tr = tr->next) {
		if (!new_roletr && tr->tclass != SECCLASS_PROCESS) {
			if (!warning_issued)
				WARN(fp->handle, "Discarding role_transition "
				     "rules for security classes other than "
				     "\"process\"");
			warning_issued = 1;
			continue;
		}
		buf[0] = cpu_to_le32(tr->role);
		buf[1] = cpu_to_le32(tr->type);
		buf[2] = cpu_to_le32(tr->new_role);
		items = put_entry(buf, sizeof(uint32_t), 3, fp);
		if (items != 3)
			return POLICYDB_ERROR;
		if (new_roletr) {
			buf[0] = cpu_to_le32(tr->tclass);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
		}
	}

	return POLICYDB_SUCCESS;
}

static int role_allow_write(role_allow_t * r, struct policy_file *fp)
{
	role_allow_t *ra;
	uint32_t buf[2];
	size_t nel, items;

	nel = 0;
	for (ra = r; ra; ra = ra->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (ra = r; ra; ra = ra->next) {
		buf[0] = cpu_to_le32(ra->role);
		buf[1] = cpu_to_le32(ra->new_role);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

static int filename_trans_write(filename_trans_t * r, struct policy_file *fp)
{
	filename_trans_t *ft;
	uint32_t buf[4];
	size_t nel, items, len;

	nel = 0;
	for (ft = r; ft; ft = ft->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (ft = r; ft; ft = ft->next) {
		len = strlen(ft->name);
		buf[0] = cpu_to_le32(len);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;

		items = put_entry(ft->name, sizeof(char), len, fp);
		if (items != len)
			return POLICYDB_ERROR;

		buf[0] = cpu_to_le32(ft->stype);
		buf[1] = cpu_to_le32(ft->ttype);
		buf[2] = cpu_to_le32(ft->tclass);
		buf[3] = cpu_to_le32(ft->otype);
		items = put_entry(buf, sizeof(uint32_t), 4, fp);
		if (items != 4)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int role_set_write(role_set_t * x, struct policy_file *fp)
{
	size_t items;
	uint32_t buf[1];

	if (ebitmap_write(&x->roles, fp))
		return POLICYDB_ERROR;

	buf[0] = cpu_to_le32(x->flags);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int type_set_write(type_set_t * x, struct policy_file *fp)
{
	size_t items;
	uint32_t buf[1];

	if (ebitmap_write(&x->types, fp))
		return POLICYDB_ERROR;
	if (ebitmap_write(&x->negset, fp))
		return POLICYDB_ERROR;

	buf[0] = cpu_to_le32(x->flags);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int cond_write_bool(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	cond_bool_datum_t *booldatum;
	uint32_t buf[3], len;
	unsigned int items, items2;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	booldatum = (cond_bool_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(booldatum->s.value);
	buf[items++] = cpu_to_le32(booldatum->state);
	buf[items++] = cpu_to_le32(len);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;
	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
		buf[0] = cpu_to_le32(booldatum->flags);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

/*
 * cond_write_cond_av_list doesn't write out the av_list nodes.
 * Instead it writes out the key/value pairs from the avtab. This
 * is necessary because there is no way to uniquely identifying rules
 * in the avtab so it is not possible to associate individual rules
 * in the avtab with a conditional without saving them as part of
 * the conditional. This means that the avtab with the conditional
 * rules will not be saved but will be rebuilt on policy load.
 */
static int cond_write_av_list(policydb_t * p,
			      cond_av_list_t * list, struct policy_file *fp)
{
	uint32_t buf[4];
	cond_av_list_t *cur_list, *new_list = NULL;
	avtab_t expa;
	uint32_t len, items;
	unsigned int oldvers = (p->policy_type == POLICY_KERN
				&& p->policyvers < POLICYDB_VERSION_AVTAB);
	int rc = -1;

	if (oldvers) {
		if (avtab_init(&expa))
			return POLICYDB_ERROR;
		if (expand_cond_av_list(p, list, &new_list, &expa))
			goto out;
		list = new_list;
	}

	len = 0;
	for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
		if (cur_list->node->parse_context)
			len++;
	}

	buf[0] = cpu_to_le32(len);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		goto out;

	if (len == 0) {
		rc = 0;
		goto out;
	}

	for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) {
		if (cur_list->node->parse_context)
			if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL))
				goto out;
	}

	rc = 0;
      out:
	if (oldvers) {
		cond_av_list_destroy(new_list);
		avtab_destroy(&expa);
	}

	return rc;
}

static int cond_write_node(policydb_t * p,
			   cond_node_t * node, struct policy_file *fp)
{
	cond_expr_t *cur_expr;
	uint32_t buf[2];
	uint32_t items, items2, len;

	buf[0] = cpu_to_le32(node->cur_state);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	/* expr */
	len = 0;
	for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next)
		len++;

	buf[0] = cpu_to_le32(len);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	for (cur_expr = node->expr; cur_expr != NULL; cur_expr = cur_expr->next) {
		items = 0;
		buf[items++] = cpu_to_le32(cur_expr->expr_type);
		buf[items++] = cpu_to_le32(cur_expr->bool);
		items2 = put_entry(buf, sizeof(uint32_t), items, fp);
		if (items2 != items)
			return POLICYDB_ERROR;
	}

	if (p->policy_type == POLICY_KERN) {
		if (cond_write_av_list(p, node->true_list, fp) != 0)
			return POLICYDB_ERROR;
		if (cond_write_av_list(p, node->false_list, fp) != 0)
			return POLICYDB_ERROR;
	} else {
		if (avrule_write_list(node->avtrue_list, fp))
			return POLICYDB_ERROR;
		if (avrule_write_list(node->avfalse_list, fp))
			return POLICYDB_ERROR;
	}

	if (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) {
		buf[0] = cpu_to_le32(node->flags);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int cond_write_list(policydb_t * p, cond_list_t * list,
			   struct policy_file *fp)
{
	cond_node_t *cur;
	uint32_t len, items;
	uint32_t buf[1];

	len = 0;
	for (cur = list; cur != NULL; cur = cur->next)
		len++;
	buf[0] = cpu_to_le32(len);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	for (cur = list; cur != NULL; cur = cur->next) {
		if (cond_write_node(p, cur, fp) != 0)
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

/*
 * Write a security context structure
 * to a policydb binary representation file.
 */
static int context_write(struct policydb *p, context_struct_t * c,
			 struct policy_file *fp)
{
	uint32_t buf[32];
	size_t items, items2;

	items = 0;
	buf[items++] = cpu_to_le32(c->user);
	buf[items++] = cpu_to_le32(c->role);
	buf[items++] = cpu_to_le32(c->type);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items2 != items)
		return POLICYDB_ERROR;
	if ((p->policyvers >= POLICYDB_VERSION_MLS
	     && p->policy_type == POLICY_KERN)
	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policy_type == POLICY_BASE))
		if (mls_write_range_helper(&c->range, fp))
			return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

/*
 * The following *_write functions are used to
 * write the symbol data to a policy database
 * binary representation file.
 */

static int perm_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	perm_datum_t *perdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	perdatum = (perm_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(perdatum->s.value);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int common_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	common_datum_t *comdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;

	comdatum = (common_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(comdatum->s.value);
	buf[items++] = cpu_to_le32(comdatum->permissions.nprim);
	buf[items++] = cpu_to_le32(comdatum->permissions.table->nel);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (hashtab_map(comdatum->permissions.table, perm_write, pd))
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int write_cons_helper(policydb_t * p,
			     constraint_node_t * node, int allowxtarget,
			     struct policy_file *fp)
{
	constraint_node_t *c;
	constraint_expr_t *e;
	uint32_t buf[3], nexpr;
	int items;

	for (c = node; c; c = c->next) {
		nexpr = 0;
		for (e = c->expr; e; e = e->next) {
			nexpr++;
		}
		buf[0] = cpu_to_le32(c->permissions);
		buf[1] = cpu_to_le32(nexpr);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
		for (e = c->expr; e; e = e->next) {
			items = 0;
			buf[0] = cpu_to_le32(e->expr_type);
			buf[1] = cpu_to_le32(e->attr);
			buf[2] = cpu_to_le32(e->op);
			items = put_entry(buf, sizeof(uint32_t), 3, fp);
			if (items != 3)
				return POLICYDB_ERROR;

			switch (e->expr_type) {
			case CEXPR_NAMES:
				if (!allowxtarget && (e->attr & CEXPR_XTARGET))
					return POLICYDB_ERROR;
				if (ebitmap_write(&e->names, fp)) {
					return POLICYDB_ERROR;
				}
				if ((p->policy_type != POLICY_KERN &&
						type_set_write(e->type_names, fp)) ||
						(p->policy_type == POLICY_KERN &&
						(p->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES) &&
						type_set_write(e->type_names, fp))) {
					return POLICYDB_ERROR;
				}
				break;
			default:
				break;
			}
		}
	}

	return POLICYDB_SUCCESS;
}

static int class_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	class_datum_t *cladatum;
	constraint_node_t *c;
	uint32_t buf[32], ncons;
	size_t items, items2, len, len2;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	cladatum = (class_datum_t *) datum;

	len = strlen(key);
	if (cladatum->comkey)
		len2 = strlen(cladatum->comkey);
	else
		len2 = 0;

	ncons = 0;
	for (c = cladatum->constraints; c; c = c->next) {
		ncons++;
	}

	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(len2);
	buf[items++] = cpu_to_le32(cladatum->s.value);
	buf[items++] = cpu_to_le32(cladatum->permissions.nprim);
	if (cladatum->permissions.table)
		buf[items++] = cpu_to_le32(cladatum->permissions.table->nel);
	else
		buf[items++] = 0;
	buf[items++] = cpu_to_le32(ncons);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (cladatum->comkey) {
		items = put_entry(cladatum->comkey, 1, len2, fp);
		if (items != len2)
			return POLICYDB_ERROR;
	}
	if (hashtab_map(cladatum->permissions.table, perm_write, pd))
		return POLICYDB_ERROR;

	if (write_cons_helper(p, cladatum->constraints, 0, fp))
		return POLICYDB_ERROR;

	if ((p->policy_type == POLICY_KERN
	     && p->policyvers >= POLICYDB_VERSION_VALIDATETRANS)
	    || (p->policy_type == POLICY_BASE
		&& p->policyvers >= MOD_POLICYDB_VERSION_VALIDATETRANS)) {
		/* write out the validatetrans rule */
		ncons = 0;
		for (c = cladatum->validatetrans; c; c = c->next) {
			ncons++;
		}
		buf[0] = cpu_to_le32(ncons);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		if (write_cons_helper(p, cladatum->validatetrans, 1, fp))
			return POLICYDB_ERROR;
	}

	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)) {
		buf[0] = cpu_to_le32(cladatum->default_user);
		buf[1] = cpu_to_le32(cladatum->default_role);
		buf[2] = cpu_to_le32(cladatum->default_range);
		items = put_entry(buf, sizeof(uint32_t), 3, fp);
		if (items != 3)
			return POLICYDB_ERROR;
	}

	if ((p->policy_type == POLICY_KERN &&
	     p->policyvers >= POLICYDB_VERSION_DEFAULT_TYPE) ||
	    (p->policy_type == POLICY_BASE &&
	     p->policyvers >= MOD_POLICYDB_VERSION_DEFAULT_TYPE)) {
		buf[0] = cpu_to_le32(cladatum->default_type);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int role_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	role_datum_t *role;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	role = (role_datum_t *) datum;

	/*
	 * Role attributes are redundant for policy.X, skip them
	 * when writing the roles symbol table. They are also skipped
	 * when pp is downgraded.
	 *
	 * Their numbers would be deducted in policydb_write().
	 */
	if ((role->flavor == ROLE_ATTRIB) &&
	    ((p->policy_type == POLICY_KERN) ||
	     (p->policy_type != POLICY_KERN &&
	      p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB)))
		return POLICYDB_SUCCESS;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(role->s.value);
	if (policydb_has_boundary_feature(p))
		buf[items++] = cpu_to_le32(role->bounds);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (ebitmap_write(&role->dominates, fp))
		return POLICYDB_ERROR;
	if (p->policy_type == POLICY_KERN) {
		if (ebitmap_write(&role->types.types, fp))
			return POLICYDB_ERROR;
	} else {
		if (type_set_write(&role->types, fp))
			return POLICYDB_ERROR;
	}

	if (p->policy_type != POLICY_KERN &&
	    p->policyvers >= MOD_POLICYDB_VERSION_ROLEATTRIB) {
		buf[0] = cpu_to_le32(role->flavor);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;

		if (ebitmap_write(&role->roles, fp))
			return POLICYDB_ERROR;
	}

	return POLICYDB_SUCCESS;
}

static int type_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	type_datum_t *typdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	typdatum = (type_datum_t *) datum;

	/*
	 * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY)
	 * does not support to load entries of attribute, so we skip to write it.
	 */
	if (p->policy_type == POLICY_KERN
	    && p->policyvers < POLICYDB_VERSION_BOUNDARY
	    && typdatum->flavor == TYPE_ATTRIB)
		return POLICYDB_SUCCESS;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(typdatum->s.value);
	if (policydb_has_boundary_feature(p)) {
		uint32_t properties = 0;

		if (p->policy_type != POLICY_KERN
		    && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY_ALIAS) {
			buf[items++] = cpu_to_le32(typdatum->primary);
		}

		if (typdatum->primary)
			properties |= TYPEDATUM_PROPERTY_PRIMARY;

		if (typdatum->flavor == TYPE_ATTRIB) {
			properties |= TYPEDATUM_PROPERTY_ATTRIBUTE;
		} else if (typdatum->flavor == TYPE_ALIAS
			   && p->policy_type != POLICY_KERN)
			properties |= TYPEDATUM_PROPERTY_ALIAS;

		if (typdatum->flags & TYPE_FLAGS_PERMISSIVE
		    && p->policy_type != POLICY_KERN)
			properties |= TYPEDATUM_PROPERTY_PERMISSIVE;

		buf[items++] = cpu_to_le32(properties);
		buf[items++] = cpu_to_le32(typdatum->bounds);
	} else {
		buf[items++] = cpu_to_le32(typdatum->primary);

		if (p->policy_type != POLICY_KERN) {
			buf[items++] = cpu_to_le32(typdatum->flavor);

			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
				buf[items++] = cpu_to_le32(typdatum->flags);
			else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE)
				WARN(fp->handle, "Warning! Module policy "
				     "version %d cannot support permissive "
				     "types, but one was defined",
				     p->policyvers);
		}
	}
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	if (p->policy_type != POLICY_KERN) {
		if (ebitmap_write(&typdatum->types, fp))
			return POLICYDB_ERROR;
	}

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	return POLICYDB_SUCCESS;
}

static int user_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	user_datum_t *usrdatum;
	uint32_t buf[32];
	size_t items, items2, len;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	struct policydb *p = pd->p;

	usrdatum = (user_datum_t *) datum;

	len = strlen(key);
	items = 0;
	buf[items++] = cpu_to_le32(len);
	buf[items++] = cpu_to_le32(usrdatum->s.value);
	if (policydb_has_boundary_feature(p))
		buf[items++] = cpu_to_le32(usrdatum->bounds);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	items = put_entry(key, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	if (p->policy_type == POLICY_KERN) {
		if (ebitmap_write(&usrdatum->roles.roles, fp))
			return POLICYDB_ERROR;
	} else {
		if (role_set_write(&usrdatum->roles, fp))
			return POLICYDB_ERROR;
	}

	if ((p->policyvers >= POLICYDB_VERSION_MLS
	     && p->policy_type == POLICY_KERN)
	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS
		&& p->policy_type == POLICY_MOD)
	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policyvers < MOD_POLICYDB_VERSION_MLS_USERS
		&& p->policy_type == POLICY_BASE)) {
		if (mls_write_range_helper(&usrdatum->exp_range, fp))
			return POLICYDB_ERROR;
		if (mls_write_level(&usrdatum->exp_dfltlevel, fp))
			return POLICYDB_ERROR;
	} else if ((p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS
		    && p->policy_type == POLICY_MOD)
		   || (p->policyvers >= MOD_POLICYDB_VERSION_MLS_USERS
		       && p->policy_type == POLICY_BASE)) {
		if (mls_write_semantic_range_helper(&usrdatum->range, fp))
			return -1;
		if (mls_write_semantic_level_helper(&usrdatum->dfltlevel, fp))
			return -1;
	}

	return POLICYDB_SUCCESS;
}

static int (*write_f[SYM_NUM]) (hashtab_key_t key, hashtab_datum_t datum,
				void *datap) = {
common_write, class_write, role_write, type_write, user_write,
	    cond_write_bool, sens_write, cat_write,};

static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
			  struct policy_file *fp)
{
	unsigned int i, j;
	size_t nel, items, len;
	uint32_t buf[32];
	ocontext_t *c;
	for (i = 0; i < info->ocon_num; i++) {
		nel = 0;
		for (c = p->ocontexts[i]; c; c = c->next)
			nel++;
		buf[0] = cpu_to_le32(nel);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (c = p->ocontexts[i]; c; c = c->next) {
			switch (i) {
			case OCON_XEN_ISID:
				buf[0] = cpu_to_le32(c->sid[0]);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_PIRQ:
				buf[0] = cpu_to_le32(c->u.pirq);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_IOPORT:
				buf[0] = c->u.ioport.low_ioport;
				buf[1] = c->u.ioport.high_ioport;
				for (j = 0; j < 2; j++)
					buf[j] = cpu_to_le32(buf[j]);
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_IOMEM:
				if (p->policyvers >= POLICYDB_VERSION_XEN_DEVICETREE) {
					uint64_t b64[2];
					b64[0] = c->u.iomem.low_iomem;
					b64[1] = c->u.iomem.high_iomem;
					for (j = 0; j < 2; j++)
						b64[j] = cpu_to_le64(b64[j]);
					items = put_entry(b64, sizeof(uint64_t), 2, fp);
					if (items != 2)
						return POLICYDB_ERROR;
				} else {
					if (c->u.iomem.high_iomem > 0xFFFFFFFFULL) {
						ERR(fp->handle, "policy version %d"
							" cannot represent IOMEM addresses over 16TB",
							p->policyvers);
						return POLICYDB_ERROR;
					}

					buf[0] = c->u.iomem.low_iomem;
					buf[1] = c->u.iomem.high_iomem;
					for (j = 0; j < 2; j++)
						buf[j] = cpu_to_le32(buf[j]);
					items = put_entry(buf, sizeof(uint32_t), 2, fp);
					if (items != 2)
						return POLICYDB_ERROR;
				}
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_PCIDEVICE:
				buf[0] = cpu_to_le32(c->u.device);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_XEN_DEVICETREE:
				len = strlen(c->u.name);
				buf[0] = cpu_to_le32(len);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				items = put_entry(c->u.name, 1, len, fp);
				if (items != len)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			}
		}
	}
	return POLICYDB_SUCCESS;
}

static int ocontext_write_selinux(struct policydb_compat_info *info,
	policydb_t *p, struct policy_file *fp)
{
	unsigned int i, j;
	size_t nel, items, len;
	uint32_t buf[32];
	ocontext_t *c;
	for (i = 0; i < info->ocon_num; i++) {
		nel = 0;
		for (c = p->ocontexts[i]; c; c = c->next)
			nel++;
		buf[0] = cpu_to_le32(nel);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (c = p->ocontexts[i]; c; c = c->next) {
			switch (i) {
			case OCON_ISID:
				buf[0] = cpu_to_le32(c->sid[0]);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_FS:
			case OCON_NETIF:
				len = strlen(c->u.name);
				buf[0] = cpu_to_le32(len);
				items = put_entry(buf, sizeof(uint32_t), 1, fp);
				if (items != 1)
					return POLICYDB_ERROR;
				items = put_entry(c->u.name, 1, len, fp);
				if (items != len)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[1], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_PORT:
				buf[0] = c->u.port.protocol;
				buf[1] = c->u.port.low_port;
				buf[2] = c->u.port.high_port;
				for (j = 0; j < 3; j++) {
					buf[j] = cpu_to_le32(buf[j]);
				}
				items = put_entry(buf, sizeof(uint32_t), 3, fp);
				if (items != 3)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_NODE:
				buf[0] = c->u.node.addr; /* network order */
				buf[1] = c->u.node.mask; /* network order */
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_FSUSE:
				buf[0] = cpu_to_le32(c->v.behavior);
				len = strlen(c->u.name);
				buf[1] = cpu_to_le32(len);
				items = put_entry(buf, sizeof(uint32_t), 2, fp);
				if (items != 2)
					return POLICYDB_ERROR;
				items = put_entry(c->u.name, 1, len, fp);
				if (items != len)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			case OCON_NODE6:
				for (j = 0; j < 4; j++)
					buf[j] = c->u.node6.addr[j]; /* network order */
				for (j = 0; j < 4; j++)
					buf[j + 4] = c->u.node6.mask[j]; /* network order */
				items = put_entry(buf, sizeof(uint32_t), 8, fp);
				if (items != 8)
					return POLICYDB_ERROR;
				if (context_write(p, &c->context[0], fp))
					return POLICYDB_ERROR;
				break;
			}
		}
	}
	return POLICYDB_SUCCESS;
}

static int ocontext_write(struct policydb_compat_info *info, policydb_t * p,
	struct policy_file *fp)
{
	int rc = POLICYDB_ERROR;
	switch (p->target_platform) {
	case SEPOL_TARGET_SELINUX:
		rc = ocontext_write_selinux(info, p, fp);
		break;
	case SEPOL_TARGET_XEN:
		rc = ocontext_write_xen(info, p, fp);
		break;
	}
	return rc;
}

static int genfs_write(policydb_t * p, struct policy_file *fp)
{
	genfs_t *genfs;
	ocontext_t *c;
	size_t nel = 0, items, len;
	uint32_t buf[32];

	for (genfs = p->genfs; genfs; genfs = genfs->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (genfs = p->genfs; genfs; genfs = genfs->next) {
		len = strlen(genfs->fstype);
		buf[0] = cpu_to_le32(len);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		items = put_entry(genfs->fstype, 1, len, fp);
		if (items != len)
			return POLICYDB_ERROR;
		nel = 0;
		for (c = genfs->head; c; c = c->next)
			nel++;
		buf[0] = cpu_to_le32(nel);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (c = genfs->head; c; c = c->next) {
			len = strlen(c->u.name);
			buf[0] = cpu_to_le32(len);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
			items = put_entry(c->u.name, 1, len, fp);
			if (items != len)
				return POLICYDB_ERROR;
			buf[0] = cpu_to_le32(c->v.sclass);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
			if (context_write(p, &c->context[0], fp))
				return POLICYDB_ERROR;
		}
	}
	return POLICYDB_SUCCESS;
}

static int range_write(policydb_t * p, struct policy_file *fp)
{
	size_t nel, items;
	struct range_trans *rt;
	uint32_t buf[2];
	int new_rangetr = (p->policy_type == POLICY_KERN &&
			   p->policyvers >= POLICYDB_VERSION_RANGETRANS);
	int warning_issued = 0;

	nel = 0;
	for (rt = p->range_tr; rt; rt = rt->next) {
		/* all range_transitions are written for the new format, only
		   process related range_transitions are written for the old
		   format, so count accordingly */
		if (new_rangetr || rt->target_class == SECCLASS_PROCESS)
			nel++;
	}
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (rt = p->range_tr; rt; rt = rt->next) {
		if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) {
			if (!warning_issued)
				WARN(fp->handle, "Discarding range_transition "
				     "rules for security classes other than "
				     "\"process\"");
			warning_issued = 1;
			continue;
		}
		buf[0] = cpu_to_le32(rt->source_type);
		buf[1] = cpu_to_le32(rt->target_type);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
		if (new_rangetr) {
			buf[0] = cpu_to_le32(rt->target_class);
			items = put_entry(buf, sizeof(uint32_t), 1, fp);
			if (items != 1)
				return POLICYDB_ERROR;
		}
		if (mls_write_range_helper(&rt->target_range, fp))
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

/************** module writing functions below **************/

static int avrule_write(avrule_t * avrule, struct policy_file *fp)
{
	size_t items, items2;
	uint32_t buf[32], len;
	class_perm_node_t *cur;

	if (avrule->specified & AVRULE_XPERMS) {
		ERR(fp->handle, "module policy does not support extended"
				" permissions rules and one was specified");
		return POLICYDB_ERROR;
	}

	items = 0;
	buf[items++] = cpu_to_le32(avrule->specified);
	buf[items++] = cpu_to_le32(avrule->flags);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items2 != items)
		return POLICYDB_ERROR;

	if (type_set_write(&avrule->stypes, fp))
		return POLICYDB_ERROR;

	if (type_set_write(&avrule->ttypes, fp))
		return POLICYDB_ERROR;

	cur = avrule->perms;
	len = 0;
	while (cur) {
		len++;
		cur = cur->next;
	}
	items = 0;
	buf[items++] = cpu_to_le32(len);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items2 != items)
		return POLICYDB_ERROR;
	cur = avrule->perms;
	while (cur) {
		items = 0;
		buf[items++] = cpu_to_le32(cur->tclass);
		buf[items++] = cpu_to_le32(cur->data);
		items2 = put_entry(buf, sizeof(uint32_t), items, fp);
		if (items2 != items)
			return POLICYDB_ERROR;

		cur = cur->next;
	}

	return POLICYDB_SUCCESS;
}

static int avrule_write_list(avrule_t * avrules, struct policy_file *fp)
{
	uint32_t buf[32], len;
	avrule_t *avrule;

	avrule = avrules;
	len = 0;
	while (avrule) {
		len++;
		avrule = avrule->next;
	}

	buf[0] = cpu_to_le32(len);
	if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1)
		return POLICYDB_ERROR;

	avrule = avrules;
	while (avrule) {
		if (avrule_write(avrule, fp))
			return POLICYDB_ERROR;
		avrule = avrule->next;
	}

	return POLICYDB_SUCCESS;
}

static int only_process(ebitmap_t *in)
{
	unsigned int i;
	ebitmap_node_t *node;

	ebitmap_for_each_bit(in, node, i) {
		if (ebitmap_node_get_bit(node, i) &&
		    i != SECCLASS_PROCESS - 1)
			return 0;
	}
	return 1;
}

static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t,
				 struct policy_file *fp)
{
	int nel = 0;
	size_t items;
	uint32_t buf[1];
	role_trans_rule_t *tr;
	int warned = 0;
	int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS;

	for (tr = t; tr; tr = tr->next)
		if (new_role || only_process(&tr->classes))
			nel++;

	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (tr = t; tr; tr = tr->next) {
		if (!new_role && !only_process(&tr->classes)) {
			if (!warned)
				WARN(fp->handle, "Discarding role_transition "
					"rules for security classes other than "
					"\"process\"");
			warned = 1;
			continue;
		}
		if (role_set_write(&tr->roles, fp))
			return POLICYDB_ERROR;
		if (type_set_write(&tr->types, fp))
			return POLICYDB_ERROR;
		if (new_role)
			if (ebitmap_write(&tr->classes, fp))
				return POLICYDB_ERROR;
		buf[0] = cpu_to_le32(tr->new_role);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

static int role_allow_rule_write(role_allow_rule_t * r, struct policy_file *fp)
{
	int nel = 0;
	size_t items;
	uint32_t buf[1];
	role_allow_rule_t *ra;

	for (ra = r; ra; ra = ra->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (ra = r; ra; ra = ra->next) {
		if (role_set_write(&ra->roles, fp))
			return POLICYDB_ERROR;
		if (role_set_write(&ra->new_roles, fp))
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

static int filename_trans_rule_write(filename_trans_rule_t * t, struct policy_file *fp)
{
	int nel = 0;
	size_t items;
	uint32_t buf[2], len;
	filename_trans_rule_t *ftr;

	for (ftr = t; ftr; ftr = ftr->next)
		nel++;

	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;

	for (ftr = t; ftr; ftr = ftr->next) {
		len = strlen(ftr->name);
		buf[0] = cpu_to_le32(len);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;

		items = put_entry(ftr->name, sizeof(char), len, fp);
		if (items != len)
			return POLICYDB_ERROR;

		if (type_set_write(&ftr->stypes, fp))
			return POLICYDB_ERROR;
		if (type_set_write(&ftr->ttypes, fp))
			return POLICYDB_ERROR;

		buf[0] = cpu_to_le32(ftr->tclass);
		buf[1] = cpu_to_le32(ftr->otype);

		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

static int range_trans_rule_write(range_trans_rule_t * t,
				  struct policy_file *fp)
{
	int nel = 0;
	size_t items;
	uint32_t buf[1];
	range_trans_rule_t *rt;

	for (rt = t; rt; rt = rt->next)
		nel++;
	buf[0] = cpu_to_le32(nel);
	items = put_entry(buf, sizeof(uint32_t), 1, fp);
	if (items != 1)
		return POLICYDB_ERROR;
	for (rt = t; rt; rt = rt->next) {
		if (type_set_write(&rt->stypes, fp))
			return POLICYDB_ERROR;
		if (type_set_write(&rt->ttypes, fp))
			return POLICYDB_ERROR;
		if (ebitmap_write(&rt->tclasses, fp))
			return POLICYDB_ERROR;
		if (mls_write_semantic_range_helper(&rt->trange, fp))
			return POLICYDB_ERROR;
	}
	return POLICYDB_SUCCESS;
}

static int scope_index_write(scope_index_t * scope_index,
			     unsigned int num_scope_syms,
			     struct policy_file *fp)
{
	unsigned int i;
	uint32_t buf[1];
	for (i = 0; i < num_scope_syms; i++) {
		if (ebitmap_write(scope_index->scope + i, fp) == -1) {
			return POLICYDB_ERROR;
		}
	}
	buf[0] = cpu_to_le32(scope_index->class_perms_len);
	if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
		return POLICYDB_ERROR;
	}
	for (i = 0; i < scope_index->class_perms_len; i++) {
		if (ebitmap_write(scope_index->class_perms_map + i, fp) == -1) {
			return POLICYDB_ERROR;
		}
	}
	return POLICYDB_SUCCESS;
}

static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms,
			     policydb_t * p, struct policy_file *fp)
{
	struct policy_data pd;
	uint32_t buf[2];
	int i;
	buf[0] = cpu_to_le32(decl->decl_id);
	buf[1] = cpu_to_le32(decl->enabled);
	if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) {
		return POLICYDB_ERROR;
	}
	if (cond_write_list(p, decl->cond_list, fp) == -1 ||
	    avrule_write_list(decl->avrules, fp) == -1 ||
	    role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 ||
	    role_allow_rule_write(decl->role_allow_rules, fp) == -1) {
		return POLICYDB_ERROR;
	}

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

	if (p->policyvers >= MOD_POLICYDB_VERSION_RANGETRANS &&
	    range_trans_rule_write(decl->range_tr_rules, fp) == -1) {
		return POLICYDB_ERROR;
	}
	if (scope_index_write(&decl->required, num_scope_syms, fp) == -1 ||
	    scope_index_write(&decl->declared, num_scope_syms, fp) == -1) {
		return POLICYDB_ERROR;
	}
	pd.fp = fp;
	pd.p = p;
	for (i = 0; i < num_scope_syms; i++) {
		buf[0] = cpu_to_le32(decl->symtab[i].nprim);
		buf[1] = cpu_to_le32(decl->symtab[i].table->nel);
		if (put_entry(buf, sizeof(uint32_t), 2, fp) != 2) {
			return POLICYDB_ERROR;
		}
		if (hashtab_map(decl->symtab[i].table, write_f[i], &pd)) {
			return POLICYDB_ERROR;
		}
	}
	return POLICYDB_SUCCESS;
}

static int avrule_block_write(avrule_block_t * block, int num_scope_syms,
			      policydb_t * p, struct policy_file *fp)
{
	/* first write a count of the total number of blocks */
	uint32_t buf[1], num_blocks = 0;
	avrule_block_t *cur;
	for (cur = block; cur != NULL; cur = cur->next) {
		num_blocks++;
	}
	buf[0] = cpu_to_le32(num_blocks);
	if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
		return POLICYDB_ERROR;
	}

	/* now write each block */
	for (cur = block; cur != NULL; cur = cur->next) {
		uint32_t num_decls = 0;
		avrule_decl_t *decl;
		/* write a count of number of branches */
		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
			num_decls++;
		}
		buf[0] = cpu_to_le32(num_decls);
		if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
			return POLICYDB_ERROR;
		}
		for (decl = cur->branch_list; decl != NULL; decl = decl->next) {
			if (avrule_decl_write(decl, num_scope_syms, p, fp) ==
			    -1) {
				return POLICYDB_ERROR;
			}
		}
	}
	return POLICYDB_SUCCESS;
}

static int scope_write(hashtab_key_t key, hashtab_datum_t datum, void *ptr)
{
	scope_datum_t *scope = (scope_datum_t *) datum;
	struct policy_data *pd = ptr;
	struct policy_file *fp = pd->fp;
	uint32_t static_buf[32], *dyn_buf = NULL, *buf;
	size_t key_len = strlen(key);
	unsigned int items = 2 + scope->decl_ids_len, i;
	int rc;

	buf = static_buf;
	if (items >= (sizeof(static_buf) / 4)) {
		/* too many things required, so dynamically create a
		 * buffer.  this would have been easier with C99's
		 * dynamic arrays... */
		rc = POLICYDB_ERROR;
		dyn_buf = malloc(items * sizeof(*dyn_buf));
		if (!dyn_buf)
			goto err;
		buf = dyn_buf;
	}
	buf[0] = cpu_to_le32(key_len);

	rc = POLICYDB_ERROR;
	if (put_entry(buf, sizeof(*buf), 1, fp) != 1 ||
	    put_entry(key, 1, key_len, fp) != key_len)
		goto err;
	buf[0] = cpu_to_le32(scope->scope);
	buf[1] = cpu_to_le32(scope->decl_ids_len);

	for (i = 0; i < scope->decl_ids_len; i++)
		buf[2 + i] = cpu_to_le32(scope->decl_ids[i]);

	rc = POLICYDB_ERROR;
	if (put_entry(buf, sizeof(*buf), items, fp) != items)
		goto err;
	rc = POLICYDB_SUCCESS;
err:
	free(dyn_buf);
	return rc;
}

static int type_attr_uncount(hashtab_key_t key __attribute__ ((unused)),
			     hashtab_datum_t datum, void *args)
{
	type_datum_t *typdatum = datum;
	uint32_t *p_nel = args;

	if (typdatum->flavor == TYPE_ATTRIB) {
		/* uncount attribute from total number of types */
		(*p_nel)--;
	}
	return 0;
}

static int role_attr_uncount(hashtab_key_t key __attribute__ ((unused)),
			     hashtab_datum_t datum, void *args)
{
	role_datum_t *role = datum;
	uint32_t *p_nel = args;

	if (role->flavor == ROLE_ATTRIB) {
		/* uncount attribute from total number of roles */
		(*p_nel)--;
	}
	return 0;
}

/*
 * Write the configuration data in a policy database
 * structure to a policy database binary representation
 * file.
 */
int policydb_write(policydb_t * p, struct policy_file *fp)
{
	unsigned int i, num_syms;
	uint32_t buf[32], config;
	size_t items, items2, len;
	struct policydb_compat_info *info;
	struct policy_data pd;
	const char *policydb_str;

	if (p->unsupported_format)
		return POLICYDB_UNSUPPORTED;

	pd.fp = fp;
	pd.p = p;

	config = 0;
	if (p->mls) {
		if ((p->policyvers < POLICYDB_VERSION_MLS &&
		    p->policy_type == POLICY_KERN) ||
		    (p->policyvers < MOD_POLICYDB_VERSION_MLS &&
		    p->policy_type == POLICY_BASE) ||
		    (p->policyvers < MOD_POLICYDB_VERSION_MLS &&
		    p->policy_type == POLICY_MOD)) {
			ERR(fp->handle, "policy version %d cannot support MLS",
			    p->policyvers);
			return POLICYDB_ERROR;
		}
		config |= POLICYDB_CONFIG_MLS;
	}

	config |= (POLICYDB_CONFIG_UNKNOWN_MASK & p->handle_unknown);

	/* Write the magic number and string identifiers. */
	items = 0;
	if (p->policy_type == POLICY_KERN) {
		buf[items++] = cpu_to_le32(POLICYDB_MAGIC);
		len = strlen(policydb_target_strings[p->target_platform]);
		policydb_str = policydb_target_strings[p->target_platform];
	} else {
		buf[items++] = cpu_to_le32(POLICYDB_MOD_MAGIC);
		len = strlen(POLICYDB_MOD_STRING);
		policydb_str = POLICYDB_MOD_STRING;
	}
	buf[items++] = cpu_to_le32(len);
	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;
	items = put_entry(policydb_str, 1, len, fp);
	if (items != len)
		return POLICYDB_ERROR;

	/* Write the version, config, and table sizes. */
	items = 0;
	info = policydb_lookup_compat(p->policyvers, p->policy_type,
					p->target_platform);
	if (!info) {
		ERR(fp->handle, "compatibility lookup failed for policy "
		    "version %d", p->policyvers);
		return POLICYDB_ERROR;
	}

	if (p->policy_type != POLICY_KERN) {
		buf[items++] = cpu_to_le32(p->policy_type);
	}
	buf[items++] = cpu_to_le32(p->policyvers);
	buf[items++] = cpu_to_le32(config);
	buf[items++] = cpu_to_le32(info->sym_num);
	buf[items++] = cpu_to_le32(info->ocon_num);

	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
	if (items != items2)
		return POLICYDB_ERROR;

	if (p->policy_type == POLICY_MOD) {
		/* Write module name and version */
		len = strlen(p->name);
		buf[0] = cpu_to_le32(len);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		items = put_entry(p->name, 1, len, fp);
		if (items != len)
			return POLICYDB_ERROR;
		len = strlen(p->version);
		buf[0] = cpu_to_le32(len);
		items = put_entry(buf, sizeof(uint32_t), 1, fp);
		if (items != 1)
			return POLICYDB_ERROR;
		items = put_entry(p->version, 1, len, fp);
		if (items != len)
			return POLICYDB_ERROR;
	}

	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_write(&p->policycaps, fp) == -1)
			return POLICYDB_ERROR;
	}

	if (p->policyvers < POLICYDB_VERSION_PERMISSIVE &&
	    p->policy_type == POLICY_KERN) {
		ebitmap_node_t *tnode;

		ebitmap_for_each_bit(&p->permissive_map, tnode, i) {
			if (ebitmap_node_get_bit(tnode, i)) {
				WARN(fp->handle, "Warning! Policy version %d cannot "
				     "support permissive types, but some were defined",
				     p->policyvers);
				break;
			}
		}
	}

	if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
	    p->policy_type == POLICY_KERN) {
		if (ebitmap_write(&p->permissive_map, fp) == -1)
			return POLICYDB_ERROR;
	}

	num_syms = info->sym_num;
	for (i = 0; i < num_syms; i++) {
		buf[0] = cpu_to_le32(p->symtab[i].nprim);
		buf[1] = p->symtab[i].table->nel;

		/*
		 * A special case when writing type/attribute symbol table.
		 * The kernel policy version less than 24 does not support
		 * to load entries of attribute, so we have to re-calculate
		 * the actual number of types except for attributes.
		 */
		if (i == SYM_TYPES &&
		    p->policyvers < POLICYDB_VERSION_BOUNDARY &&
		    p->policy_type == POLICY_KERN) {
			hashtab_map(p->symtab[i].table, type_attr_uncount, &buf[1]);
		}

		/*
		 * Another special case when writing role/attribute symbol
		 * table, role attributes are redundant for policy.X, or
		 * when the pp's version is not big enough. So deduct
		 * their numbers from p_roles.table->nel.
		 */
		if ((i == SYM_ROLES) &&
		    ((p->policy_type == POLICY_KERN) ||
		     (p->policy_type != POLICY_KERN &&
		      p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB)))
			(void)hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]);

		buf[1] = cpu_to_le32(buf[1]);
		items = put_entry(buf, sizeof(uint32_t), 2, fp);
		if (items != 2)
			return POLICYDB_ERROR;
		if (hashtab_map(p->symtab[i].table, write_f[i], &pd))
			return POLICYDB_ERROR;
	}

	if (p->policy_type == POLICY_KERN) {
		if (avtab_write(p, &p->te_avtab, fp))
			return POLICYDB_ERROR;
		if (p->policyvers < POLICYDB_VERSION_BOOL) {
			if (p->p_bools.nprim)
				WARN(fp->handle, "Discarding "
				     "booleans and conditional rules");
		} else {
			if (cond_write_list(p, p->cond_list, fp))
				return POLICYDB_ERROR;
		}
		if (role_trans_write(p, fp))
			return POLICYDB_ERROR;
		if (role_allow_write(p->role_allow, fp))
			return POLICYDB_ERROR;
		if (p->policyvers >= POLICYDB_VERSION_FILENAME_TRANS) {
			if (filename_trans_write(p->filename_trans, fp))
				return POLICYDB_ERROR;
		} else {
			if (p->filename_trans)
				WARN(fp->handle, "Discarding filename type transition rules");
		}
	} else {
		if (avrule_block_write(p->global, num_syms, p, fp) == -1) {
			return POLICYDB_ERROR;
		}

		for (i = 0; i < num_syms; i++) {
			buf[0] = cpu_to_le32(p->scope[i].table->nel);
			if (put_entry(buf, sizeof(uint32_t), 1, fp) != 1) {
				return POLICYDB_ERROR;
			}
			if (hashtab_map(p->scope[i].table, scope_write, &pd))
				return POLICYDB_ERROR;
		}
	}

	if (ocontext_write(info, p, fp) == -1 || genfs_write(p, fp) == -1) {
		return POLICYDB_ERROR;
	}

	if ((p->policyvers >= POLICYDB_VERSION_MLS
	     && p->policy_type == POLICY_KERN)
	    || (p->policyvers >= MOD_POLICYDB_VERSION_MLS
		&& p->policyvers < MOD_POLICYDB_VERSION_RANGETRANS
		&& p->policy_type == POLICY_BASE)) {
		if (range_write(p, fp)) {
			return POLICYDB_ERROR;
		}
	}

	if (p->policy_type == POLICY_KERN
	    && p->policyvers >= POLICYDB_VERSION_AVTAB) {
		for (i = 0; i < p->p_types.nprim; i++) {
			if (ebitmap_write(&p->type_attr_map[i], fp) == -1)
				return POLICYDB_ERROR;
		}
	}

	return POLICYDB_SUCCESS;
}
