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

/* FLASK */

/*
 * Implementation of the security services.
 */

/* Initial sizes malloc'd for sepol_compute_av_reason_buffer() support */
#define REASON_BUF_SIZE 2048
#define EXPR_BUF_SIZE 1024
#define STACK_LEN 32

#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <sepol/policydb/policydb.h>
#include <sepol/policydb/sidtab.h>
#include <sepol/policydb/services.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/flask.h>
#include <sepol/policydb/util.h>

#include "debug.h"
#include "private.h"
#include "context.h"
#include "av_permissions.h"
#include "dso.h"
#include "mls.h"

#define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)
#define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)

static int selinux_enforcing = 1;

static sidtab_t mysidtab, *sidtab = &mysidtab;
static policydb_t mypolicydb, *policydb = &mypolicydb;

/* Used by sepol_compute_av_reason_buffer() to keep track of entries */
static int reason_buf_used;
static int reason_buf_len;

/* Stack services for RPN to infix conversion. */
static char **stack;
static int stack_len;
static int next_stack_entry;

static void push(char *expr_ptr)
{
	if (next_stack_entry >= stack_len) {
		char **new_stack = stack;
		int new_stack_len;

		if (stack_len == 0)
			new_stack_len = STACK_LEN;
		else
			new_stack_len = stack_len * 2;

		new_stack = realloc(stack, new_stack_len * sizeof(*stack));
		if (!new_stack) {
			ERR(NULL, "unable to allocate stack space");
			return;
		}
		stack_len = new_stack_len;
		stack = new_stack;
	}
	stack[next_stack_entry] = expr_ptr;
	next_stack_entry++;
}

static char *pop(void)
{
	next_stack_entry--;
	if (next_stack_entry < 0) {
		next_stack_entry = 0;
		ERR(NULL, "pop called with no stack entries");
		return NULL;
	}
	return stack[next_stack_entry];
}
/* End Stack services */

int hidden sepol_set_sidtab(sidtab_t * s)
{
	sidtab = s;
	return 0;
}

int hidden sepol_set_policydb(policydb_t * p)
{
	policydb = p;
	return 0;
}

int sepol_set_policydb_from_file(FILE * fp)
{
	struct policy_file pf;

	policy_file_init(&pf);
	pf.fp = fp;
	pf.type = PF_USE_STDIO;
	if (mypolicydb.policy_type)
		policydb_destroy(&mypolicydb);
	if (policydb_init(&mypolicydb)) {
		ERR(NULL, "Out of memory!");
		return -1;
	}
	if (policydb_read(&mypolicydb, &pf, 0)) {
		policydb_destroy(&mypolicydb);
		ERR(NULL, "can't read binary policy: %s", strerror(errno));
		return -1;
	}
	policydb = &mypolicydb;
	return sepol_sidtab_init(sidtab);
}

/*
 * The largest sequence number that has been used when
 * providing an access decision to the access vector cache.
 * The sequence number only changes when a policy change
 * occurs.
 */
static uint32_t latest_granting = 0;

/*
 * cat_expr_buf adds a string to an expression buffer and handles
 * realloc's if buffer is too small. The array of expression text
 * buffer pointers and its counter are globally defined here as
 * constraint_expr_eval_reason() sets them up and cat_expr_buf
 * updates the e_buf pointer.
 */
static int expr_counter;
static char **expr_list;
static int expr_buf_used;
static int expr_buf_len;

static void cat_expr_buf(char *e_buf, const char *string)
{
	int len, new_buf_len;
	char *p, *new_buf = e_buf;

	while (1) {
		p = e_buf + expr_buf_used;
		len = snprintf(p, expr_buf_len - expr_buf_used, "%s", string);
		if (len < 0 || len >= expr_buf_len - expr_buf_used) {
			new_buf_len = expr_buf_len + EXPR_BUF_SIZE;
			new_buf = realloc(e_buf, new_buf_len);
			if (!new_buf) {
				ERR(NULL, "failed to realloc expr buffer");
				return;
			}
			/* Update new ptr in expr list and locally + new len */
			expr_list[expr_counter] = new_buf;
			e_buf = new_buf;
			expr_buf_len = new_buf_len;
		} else {
			expr_buf_used += len;
			return;
		}
	}
}

/*
 * If the POLICY_KERN version is >= POLICYDB_VERSION_CONSTRAINT_NAMES,
 * then for 'types' only, read the types_names->types list as it will
 * contain a list of types and attributes that were defined in the
 * policy source.
 * For user and role plus types (for policy vers <
 * POLICYDB_VERSION_CONSTRAINT_NAMES) just read the e->names list.
 */
static void get_name_list(constraint_expr_t *e, int type,
							const char *src, const char *op, int failed)
{
	ebitmap_t *types;
	int rc = 0;
	unsigned int i;
	char tmp_buf[128];
	int counter = 0;

	if (policydb->policy_type == POLICY_KERN &&
			policydb->policyvers >= POLICYDB_VERSION_CONSTRAINT_NAMES &&
			type == CEXPR_TYPE)
		types = &e->type_names->types;
	else
		types = &e->names;

	/* Find out how many entries */
	for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) {
		rc = ebitmap_get_bit(types, i);
		if (rc == 0)
			continue;
		else
			counter++;
	}
	snprintf(tmp_buf, sizeof(tmp_buf), "(%s%s", src, op);
	cat_expr_buf(expr_list[expr_counter], tmp_buf);

	if (counter == 0)
		cat_expr_buf(expr_list[expr_counter], "<empty_set> ");
	if (counter > 1)
		cat_expr_buf(expr_list[expr_counter], " {");
	if (counter >= 1) {
		for (i = ebitmap_startbit(types); i < ebitmap_length(types); i++) {
			rc = ebitmap_get_bit(types, i);
			if (rc == 0)
				continue;

			/* Collect entries */
			switch (type) {
			case CEXPR_USER:
				snprintf(tmp_buf, sizeof(tmp_buf), " %s",
							policydb->p_user_val_to_name[i]);
				break;
			case CEXPR_ROLE:
				snprintf(tmp_buf, sizeof(tmp_buf), " %s",
							policydb->p_role_val_to_name[i]);
				break;
			case CEXPR_TYPE:
				snprintf(tmp_buf, sizeof(tmp_buf), " %s",
							policydb->p_type_val_to_name[i]);
				break;
			}
			cat_expr_buf(expr_list[expr_counter], tmp_buf);
		}
	}
	if (counter > 1)
		cat_expr_buf(expr_list[expr_counter], " }");
	if (failed)
		cat_expr_buf(expr_list[expr_counter], " -Fail-) ");
	else
		cat_expr_buf(expr_list[expr_counter], ") ");

	return;
}

static void msgcat(const char *src, const char *tgt, const char *op, int failed)
{
	char tmp_buf[128];
	if (failed)
		snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s -Fail-) ",
				src, op, tgt);
	else
		snprintf(tmp_buf, sizeof(tmp_buf), "(%s %s %s) ",
				src, op, tgt);
	cat_expr_buf(expr_list[expr_counter], tmp_buf);
}

