
/* 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_IOCTL_OPERATIONS) &&
			(cur->key.specified & AVTAB_OP)) {
		ERR(fp->handle, "policy version %u does not support ioctl operation"
				" rules and one was specified", p->policyvers);
		return POLICYDB_ERROR;
	}

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

	if (cur->key.specified & AVTAB_OP) {
		buf8 = cur->datum.ops->type;
		items = put_entry(&buf8, sizeof(uint8_t),1,fp);
		if (items != 1)
			return POLICYDB_ERROR;
		for (i = 0; i < ARRAY_SIZE(cur->datum.ops->perms); i++)
			buf32[i] = cpu_to_le32(cur->datum.ops->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_OP) {
		ERR(fp->handle, "module policy does not support ioctl operation"
				" 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;
}