/* Returns a buffer with class, statement type and permissions */
static char *get_class_info(sepol_security_class_t tclass,
							constraint_node_t *constraint,
							context_struct_t *xcontext)
{
	constraint_expr_t *e;
	int mls, state_num;

	/* Find if MLS statement or not */
	mls = 0;
	for (e = constraint->expr; e; e = e->next) {
		if (e->attr >= CEXPR_L1L2) {
			mls = 1;
			break;
		}
	}

	/* Determine statement type */
	const char *statements[] = {
		"constrain ",			/* 0 */
		"mlsconstrain ",		/* 1 */
		"validatetrans ",		/* 2 */
		"mlsvalidatetrans ",	/* 3 */
		0 };

	if (xcontext == NULL)
		state_num = mls + 0;
	else
		state_num = mls + 2;

	int class_buf_len = 0;
	int new_class_buf_len;
	int len, buf_used;
	char *class_buf = NULL, *p;
	char *new_class_buf = NULL;

	while (1) {
		new_class_buf_len = class_buf_len + EXPR_BUF_SIZE;
		new_class_buf = realloc(class_buf, new_class_buf_len);
			if (!new_class_buf)
				return NULL;
		class_buf_len = new_class_buf_len;
		class_buf = new_class_buf;
		buf_used = 0;
		p = class_buf;

		/* Add statement type */
		len = snprintf(p, class_buf_len - buf_used, "%s", statements[state_num]);
		if (len < 0 || len >= class_buf_len - buf_used)
			continue;

		/* Add class entry */
		p += len;
		buf_used += len;
		len = snprintf(p, class_buf_len - buf_used, "%s ",
				policydb->p_class_val_to_name[tclass - 1]);
		if (len < 0 || len >= class_buf_len - buf_used)
			continue;

		/* Add permission entries (validatetrans does not have perms) */
		p += len;
		buf_used += len;
		if (state_num < 2) {
			len = snprintf(p, class_buf_len - buf_used, "{%s } (",
			sepol_av_to_string(policydb, tclass,
				constraint->permissions));
		} else {
			len = snprintf(p, class_buf_len - buf_used, "(");
		}
		if (len < 0 || len >= class_buf_len - buf_used)
			continue;
		break;
	}
	return class_buf;
}

/*
 * Modified version of constraint_expr_eval that will process each
 * constraint as before but adds the information to text buffers that
 * will hold various components. The expression will be in RPN format,
 * therefore there is a stack based RPN to infix converter to produce
 * the final readable constraint.
 *
 * Return the boolean value of a constraint expression
 * when it is applied to the specified source and target
 * security contexts.
 *
 * xcontext is a special beast...  It is used by the validatetrans rules
 * only.  For these rules, scontext is the context before the transition,
 * tcontext is the context after the transition, and xcontext is the
 * context of the process performing the transition.  All other callers
 * of constraint_expr_eval_reason should pass in NULL for xcontext.
 *
 * This function will also build a buffer as the constraint is processed
 * for analysis. If this option is not required, then:
 *      'tclass' should be '0' and r_buf MUST be NULL.
 */
static int constraint_expr_eval_reason(context_struct_t *scontext,
				context_struct_t *tcontext,
				context_struct_t *xcontext,
				sepol_security_class_t tclass,
				constraint_node_t *constraint,
				char **r_buf,
				unsigned int flags)
{
	uint32_t val1, val2;
	context_struct_t *c;
	role_datum_t *r1, *r2;
	mls_level_t *l1, *l2;
	constraint_expr_t *e;
	int s[CEXPR_MAXDEPTH];
	int sp = -1;
	char tmp_buf[128];

/*
 * Define the s_t_x_num values that make up r1, t2 etc. in text strings
 * Set 1 = source, 2 = target, 3 = xcontext for validatetrans
 */
#define SOURCE  1
#define TARGET  2
#define XTARGET 3

	int s_t_x_num = SOURCE;

	/* Set 0 = fail, u = CEXPR_USER, r = CEXPR_ROLE, t = CEXPR_TYPE */
	int u_r_t = 0;

	char *src = NULL;
	char *tgt = NULL;
	int rc = 0, x;
	char *class_buf = NULL;

	/*
	 * The array of expression answer buffer pointers and counter.
	 */
	char **answer_list = NULL;
	int answer_counter = 0;

	class_buf = get_class_info(tclass, constraint, xcontext);
	if (!class_buf) {
		ERR(NULL, "failed to allocate class buffer");
		return -ENOMEM;
	}

	/* Original function but with buffer support */
	int expr_list_len = 0;
	expr_counter = 0;
	expr_list = NULL;
	for (e = constraint->expr; e; e = e->next) {
		/* Allocate a stack to hold expression buffer entries */
		if (expr_counter >= expr_list_len) {
			char **new_expr_list = expr_list;
			int new_expr_list_len;

			if (expr_list_len == 0)
				new_expr_list_len = STACK_LEN;
			else
				new_expr_list_len = expr_list_len * 2;

			new_expr_list = realloc(expr_list,
					new_expr_list_len * sizeof(*expr_list));
			if (!new_expr_list) {
				ERR(NULL, "failed to allocate expr buffer stack");
				rc = -ENOMEM;
				goto out;
			}
			expr_list_len = new_expr_list_len;
			expr_list = new_expr_list;
		}

		/*
		 * malloc a buffer to store each expression text component. If
		 * buffer is too small cat_expr_buf() will realloc extra space.
		 */
		expr_buf_len = EXPR_BUF_SIZE;
		expr_list[expr_counter] = malloc(expr_buf_len);
		if (!expr_list[expr_counter]) {
			ERR(NULL, "failed to allocate expr buffer");
			rc = -ENOMEM;
			goto out;
		}
		expr_buf_used = 0;

		/* Now process each expression of the constraint */
		switch (e->expr_type) {
		case CEXPR_NOT:
			BUG_ON(sp < 0);
			s[sp] = !s[sp];
			cat_expr_buf(expr_list[expr_counter], "not");
			break;
		case CEXPR_AND:
			BUG_ON(sp < 1);
			sp--;
			s[sp] &= s[sp + 1];
			cat_expr_buf(expr_list[expr_counter], "and");
			break;
		case CEXPR_OR:
			BUG_ON(sp < 1);
			sp--;
			s[sp] |= s[sp + 1];
			cat_expr_buf(expr_list[expr_counter], "or");
			break;
		case CEXPR_ATTR:
			if (sp == (CEXPR_MAXDEPTH - 1))
				goto out;

			switch (e->attr) {
			case CEXPR_USER:
				val1 = scontext->user;
				val2 = tcontext->user;
				free(src); src = strdup("u1");
				free(tgt); tgt = strdup("u2");
				break;
			case CEXPR_TYPE:
				val1 = scontext->type;
				val2 = tcontext->type;
				free(src); src = strdup("t1");
				free(tgt); tgt = strdup("t2");
				break;
			case CEXPR_ROLE:
				val1 = scontext->role;
				val2 = tcontext->role;
				r1 = policydb->role_val_to_struct[val1 - 1];
				r2 = policydb->role_val_to_struct[val2 - 1];
				free(src); src = strdup("r1");
				free(tgt); tgt = strdup("r2");

				switch (e->op) {
				case CEXPR_DOM:
					s[++sp] = ebitmap_get_bit(&r1->dominates, val2 - 1);
					msgcat(src, tgt, "dom", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_DOMBY:
					s[++sp] = ebitmap_get_bit(&r2->dominates, val1 - 1);
					msgcat(src, tgt, "domby", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_INCOMP:
					s[++sp] = (!ebitmap_get_bit(&r1->dominates, val2 - 1)
						 && !ebitmap_get_bit(&r2->dominates, val1 - 1));
					msgcat(src, tgt, "incomp", s[sp] == 0);
					expr_counter++;
					continue;
				default:
					break;
				}
				break;
			case CEXPR_L1L2:
				l1 = &(scontext->range.level[0]);
				l2 = &(tcontext->range.level[0]);
				free(src); src = strdup("l1");
				free(tgt); tgt = strdup("l2");
				goto mls_ops;
			case CEXPR_L1H2:
				l1 = &(scontext->range.level[0]);
				l2 = &(tcontext->range.level[1]);
				free(src); src = strdup("l1");
				free(tgt); tgt = strdup("h2");
				goto mls_ops;
			case CEXPR_H1L2:
				l1 = &(scontext->range.level[1]);
				l2 = &(tcontext->range.level[0]);
				free(src); src = strdup("h1");
				free(tgt); tgt = strdup("l2");
				goto mls_ops;
			case CEXPR_H1H2:
				l1 = &(scontext->range.level[1]);
				l2 = &(tcontext->range.level[1]);
				free(src); src = strdup("h1");
				free(tgt); tgt = strdup("h2");
				goto mls_ops;
			case CEXPR_L1H1:
				l1 = &(scontext->range.level[0]);
				l2 = &(scontext->range.level[1]);
				free(src); src = strdup("l1");
				free(tgt); tgt = strdup("h1");
				goto mls_ops;
			case CEXPR_L2H2:
				l1 = &(tcontext->range.level[0]);
				l2 = &(tcontext->range.level[1]);
				free(src); src = strdup("l2");
				free(tgt); tgt = strdup("h2");
mls_ops:
				switch (e->op) {
				case CEXPR_EQ:
					s[++sp] = mls_level_eq(l1, l2);
					msgcat(src, tgt, "eq", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_NEQ:
					s[++sp] = !mls_level_eq(l1, l2);
					msgcat(src, tgt, "!=", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_DOM:
					s[++sp] = mls_level_dom(l1, l2);
					msgcat(src, tgt, "dom", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_DOMBY:
					s[++sp] = mls_level_dom(l2, l1);
					msgcat(src, tgt, "domby", s[sp] == 0);
					expr_counter++;
					continue;
				case CEXPR_INCOMP:
					s[++sp] = mls_level_incomp(l2, l1);
					msgcat(src, tgt, "incomp", s[sp] == 0);
					expr_counter++;
					continue;
				default:
					BUG();
					goto out;
				}
				break;
			default:
				BUG();
				goto out;
			}

			switch (e->op) {
			case CEXPR_EQ:
				s[++sp] = (val1 == val2);
				msgcat(src, tgt, "==", s[sp] == 0);
				break;
			case CEXPR_NEQ:
				s[++sp] = (val1 != val2);
				msgcat(src, tgt, "!=", s[sp] == 0);
				break;
			default:
				BUG();
				goto out;
			}
			break;
		case CEXPR_NAMES:
			if (sp == (CEXPR_MAXDEPTH - 1))
				goto out;
			s_t_x_num = SOURCE;
			c = scontext;
			if (e->attr & CEXPR_TARGET) {
				s_t_x_num = TARGET;
				c = tcontext;
			} else if (e->attr & CEXPR_XTARGET) {
				s_t_x_num = XTARGET;
				c = xcontext;
			}
			if (!c) {
				BUG();
				goto out;
			}
			if (e->attr & CEXPR_USER) {
				u_r_t = CEXPR_USER;
				val1 = c->user;
				snprintf(tmp_buf, sizeof(tmp_buf), "u%d ", s_t_x_num);
				free(src); src = strdup(tmp_buf);
			} else if (e->attr & CEXPR_ROLE) {
				u_r_t = CEXPR_ROLE;
				val1 = c->role;
				snprintf(tmp_buf, sizeof(tmp_buf), "r%d ", s_t_x_num);
				free(src); src = strdup(tmp_buf);
			} else if (e->attr & CEXPR_TYPE) {
				u_r_t = CEXPR_TYPE;
				val1 = c->type;
				snprintf(tmp_buf, sizeof(tmp_buf), "t%d ", s_t_x_num);
				free(src); src = strdup(tmp_buf);
			} else {
				BUG();
				goto out;
			}

			switch (e->op) {
			case CEXPR_EQ:
				s[++sp] = ebitmap_get_bit(&e->names, val1 - 1);
				get_name_list(e, u_r_t, src, "==", s[sp] == 0);
				break;

			case CEXPR_NEQ:
				s[++sp] = !ebitmap_get_bit(&e->names, val1 - 1);
				get_name_list(e, u_r_t, src, "!=", s[sp] == 0);
				break;
			default:
				BUG();
				goto out;
			}
			break;
		default:
			BUG();
			goto out;
		}
		expr_counter++;
	}

	/*
	 * At this point each expression of the constraint is in
	 * expr_list[n+1] and in RPN format. Now convert to 'infix'
	 */

	/*
	 * Save expr count but zero expr_counter to detect if
	 * 'BUG(); goto out;' was called as we need to release any used
	 * expr_list malloc's. Normally they are released by the RPN to
	 * infix code.
	 */
	int expr_count = expr_counter;
	expr_counter = 0;

	/*
	 * Generate the same number of answer buffer entries as expression
	 * buffers (as there will never be more).
	 */
	answer_list = malloc(expr_count * sizeof(*answer_list));
	if (!answer_list) {
		ERR(NULL, "failed to allocate answer stack");
		rc = -ENOMEM;
		goto out;
	}

	/* The pop operands */
	char *a;
	char *b;
	int a_len, b_len;

	/* Convert constraint from RPN to infix notation. */
	for (x = 0; x != expr_count; x++) {
		if (strncmp(expr_list[x], "and", 3) == 0 || strncmp(expr_list[x],
					"or", 2) == 0) {
			b = pop();
			b_len = strlen(b);
			a = pop();
			a_len = strlen(a);

			/* get a buffer to hold the answer */
			answer_list[answer_counter] = malloc(a_len + b_len + 8);
			if (!answer_list[answer_counter]) {
				ERR(NULL, "failed to allocate answer buffer");
				rc = -ENOMEM;
				goto out;
			}
			memset(answer_list[answer_counter], '\0', a_len + b_len + 8);

			sprintf(answer_list[answer_counter], "%s %s %s", a,
					expr_list[x], b);
			push(answer_list[answer_counter++]);
			free(a);
			free(b);
			free(expr_list[x]);
		} else if (strncmp(expr_list[x], "not", 3) == 0) {
			b = pop();
			b_len = strlen(b);

			answer_list[answer_counter] = malloc(b_len + 8);
			if (!answer_list[answer_counter]) {
				ERR(NULL, "failed to allocate answer buffer");
				rc = -ENOMEM;
				goto out;
			}
			memset(answer_list[answer_counter], '\0', b_len + 8);

			if (strncmp(b, "not", 3) == 0)
				sprintf(answer_list[answer_counter], "%s (%s)",
						expr_list[x], b);
			else
				sprintf(answer_list[answer_counter], "%s%s",
						expr_list[x], b);
			push(answer_list[answer_counter++]);
			free(b);
			free(expr_list[x]);
		} else {
			push(expr_list[x]);
		}
	}
	/* Get the final answer from tos and build constraint text */
	a = pop();

	/* validatetrans / constraint calculation:
				rc = 0 is denied, rc = 1 is granted */
	sprintf(tmp_buf, "%s %s\n",
			xcontext ? "Validatetrans" : "Constraint",
			s[0] ? "GRANTED" : "DENIED");

	int len, new_buf_len;
	char *p, **new_buf = r_buf;
	/*
	 * These contain the constraint components that are added to the
	 * callers reason buffer.
	 */
	const char *buffers[] = { class_buf, a, "); ", tmp_buf, 0 };

	/*
	 * This will add the constraints to the callers reason buffer (who is
	 * responsible for freeing the memory). It will handle any realloc's
	 * should the buffer be too short.
	 * The reason_buf_used and reason_buf_len counters are defined
	 * globally as multiple constraints can be in the buffer.
	 */

	if (r_buf && ((s[0] == 0) || ((s[0] == 1 &&
				(flags & SHOW_GRANTED) == SHOW_GRANTED)))) {
		for (x = 0; buffers[x] != NULL; x++) {
			while (1) {
				p = *r_buf + reason_buf_used;
				len = snprintf(p, reason_buf_len - reason_buf_used,
						"%s", buffers[x]);
				if (len < 0 || len >= reason_buf_len - reason_buf_used) {
					new_buf_len = reason_buf_len + REASON_BUF_SIZE;
					*new_buf = realloc(*r_buf, new_buf_len);
					if (!new_buf) {
						ERR(NULL, "failed to realloc reason buffer");
						goto out1;
					}
					**r_buf = **new_buf;
					reason_buf_len = new_buf_len;
					continue;
				} else {
					reason_buf_used += len;
					break;
				}
			}
		}
	}

out1:
	rc = s[0];
	free(a);

out:
	free(class_buf);
	free(src);
	free(tgt);

	if (expr_counter) {
		for (x = 0; expr_list[x] != NULL; x++)
			free(expr_list[x]);
	}
	free(answer_list);
	free(expr_list);
	return rc;
}

/* Forward declaration */
static int context_struct_compute_av(context_struct_t * scontext,
				     context_struct_t * tcontext,
				     sepol_security_class_t tclass,
				     sepol_access_vector_t requested,
				     struct sepol_av_decision *avd,
				     unsigned int *reason,
				     char **r_buf,
				     unsigned int flags);

static void type_attribute_bounds_av(context_struct_t *scontext,
				     context_struct_t *tcontext,
				     sepol_security_class_t tclass,
				     sepol_access_vector_t requested,
				     struct sepol_av_decision *avd,
				     unsigned int *reason)
{
	context_struct_t lo_scontext;
	context_struct_t lo_tcontext, *tcontextp = tcontext;
	struct sepol_av_decision lo_avd;
	type_datum_t *source;
	type_datum_t *target;
	sepol_access_vector_t masked = 0;

	source = policydb->type_val_to_struct[scontext->type - 1];
	if (!source->bounds)
		return;

	target = policydb->type_val_to_struct[tcontext->type - 1];

	memset(&lo_avd, 0, sizeof(lo_avd));

	memcpy(&lo_scontext, scontext, sizeof(lo_scontext));
	lo_scontext.type = source->bounds;

	if (target->bounds) {
		memcpy(&lo_tcontext, tcontext, sizeof(lo_tcontext));
		lo_tcontext.type = target->bounds;
		tcontextp = &lo_tcontext;
	}

	context_struct_compute_av(&lo_scontext,
				  tcontextp,
				  tclass,
				  requested,
				  &lo_avd,
				  NULL, /* reason intentionally omitted */
				  NULL,
				  0);

	masked = ~lo_avd.allowed & avd->allowed;

	if (!masked)
		return;		/* no masked permission */

	/* mask violated permissions */
	avd->allowed &= ~masked;

	*reason |= SEPOL_COMPUTEAV_BOUNDS;
}

/*
 * Compute access vectors based on a context structure pair for
 * the permissions in a particular class.
 */
static int context_struct_compute_av(context_struct_t * scontext,
				     context_struct_t * tcontext,
				     sepol_security_class_t tclass,
				     sepol_access_vector_t requested,
				     struct sepol_av_decision *avd,
				     unsigned int *reason,
				     char **r_buf,
				     unsigned int flags)
{
	constraint_node_t *constraint;
	struct role_allow *ra;
	avtab_key_t avkey;
	class_datum_t *tclass_datum;
	avtab_ptr_t node;
	ebitmap_t *sattr, *tattr;
	ebitmap_node_t *snode, *tnode;
	unsigned int i, j;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	/* 
	 * Initialize the access vectors to the default values.
	 */
	avd->allowed = 0;
	avd->decided = 0xffffffff;
	avd->auditallow = 0;
	avd->auditdeny = 0xffffffff;
	avd->seqno = latest_granting;
	if (reason)
		*reason = 0;

	/*
	 * If a specific type enforcement rule was defined for
	 * this permission check, then use it.
	 */
	avkey.target_class = tclass;
	avkey.specified = AVTAB_AV;
	sattr = &policydb->type_attr_map[scontext->type - 1];
	tattr = &policydb->type_attr_map[tcontext->type - 1];
	ebitmap_for_each_positive_bit(sattr, snode, i) {
		ebitmap_for_each_positive_bit(tattr, tnode, j) {
			avkey.source_type = i + 1;
			avkey.target_type = j + 1;
			for (node =
			     avtab_search_node(&policydb->te_avtab, &avkey);
			     node != NULL;
			     node =
			     avtab_search_node_next(node, avkey.specified)) {
				if (node->key.specified == AVTAB_ALLOWED)
					avd->allowed |= node->datum.data;
				else if (node->key.specified ==
					 AVTAB_AUDITALLOW)
					avd->auditallow |= node->datum.data;
				else if (node->key.specified == AVTAB_AUDITDENY)
					avd->auditdeny &= node->datum.data;
			}

			/* Check conditional av table for additional permissions */
			cond_compute_av(&policydb->te_cond_avtab, &avkey, avd);

		}
	}

	if (requested & ~avd->allowed) {
		if (reason)
			*reason |= SEPOL_COMPUTEAV_TE;
		requested &= avd->allowed;
	}

	/* 
	 * Remove any permissions prohibited by a constraint (this includes
	 * the MLS policy).
	 */
	constraint = tclass_datum->constraints;
	while (constraint) {
		if ((constraint->permissions & (avd->allowed)) &&
		    !constraint_expr_eval_reason(scontext, tcontext, NULL,
					  tclass, constraint, r_buf, flags)) {
			avd->allowed =
			    (avd->allowed) & ~(constraint->permissions);
		}
		constraint = constraint->next;
	}

	if (requested & ~avd->allowed) {
		if (reason)
			*reason |= SEPOL_COMPUTEAV_CONS;
		requested &= avd->allowed;
	}

	/* 
	 * If checking process transition permission and the
	 * role is changing, then check the (current_role, new_role) 
	 * pair.
	 */
	if (tclass == SECCLASS_PROCESS &&
	    (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) &&
	    scontext->role != tcontext->role) {
		for (ra = policydb->role_allow; ra; ra = ra->next) {
			if (scontext->role == ra->role &&
			    tcontext->role == ra->new_role)
				break;
		}
		if (!ra)
			avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION |
							  PROCESS__DYNTRANSITION);
	}

	if (requested & ~avd->allowed) {
		if (reason)
			*reason |= SEPOL_COMPUTEAV_RBAC;
		requested &= avd->allowed;
	}

	type_attribute_bounds_av(scontext, tcontext, tclass, requested, avd,
				 reason);
	return 0;
}

int hidden sepol_validate_transition(sepol_security_id_t oldsid,
				     sepol_security_id_t newsid,
				     sepol_security_id_t tasksid,
				     sepol_security_class_t tclass)
{
	context_struct_t *ocontext;
	context_struct_t *ncontext;
	context_struct_t *tcontext;
	class_datum_t *tclass_datum;
	constraint_node_t *constraint;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	ocontext = sepol_sidtab_search(sidtab, oldsid);
	if (!ocontext) {
		ERR(NULL, "unrecognized SID %d", oldsid);
		return -EINVAL;
	}

	ncontext = sepol_sidtab_search(sidtab, newsid);
	if (!ncontext) {
		ERR(NULL, "unrecognized SID %d", newsid);
		return -EINVAL;
	}

	tcontext = sepol_sidtab_search(sidtab, tasksid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tasksid);
		return -EINVAL;
	}

	constraint = tclass_datum->validatetrans;
	while (constraint) {
		if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext,
					  0, constraint, NULL, 0)) {
			return -EPERM;
		}
		constraint = constraint->next;
	}

	return 0;
}

/*
 * sepol_validate_transition_reason_buffer - the reason buffer is realloc'd
 * in the constraint_expr_eval_reason() function.
 */
int hidden sepol_validate_transition_reason_buffer(sepol_security_id_t oldsid,
				     sepol_security_id_t newsid,
				     sepol_security_id_t tasksid,
				     sepol_security_class_t tclass,
				     char **reason_buf,
				     unsigned int flags)
{
	context_struct_t *ocontext;
	context_struct_t *ncontext;
	context_struct_t *tcontext;
	class_datum_t *tclass_datum;
	constraint_node_t *constraint;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	ocontext = sepol_sidtab_search(sidtab, oldsid);
	if (!ocontext) {
		ERR(NULL, "unrecognized SID %d", oldsid);
		return -EINVAL;
	}

	ncontext = sepol_sidtab_search(sidtab, newsid);
	if (!ncontext) {
		ERR(NULL, "unrecognized SID %d", newsid);
		return -EINVAL;
	}

	tcontext = sepol_sidtab_search(sidtab, tasksid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tasksid);
		return -EINVAL;
	}

	/*
	 * Set the buffer to NULL as mls/validatetrans may not be processed.
	 * If a buffer is required, then the routines in
	 * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE
	 * chunks (as it gets called for each mls/validatetrans processed).
	 * We just make sure these start from zero.
	 */
	*reason_buf = NULL;
	reason_buf_used = 0;
	reason_buf_len = 0;
	constraint = tclass_datum->validatetrans;
	while (constraint) {
		if (!constraint_expr_eval_reason(ocontext, ncontext, tcontext,
				tclass, constraint, reason_buf, flags)) {
			return -EPERM;
		}
		constraint = constraint->next;
	}
	return 0;
}

int hidden sepol_compute_av_reason(sepol_security_id_t ssid,
				   sepol_security_id_t tsid,
				   sepol_security_class_t tclass,
				   sepol_access_vector_t requested,
				   struct sepol_av_decision *avd,
				   unsigned int *reason)
{
	context_struct_t *scontext = 0, *tcontext = 0;
	int rc = 0;

	scontext = sepol_sidtab_search(sidtab, ssid);
	if (!scontext) {
		ERR(NULL, "unrecognized source SID %d", ssid);
		rc = -EINVAL;
		goto out;
	}
	tcontext = sepol_sidtab_search(sidtab, tsid);
	if (!tcontext) {
		ERR(NULL, "unrecognized target SID %d", tsid);
		rc = -EINVAL;
		goto out;
	}

	rc = context_struct_compute_av(scontext, tcontext, tclass,
					requested, avd, reason, NULL, 0);
      out:
	return rc;
}

/*
 * sepol_compute_av_reason_buffer - the reason buffer is malloc'd to
 * REASON_BUF_SIZE. If the buffer size is exceeded, then it is realloc'd
 * in the constraint_expr_eval_reason() function.
 */
int hidden sepol_compute_av_reason_buffer(sepol_security_id_t ssid,
				   sepol_security_id_t tsid,
				   sepol_security_class_t tclass,
				   sepol_access_vector_t requested,
				   struct sepol_av_decision *avd,
				   unsigned int *reason,
				   char **reason_buf,
				   unsigned int flags)
{
	context_struct_t *scontext = 0, *tcontext = 0;
	int rc = 0;

	scontext = sepol_sidtab_search(sidtab, ssid);
	if (!scontext) {
		ERR(NULL, "unrecognized source SID %d", ssid);
		rc = -EINVAL;
		goto out;
	}
	tcontext = sepol_sidtab_search(sidtab, tsid);
	if (!tcontext) {
		ERR(NULL, "unrecognized target SID %d", tsid);
		rc = -EINVAL;
		goto out;
	}

	/*
	 * Set the buffer to NULL as constraints may not be processed.
	 * If a buffer is required, then the routines in
	 * constraint_expr_eval_reason will realloc in REASON_BUF_SIZE
	 * chunks (as it gets called for each constraint processed).
	 * We just make sure these start from zero.
	 */
	*reason_buf = NULL;
	reason_buf_used = 0;
	reason_buf_len = 0;

	rc = context_struct_compute_av(scontext, tcontext, tclass,
					   requested, avd, reason, reason_buf, flags);
out:
	return rc;
}

int hidden sepol_compute_av(sepol_security_id_t ssid,
			    sepol_security_id_t tsid,
			    sepol_security_class_t tclass,
			    sepol_access_vector_t requested,
			    struct sepol_av_decision *avd)
{
	unsigned int reason = 0;
	return sepol_compute_av_reason(ssid, tsid, tclass, requested, avd,
				       &reason);
}

/*
 * Return a class ID associated with the class string specified by
 * class_name.
 */
int hidden sepol_string_to_security_class(const char *class_name,
			sepol_security_class_t *tclass)
{
	class_datum_t *tclass_datum;

	tclass_datum = hashtab_search(policydb->p_classes.table,
				      (hashtab_key_t) class_name);
	if (!tclass_datum) {
		ERR(NULL, "unrecognized class %s", class_name);
		return STATUS_ERR;
	}
	*tclass = tclass_datum->s.value;
	return STATUS_SUCCESS;
}

/*
 * Return access vector bit associated with the class ID and permission
 * string.
 */
int hidden sepol_string_to_av_perm(sepol_security_class_t tclass,
					const char *perm_name,
					sepol_access_vector_t *av)
{
	class_datum_t *tclass_datum;
	perm_datum_t *perm_datum;

	if (!tclass || tclass > policydb->p_classes.nprim) {
		ERR(NULL, "unrecognized class %d", tclass);
		return -EINVAL;
	}
	tclass_datum = policydb->class_val_to_struct[tclass - 1];

	/* Check for unique perms then the common ones (if any) */
	perm_datum = (perm_datum_t *)
			hashtab_search(tclass_datum->permissions.table,
			(hashtab_key_t)perm_name);
	if (perm_datum != NULL) {
		*av = 0x1 << (perm_datum->s.value - 1);
		return STATUS_SUCCESS;
	}

	if (tclass_datum->comdatum == NULL)
		goto out;

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

	if (perm_datum != NULL) {
		*av = 0x1 << (perm_datum->s.value - 1);
		return STATUS_SUCCESS;
	}
out:
	ERR(NULL, "could not convert %s to av bit", perm_name);
	return STATUS_ERR;
}

/*
 * Write the security context string representation of 
 * the context associated with `sid' into a dynamically
 * allocated string of the correct size.  Set `*scontext'
 * to point to this string and set `*scontext_len' to
 * the length of the string.
 */
int hidden sepol_sid_to_context(sepol_security_id_t sid,
				sepol_security_context_t * scontext,
				size_t * scontext_len)
{
	context_struct_t *context;
	int rc = 0;

	context = sepol_sidtab_search(sidtab, sid);
	if (!context) {
		ERR(NULL, "unrecognized SID %d", sid);
		rc = -EINVAL;
		goto out;
	}
	rc = context_to_string(NULL, policydb, context, scontext, scontext_len);
      out:
	return rc;

}

/*
 * Return a SID associated with the security context that
 * has the string representation specified by `scontext'.
 */
int hidden sepol_context_to_sid(const sepol_security_context_t scontext,
				size_t scontext_len, sepol_security_id_t * sid)
{

	context_struct_t *context = NULL;

	/* First, create the context */
	if (context_from_string(NULL, policydb, &context,
				scontext, scontext_len) < 0)
		goto err;

	/* Obtain the new sid */
	if (sid && (sepol_sidtab_context_to_sid(sidtab, context, sid) < 0))
		goto err;

	context_destroy(context);
	free(context);
	return STATUS_SUCCESS;

      err:
	if (context) {
		context_destroy(context);
		free(context);
	}
	ERR(NULL, "could not convert %s to sid", scontext);
	return STATUS_ERR;
}

static inline int compute_sid_handle_invalid_context(context_struct_t *
						     scontext,
						     context_struct_t *
						     tcontext,
						     sepol_security_class_t
						     tclass,
						     context_struct_t *
						     newcontext)
{
	if (selinux_enforcing) {
		return -EACCES;
	} else {
		sepol_security_context_t s, t, n;
		size_t slen, tlen, nlen;

		context_to_string(NULL, policydb, scontext, &s, &slen);
		context_to_string(NULL, policydb, tcontext, &t, &tlen);
		context_to_string(NULL, policydb, newcontext, &n, &nlen);
		ERR(NULL, "invalid context %s for "
		    "scontext=%s tcontext=%s tclass=%s",
		    n, s, t, policydb->p_class_val_to_name[tclass - 1]);
		free(s);
		free(t);
		free(n);
		return 0;
	}
}

static int sepol_compute_sid(sepol_security_id_t ssid,
			     sepol_security_id_t tsid,
			     sepol_security_class_t tclass,
			     uint32_t specified, sepol_security_id_t * out_sid)
{
	context_struct_t *scontext = 0, *tcontext = 0, newcontext;
	struct role_trans *roletr = 0;
	avtab_key_t avkey;
	avtab_datum_t *avdatum;
	avtab_ptr_t node;
	int rc = 0;

	scontext = sepol_sidtab_search(sidtab, ssid);
	if (!scontext) {
		ERR(NULL, "unrecognized SID %d", ssid);
		rc = -EINVAL;
		goto out;
	}
	tcontext = sepol_sidtab_search(sidtab, tsid);
	if (!tcontext) {
		ERR(NULL, "unrecognized SID %d", tsid);
		rc = -EINVAL;
		goto out;
	}

	context_init(&newcontext);

	/* Set the user identity. */
	switch (specified) {
	case AVTAB_TRANSITION:
	case AVTAB_CHANGE:
		/* Use the process user identity. */
		newcontext.user = scontext->user;
		break;
	case AVTAB_MEMBER:
		/* Use the related object owner. */
		newcontext.user = tcontext->user;
		break;
	}

	/* Set the role and type to default values. */
	switch (tclass) {
	case SECCLASS_PROCESS:
		/* Use the current role and type of process. */
		newcontext.role = scontext->role;
		newcontext.type = scontext->type;
		break;
	default:
		/* Use the well-defined object role. */
		newcontext.role = OBJECT_R_VAL;
		/* Use the type of the related object. */
		newcontext.type = tcontext->type;
	}

	/* Look for a type transition/member/change rule. */
	avkey.source_type = scontext->type;
	avkey.target_type = tcontext->type;
	avkey.target_class = tclass;
	avkey.specified = specified;
	avdatum = avtab_search(&policydb->te_avtab, &avkey);

	/* If no permanent rule, also check for enabled conditional rules */
	if (!avdatum) {
		node = avtab_search_node(&policydb->te_cond_avtab, &avkey);
		for (; node != NULL;
		     node = avtab_search_node_next(node, specified)) {
			if (node->key.specified & AVTAB_ENABLED) {
				avdatum = &node->datum;
				break;
			}
		}
	}

	if (avdatum) {
		/* Use the type from the type transition/member/change rule. */
		newcontext.type = avdatum->data;
	}

	/* Check for class-specific changes. */
	switch (tclass) {
	case SECCLASS_PROCESS:
		if (specified & AVTAB_TRANSITION) {
			/* Look for a role transition rule. */
			for (roletr = policydb->role_tr; roletr;
			     roletr = roletr->next) {
				if (roletr->role == scontext->role &&
				    roletr->type == tcontext->type) {
					/* Use the role transition rule. */
					newcontext.role = roletr->new_role;
					break;
				}
			}
		}
		break;
	default:
		break;
	}

	/* Set the MLS attributes.
	   This is done last because it may allocate memory. */
	rc = mls_compute_sid(policydb, scontext, tcontext, tclass, specified,
			     &newcontext);
	if (rc)
		goto out;

	/* Check the validity of the context. */
	if (!policydb_context_isvalid(policydb, &newcontext)) {
		rc = compute_sid_handle_invalid_context(scontext,
							tcontext,
							tclass, &newcontext);
		if (rc)
			goto out;
	}
	/* Obtain the sid for the context. */
	rc = sepol_sidtab_context_to_sid(sidtab, &newcontext, out_sid);
      out:
	context_destroy(&newcontext);
	return rc;
}

/*
 * Compute a SID to use for labeling a new object in the 
 * class `tclass' based on a SID pair.  
 */
int hidden sepol_transition_sid(sepol_security_id_t ssid,
				sepol_security_id_t tsid,
				sepol_security_class_t tclass,
				sepol_security_id_t * out_sid)
{
	return sepol_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_sid);
}

/*
 * Compute a SID to use when selecting a member of a 
 * polyinstantiated object of class `tclass' based on 
 * a SID pair.
 */
int hidden sepol_member_sid(sepol_security_id_t ssid,
			    sepol_security_id_t tsid,
			    sepol_security_class_t tclass,
			    sepol_security_id_t * out_sid)
{
	return sepol_compute_sid(ssid, tsid, tclass, AVTAB_MEMBER, out_sid);
}

/*
 * Compute a SID to use for relabeling an object in the 
 * class `tclass' based on a SID pair.  
 */
int hidden sepol_change_sid(sepol_security_id_t ssid,
			    sepol_security_id_t tsid,
			    sepol_security_class_t tclass,
			    sepol_security_id_t * out_sid)
{
	return sepol_compute_sid(ssid, tsid, tclass, AVTAB_CHANGE, out_sid);
}

/*
 * Verify that each permission that is defined under the
 * existing policy is still defined with the same value
 * in the new policy.
 */
static int validate_perm(hashtab_key_t key, hashtab_datum_t datum, void *p)
{
	hashtab_t h;
	perm_datum_t *perdatum, *perdatum2;

	h = (hashtab_t) p;
	perdatum = (perm_datum_t *) datum;

	perdatum2 = (perm_datum_t *) hashtab_search(h, key);
	if (!perdatum2) {
		ERR(NULL, "permission %s disappeared", key);
		return -1;
	}
	if (perdatum->s.value != perdatum2->s.value) {
		ERR(NULL, "the value of permissions %s changed", key);
		return -1;
	}
	return 0;
}

/*
 * Verify that each class that is defined under the
 * existing policy is still defined with the same 
 * attributes in the new policy.
 */
static int validate_class(hashtab_key_t key, hashtab_datum_t datum, void *p)
{
	policydb_t *newp;
	class_datum_t *cladatum, *cladatum2;

	newp = (policydb_t *) p;
	cladatum = (class_datum_t *) datum;

	cladatum2 =
	    (class_datum_t *) hashtab_search(newp->p_classes.table, key);
	if (!cladatum2) {
		ERR(NULL, "class %s disappeared", key);
		return -1;
	}
	if (cladatum->s.value != cladatum2->s.value) {
		ERR(NULL, "the value of class %s changed", key);
		return -1;
	}
	if ((cladatum->comdatum && !cladatum2->comdatum) ||
	    (!cladatum->comdatum && cladatum2->comdatum)) {
		ERR(NULL, "the inherits clause for the access "
		    "vector definition for class %s changed", key);
		return -1;
	}
	if (cladatum->comdatum) {
		if (hashtab_map
		    (cladatum->comdatum->permissions.table, validate_perm,
		     cladatum2->comdatum->permissions.table)) {
			ERR(NULL,
			    " in the access vector definition "
			    "for class %s\n", key);
			return -1;
		}
	}
	if (hashtab_map(cladatum->permissions.table, validate_perm,
			cladatum2->permissions.table)) {
		ERR(NULL, " in access vector definition for class %s", key);
		return -1;
	}
	return 0;
}

/* Clone the SID into the new SID table. */
static int clone_sid(sepol_security_id_t sid,
		     context_struct_t * context, void *arg)
{
	sidtab_t *s = arg;

	return sepol_sidtab_insert(s, sid, context);
}

static inline int convert_context_handle_invalid_context(context_struct_t *
							 context)
{
	if (selinux_enforcing) {
		return -EINVAL;
	} else {
		sepol_security_context_t s;
		size_t len;

		context_to_string(NULL, policydb, context, &s, &len);
		ERR(NULL, "context %s is invalid", s);
		free(s);
		return 0;
	}
}

typedef struct {
	policydb_t *oldp;
	policydb_t *newp;
} convert_context_args_t;

/*
 * Convert the values in the security context
 * structure `c' from the values specified
 * in the policy `p->oldp' to the values specified
 * in the policy `p->newp'.  Verify that the
 * context is valid under the new policy.
 */
static int convert_context(sepol_security_id_t key __attribute__ ((unused)),
			   context_struct_t * c, void *p)
{
	convert_context_args_t *args;
	context_struct_t oldc;
	role_datum_t *role;
	type_datum_t *typdatum;
	user_datum_t *usrdatum;
	sepol_security_context_t s;
	size_t len;
	int rc = -EINVAL;

	args = (convert_context_args_t *) p;

	if (context_cpy(&oldc, c))
		return -ENOMEM;

	/* Convert the user. */
	usrdatum = (user_datum_t *) hashtab_search(args->newp->p_users.table,
						   args->oldp->
						   p_user_val_to_name[c->user -
								      1]);

	if (!usrdatum) {
		goto bad;
	}
	c->user = usrdatum->s.value;

	/* Convert the role. */
	role = (role_datum_t *) hashtab_search(args->newp->p_roles.table,
					       args->oldp->
					       p_role_val_to_name[c->role - 1]);
	if (!role) {
		goto bad;
	}
	c->role = role->s.value;

	/* Convert the type. */
	typdatum = (type_datum_t *)
	    hashtab_search(args->newp->p_types.table,
			   args->oldp->p_type_val_to_name[c->type - 1]);
	if (!typdatum) {
		goto bad;
	}
	c->type = typdatum->s.value;

	rc = mls_convert_context(args->oldp, args->newp, c);
	if (rc)
		goto bad;

	/* Check the validity of the new context. */
	if (!policydb_context_isvalid(args->newp, c)) {
		rc = convert_context_handle_invalid_context(&oldc);
		if (rc)
			goto bad;
	}

	context_destroy(&oldc);
	return 0;

      bad:
	context_to_string(NULL, policydb, &oldc, &s, &len);
	context_destroy(&oldc);
	ERR(NULL, "invalidating context %s", s);
	free(s);
	return rc;
}

/* Reading from a policy "file". */
int hidden next_entry(void *buf, struct policy_file *fp, size_t bytes)
{
	size_t nread;

	switch (fp->type) {
	case PF_USE_STDIO:
		nread = fread(buf, bytes, 1, fp->fp);

		if (nread != 1)
			return -1;
		break;
	case PF_USE_MEMORY:
		if (bytes > fp->len) {
			errno = EOVERFLOW;
			return -1;
		}
		memcpy(buf, fp->data, bytes);
		fp->data += bytes;
		fp->len -= bytes;
		break;
	default:
		errno = EINVAL;
		return -1;
	}
	return 0;
}

size_t hidden put_entry(const void *ptr, size_t size, size_t n,
			struct policy_file *fp)
{
	size_t bytes = size * n;

	switch (fp->type) {
	case PF_USE_STDIO:
		return fwrite(ptr, size, n, fp->fp);
	case PF_USE_MEMORY:
		if (bytes > fp->len) {
			errno = ENOSPC;
			return 0;
		}

		memcpy(fp->data, ptr, bytes);
		fp->data += bytes;
		fp->len -= bytes;
		return n;
	case PF_LEN:
		fp->len += bytes;
		return n;
	default:
		return 0;
	}
	return 0;
}

/*
 * Reads a string and null terminates it from the policy file.
 * This is a port of str_read from the SE Linux kernel code.
 *
 * It returns:
 *   0 - Success
 *  -1 - Failure with errno set
 */
int hidden str_read(char **strp, struct policy_file *fp, size_t len)
{
	int rc;
	char *str;

	if (zero_or_saturated(len)) {
		errno = EINVAL;
		return -1;
	}

	str = malloc(len + 1);
	if (!str)
		return -1;

	/* it's expected the caller should free the str */
	*strp = str;

	/* next_entry sets errno */
	rc = next_entry(str, fp, len);
	if (rc)
		return rc;

	str[len] = '\0';
	return 0;
}

/*
 * Read a new set of configuration data from 
 * a policy database binary representation file.
 *
 * Verify that each class that is defined under the
 * existing policy is still defined with the same 
 * attributes in the new policy.  
 *
 * Convert the context structures in the SID table to the
 * new representation and verify that all entries
 * in the SID table are valid under the new policy. 
 *
 * Change the active policy database to use the new 
 * configuration data.  
 *
 * Reset the access vector cache.
 */
int hidden sepol_load_policy(void *data, size_t len)
{
	policydb_t oldpolicydb, newpolicydb;
	sidtab_t oldsidtab, newsidtab;
	convert_context_args_t args;
	int rc = 0;
	struct policy_file file, *fp;

	policy_file_init(&file);
	file.type = PF_USE_MEMORY;
	file.data = data;
	file.len = len;
	fp = &file;

	if (policydb_init(&newpolicydb))
		return -ENOMEM;

	if (policydb_read(&newpolicydb, fp, 1)) {
		policydb_destroy(&mypolicydb);
		return -EINVAL;
	}

	sepol_sidtab_init(&newsidtab);

	/* Verify that the existing classes did not change. */
	if (hashtab_map
	    (policydb->p_classes.table, validate_class, &newpolicydb)) {
		ERR(NULL, "the definition of an existing class changed");
		rc = -EINVAL;
		goto err;
	}

	/* Clone the SID table. */
	sepol_sidtab_shutdown(sidtab);
	if (sepol_sidtab_map(sidtab, clone_sid, &newsidtab)) {
		rc = -ENOMEM;
		goto err;
	}

	/* Convert the internal representations of contexts 
	   in the new SID table and remove invalid SIDs. */
	args.oldp = policydb;
	args.newp = &newpolicydb;
	sepol_sidtab_map_remove_on_error(&newsidtab, convert_context, &args);

	/* Save the old policydb and SID table to free later. */
	memcpy(&oldpolicydb, policydb, sizeof *policydb);
	sepol_sidtab_set(&oldsidtab, sidtab);

	/* Install the new policydb and SID table. */
	memcpy(policydb, &newpolicydb, sizeof *policydb);
	sepol_sidtab_set(sidtab, &newsidtab);

	/* Free the old policydb and SID table. */
	policydb_destroy(&oldpolicydb);
	sepol_sidtab_destroy(&oldsidtab);

	return 0;

      err:
	sepol_sidtab_destroy(&newsidtab);
	policydb_destroy(&newpolicydb);
	return rc;

}

/*
 * Return the SIDs to use for an unlabeled file system
 * that is being mounted from the device with the
 * the kdevname `name'.  The `fs_sid' SID is returned for 
 * the file system and the `file_sid' SID is returned
 * for all files within that file system.
 */
int hidden sepol_fs_sid(char *name,
			sepol_security_id_t * fs_sid,
			sepol_security_id_t * file_sid)
{
	int rc = 0;
	ocontext_t *c;

	c = policydb->ocontexts[OCON_FS];
	while (c) {
		if (strcmp(c->u.name, name) == 0)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0] || !c->sid[1]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[1],
							 &c->sid[1]);
			if (rc)
				goto out;
		}
		*fs_sid = c->sid[0];
		*file_sid = c->sid[1];
	} else {
		*fs_sid = SECINITSID_FS;
		*file_sid = SECINITSID_FILE;
	}

      out:
	return rc;
}

/*
 * Return the SID of the ibpkey specified by
 * `subnet prefix', and `pkey number'.
 */
int hidden sepol_ibpkey_sid(uint64_t subnet_prefix,
			    uint16_t pkey, sepol_security_id_t *out_sid)
{
	ocontext_t *c;
	int rc = 0;

	c = policydb->ocontexts[OCON_IBPKEY];
	while (c) {
		if (c->u.ibpkey.low_pkey <= pkey &&
		    c->u.ibpkey.high_pkey >= pkey &&
		    subnet_prefix == c->u.ibpkey.subnet_prefix)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*out_sid = c->sid[0];
	} else {
		*out_sid = SECINITSID_UNLABELED;
	}

out:
	return rc;
}

/*
 * Return the SID of the subnet management interface specified by
 * `device name', and `port'.
 */
int hidden sepol_ibendport_sid(char *dev_name,
			       uint8_t port,
			       sepol_security_id_t *out_sid)
{
	ocontext_t *c;
	int rc = 0;

	c = policydb->ocontexts[OCON_IBENDPORT];
	while (c) {
		if (c->u.ibendport.port == port &&
		    !strcmp(dev_name, c->u.ibendport.dev_name))
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*out_sid = c->sid[0];
	} else {
		*out_sid = SECINITSID_UNLABELED;
	}

out:
	return rc;
}


/*
 * Return the SID of the port specified by
 * `domain', `type', `protocol', and `port'.
 */
int hidden sepol_port_sid(uint16_t domain __attribute__ ((unused)),
			  uint16_t type __attribute__ ((unused)),
			  uint8_t protocol,
			  uint16_t port, sepol_security_id_t * out_sid)
{
	ocontext_t *c;
	int rc = 0;

	c = policydb->ocontexts[OCON_PORT];
	while (c) {
		if (c->u.port.protocol == protocol &&
		    c->u.port.low_port <= port && c->u.port.high_port >= port)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*out_sid = c->sid[0];
	} else {
		*out_sid = SECINITSID_PORT;
	}

      out:
	return rc;
}

/*
 * Return the SIDs to use for a network interface
 * with the name `name'.  The `if_sid' SID is returned for 
 * the interface and the `msg_sid' SID is returned as 
 * the default SID for messages received on the
 * interface.
 */
int hidden sepol_netif_sid(char *name,
			   sepol_security_id_t * if_sid,
			   sepol_security_id_t * msg_sid)
{
	int rc = 0;
	ocontext_t *c;

	c = policydb->ocontexts[OCON_NETIF];
	while (c) {
		if (strcmp(name, c->u.name) == 0)
			break;
		c = c->next;
	}

	if (c) {
		if (!c->sid[0] || !c->sid[1]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[1],
							 &c->sid[1]);
			if (rc)
				goto out;
		}
		*if_sid = c->sid[0];
		*msg_sid = c->sid[1];
	} else {
		*if_sid = SECINITSID_NETIF;
		*msg_sid = SECINITSID_NETMSG;
	}

      out:
	return rc;
}

static int match_ipv6_addrmask(uint32_t * input, uint32_t * addr,
			       uint32_t * mask)
{
	int i, fail = 0;

	for (i = 0; i < 4; i++)
		if (addr[i] != (input[i] & mask[i])) {
			fail = 1;
			break;
		}

	return !fail;
}

/*
 * Return the SID of the node specified by the address
 * `addrp' where `addrlen' is the length of the address
 * in bytes and `domain' is the communications domain or
 * address family in which the address should be interpreted.
 */
int hidden sepol_node_sid(uint16_t domain,
			  void *addrp,
			  size_t addrlen, sepol_security_id_t * out_sid)
{
	int rc = 0;
	ocontext_t *c;

	switch (domain) {
	case AF_INET:{
			uint32_t addr;

			if (addrlen != sizeof(uint32_t)) {
				rc = -EINVAL;
				goto out;
			}

			addr = *((uint32_t *) addrp);

			c = policydb->ocontexts[OCON_NODE];
			while (c) {
				if (c->u.node.addr == (addr & c->u.node.mask))
					break;
				c = c->next;
			}
			break;
		}

	case AF_INET6:
		if (addrlen != sizeof(uint64_t) * 2) {
			rc = -EINVAL;
			goto out;
		}

		c = policydb->ocontexts[OCON_NODE6];
		while (c) {
			if (match_ipv6_addrmask(addrp, c->u.node6.addr,
						c->u.node6.mask))
				break;
			c = c->next;
		}
		break;

	default:
		*out_sid = SECINITSID_NODE;
		goto out;
	}

	if (c) {
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*out_sid = c->sid[0];
	} else {
		*out_sid = SECINITSID_NODE;
	}

      out:
	return rc;
}

/*
 * Generate the set of SIDs for legal security contexts
 * for a given user that can be reached by `fromsid'.
 * Set `*sids' to point to a dynamically allocated 
 * array containing the set of SIDs.  Set `*nel' to the
 * number of elements in the array.
 */
#define SIDS_NEL 25

int hidden sepol_get_user_sids(sepol_security_id_t fromsid,
			       char *username,
			       sepol_security_id_t ** sids, uint32_t * nel)
{
	context_struct_t *fromcon, usercon;
	sepol_security_id_t *mysids, *mysids2, sid;
	uint32_t mynel = 0, maxnel = SIDS_NEL;
	user_datum_t *user;
	role_datum_t *role;
	struct sepol_av_decision avd;
	int rc = 0;
	unsigned int i, j, reason;
	ebitmap_node_t *rnode, *tnode;

	fromcon = sepol_sidtab_search(sidtab, fromsid);
	if (!fromcon) {
		rc = -EINVAL;
		goto out;
	}

	user = (user_datum_t *) hashtab_search(policydb->p_users.table,
					       username);
	if (!user) {
		rc = -EINVAL;
		goto out;
	}
	usercon.user = user->s.value;

	mysids = malloc(maxnel * sizeof(sepol_security_id_t));
	if (!mysids) {
		rc = -ENOMEM;
		goto out;
	}
	memset(mysids, 0, maxnel * sizeof(sepol_security_id_t));

	ebitmap_for_each_positive_bit(&user->roles.roles, rnode, i) {
		role = policydb->role_val_to_struct[i];
		usercon.role = i + 1;
		ebitmap_for_each_positive_bit(&role->types.types, tnode, j) {
			usercon.type = j + 1;
			if (usercon.type == fromcon->type)
				continue;

			if (mls_setup_user_range
			    (fromcon, user, &usercon, policydb->mls))
				continue;

			rc = context_struct_compute_av(fromcon, &usercon,
						       SECCLASS_PROCESS,
						       PROCESS__TRANSITION,
						       &avd, &reason, NULL, 0);
			if (rc || !(avd.allowed & PROCESS__TRANSITION))
				continue;
			rc = sepol_sidtab_context_to_sid(sidtab, &usercon,
							 &sid);
			if (rc) {
				free(mysids);
				goto out;
			}
			if (mynel < maxnel) {
				mysids[mynel++] = sid;
			} else {
				maxnel += SIDS_NEL;
				mysids2 =
				    malloc(maxnel *
					   sizeof(sepol_security_id_t));

				if (!mysids2) {
					rc = -ENOMEM;
					free(mysids);
					goto out;
				}
				memset(mysids2, 0,
				       maxnel * sizeof(sepol_security_id_t));
				memcpy(mysids2, mysids,
				       mynel * sizeof(sepol_security_id_t));
				free(mysids);
				mysids = mysids2;
				mysids[mynel++] = sid;
			}
		}
	}

	*sids = mysids;
	*nel = mynel;

      out:
	return rc;
}

/*
 * Return the SID to use for a file in a filesystem
 * that cannot support a persistent label mapping or use another
 * fixed labeling behavior like transition SIDs or task SIDs.
 */
int hidden sepol_genfs_sid(const char *fstype,
			   const char *path,
			   sepol_security_class_t sclass,
			   sepol_security_id_t * sid)
{
	size_t len;
	genfs_t *genfs;
	ocontext_t *c;
	int rc = 0, cmp = 0;

	for (genfs = policydb->genfs; genfs; genfs = genfs->next) {
		cmp = strcmp(fstype, genfs->fstype);
		if (cmp <= 0)
			break;
	}

	if (!genfs || cmp) {
		*sid = SECINITSID_UNLABELED;
		rc = -ENOENT;
		goto out;
	}

	for (c = genfs->head; c; c = c->next) {
		len = strlen(c->u.name);
		if ((!c->v.sclass || sclass == c->v.sclass) &&
		    (strncmp(c->u.name, path, len) == 0))
			break;
	}

	if (!c) {
		*sid = SECINITSID_UNLABELED;
		rc = -ENOENT;
		goto out;
	}

	if (!c->sid[0]) {
		rc = sepol_sidtab_context_to_sid(sidtab,
						 &c->context[0], &c->sid[0]);
		if (rc)
			goto out;
	}

	*sid = c->sid[0];
      out:
	return rc;
}

int hidden sepol_fs_use(const char *fstype,
			unsigned int *behavior, sepol_security_id_t * sid)
{
	int rc = 0;
	ocontext_t *c;

	c = policydb->ocontexts[OCON_FSUSE];
	while (c) {
		if (strcmp(fstype, c->u.name) == 0)
			break;
		c = c->next;
	}

	if (c) {
		*behavior = c->v.behavior;
		if (!c->sid[0]) {
			rc = sepol_sidtab_context_to_sid(sidtab,
							 &c->context[0],
							 &c->sid[0]);
			if (rc)
				goto out;
		}
		*sid = c->sid[0];
	} else {
		rc = sepol_genfs_sid(fstype, "/", SECCLASS_DIR, sid);
		if (rc) {
			*behavior = SECURITY_FS_USE_NONE;
			rc = 0;
		} else {
			*behavior = SECURITY_FS_USE_GENFS;
		}
	}

      out:
	return rc;
}

/* FLASK */
