/* Authors: Joshua Brindle <jbrindle@tresys.com>
 * 	    Jason Tang <jtang@tresys.com>
 *
 * Updates: KaiGai Kohei <kaigai@ak.jp.nec.com>
 *          adds checks based on newer boundary facility.
 *
 * A set of utility functions that aid policy decision when dealing
 * with hierarchal namespaces.
 *
 * Copyright (C) 2005 Tresys Technology, LLC
 *
 * Copyright (c) 2008 NEC Corporation
 *
 *  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 <string.h>
#include <stdlib.h>
#include <assert.h>
#include <sepol/policydb/policydb.h>
#include <sepol/policydb/conditional.h>
#include <sepol/policydb/hierarchy.h>
#include <sepol/policydb/expand.h>
#include <sepol/policydb/util.h>

#include "debug.h"

#define BOUNDS_AVTAB_SIZE 1024

static int bounds_insert_helper(sepol_handle_t *handle, avtab_t *avtab,
				avtab_key_t *avtab_key, avtab_datum_t *datum)
{
	int rc = avtab_insert(avtab, avtab_key, datum);
	if (rc) {
		if (rc == SEPOL_ENOMEM)
			ERR(handle, "Insufficient memory");
		else
			ERR(handle, "Unexpected error (%d)", rc);
	}
	return rc;
}


static int bounds_insert_rule(sepol_handle_t *handle, avtab_t *avtab,
			      avtab_t *global, avtab_t *other,
			      avtab_key_t *avtab_key, avtab_datum_t *datum)
{
	int rc = 0;
	avtab_datum_t *dup = avtab_search(avtab, avtab_key);

	if (!dup) {
		rc = bounds_insert_helper(handle, avtab, avtab_key, datum);
		if (rc) goto exit;
	} else {
		dup->data |= datum->data;
	}

	if (other) {
		/* Search the other conditional avtab for the key and
		 * add any common permissions to the global avtab
		 */
		uint32_t data = 0;
		dup = avtab_search(other, avtab_key);
		if (dup) {
			data = dup->data & datum->data;
			if (data) {
				dup = avtab_search(global, avtab_key);
				if (!dup) {
					avtab_datum_t d;
					d.data = data;
					rc = bounds_insert_helper(handle, global,
								  avtab_key, &d);
					if (rc) goto exit;
				} else {
					dup->data |= data;
				}
			}
		}
	}

exit:
	return rc;
}

static int bounds_expand_rule(sepol_handle_t *handle, policydb_t *p,
			      avtab_t *avtab, avtab_t *global, avtab_t *other,
			      uint32_t parent, uint32_t src, uint32_t tgt,
			      uint32_t class, uint32_t data)
{
	int rc = 0;
	avtab_key_t avtab_key;
	avtab_datum_t datum;
	ebitmap_node_t *tnode;
	unsigned int i;

	avtab_key.specified = AVTAB_ALLOWED;
	avtab_key.target_class = class;
	datum.data = data;

	if (ebitmap_get_bit(&p->attr_type_map[src - 1], parent - 1)) {
		avtab_key.source_type = parent;
		ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
			if (!ebitmap_node_get_bit(tnode, i))
				continue;
			avtab_key.target_type = i + 1;
			rc = bounds_insert_rule(handle, avtab, global, other,
						&avtab_key, &datum);
			if (rc) goto exit;
		}
	}

exit:
	return rc;
}

static int bounds_expand_cond_rules(sepol_handle_t *handle, policydb_t *p,
				    cond_av_list_t *cur, avtab_t *avtab,
				    avtab_t *global, avtab_t *other,
				    uint32_t parent)
{
	int rc = 0;

	for (; cur; cur = cur->next) {
		avtab_ptr_t n = cur->node;
		rc = bounds_expand_rule(handle, p, avtab, global, other, parent,
					n->key.source_type, n->key.target_type,
					n->key.target_class, n->datum.data);
		if (rc) goto exit;
	}

exit:
	return rc;
}

struct bounds_expand_args {
	sepol_handle_t *handle;
	policydb_t *p;
	avtab_t *avtab;
	uint32_t parent;
};

static int bounds_expand_rule_callback(avtab_key_t *k, avtab_datum_t *d,
				       void *args)
{
	struct bounds_expand_args *a = (struct bounds_expand_args *)args;

	if (!(k->specified & AVTAB_ALLOWED))
		return 0;

	return bounds_expand_rule(a->handle, a->p, a->avtab, NULL, NULL,
				  a->parent, k->source_type, k->target_type,
				  k->target_class, d->data);
}

struct bounds_cond_info {
	avtab_t true_avtab;
	avtab_t false_avtab;
	cond_list_t *cond_list;
	struct bounds_cond_info *next;
};

static void bounds_destroy_cond_info(struct bounds_cond_info *cur)
{
	struct bounds_cond_info *next;

	for (; cur; cur = next) {
		next = cur->next;
		avtab_destroy(&cur->true_avtab);
		avtab_destroy(&cur->false_avtab);
		cur->next = NULL;
		free(cur);
	}
}

static int bounds_expand_parent_rules(sepol_handle_t *handle, policydb_t *p,
				      avtab_t *global_avtab,
				      struct bounds_cond_info **cond_info,
				      uint32_t parent)
{
	int rc = 0;
	struct bounds_expand_args args;
	cond_list_t *cur;

	avtab_init(global_avtab);
	rc = avtab_alloc(global_avtab, BOUNDS_AVTAB_SIZE);
	if (rc) goto oom;

	args.handle = handle;
	args.p = p;
	args.avtab = global_avtab;
	args.parent = parent;
	rc = avtab_map(&p->te_avtab, bounds_expand_rule_callback, &args);
	if (rc) goto exit;

	*cond_info = NULL;
	for (cur = p->cond_list; cur; cur = cur->next) {
		struct bounds_cond_info *ci;
		ci = malloc(sizeof(struct bounds_cond_info));
		if (!ci) goto oom;
		avtab_init(&ci->true_avtab);
		avtab_init(&ci->false_avtab);
		ci->cond_list = cur;
		ci->next = *cond_info;
		*cond_info = ci;
		if (cur->true_list) {
			rc = avtab_alloc(&ci->true_avtab, BOUNDS_AVTAB_SIZE);
			if (rc) goto oom;
			rc = bounds_expand_cond_rules(handle, p, cur->true_list,
						      &ci->true_avtab, NULL,
						      NULL, parent);
			if (rc) goto exit;
		}
		if (cur->false_list) {
			rc = avtab_alloc(&ci->false_avtab, BOUNDS_AVTAB_SIZE);
			if (rc) goto oom;
			rc = bounds_expand_cond_rules(handle, p, cur->false_list,
						      &ci->false_avtab,
						      global_avtab,
						      &ci->true_avtab, parent);
			if (rc) goto exit;
		}
	}

	return 0;

oom:
	ERR(handle, "Insufficient memory");

exit:
	ERR(handle,"Failed to expand parent rules\n");
	avtab_destroy(global_avtab);
	bounds_destroy_cond_info(*cond_info);
	*cond_info = NULL;
	return rc;
}

static int bounds_not_covered(avtab_t *global_avtab, avtab_t *cur_avtab,
			      avtab_key_t *avtab_key, uint32_t data)
{
	avtab_datum_t *datum = avtab_search(cur_avtab, avtab_key);
	if (datum)
		data &= ~datum->data;
	if (global_avtab && data) {
		datum = avtab_search(global_avtab, avtab_key);
		if (datum)
			data &= ~datum->data;
	}

	return data;
}

static int bounds_add_bad(sepol_handle_t *handle, uint32_t src, uint32_t tgt,
			  uint32_t class, uint32_t data, avtab_ptr_t *bad)
{
	struct avtab_node *new = malloc(sizeof(struct avtab_node));
	if (new == NULL) {
		ERR(handle, "Insufficient memory");
		return SEPOL_ENOMEM;
	}
	memset(new, 0, sizeof(struct avtab_node));
	new->key.source_type = src;
	new->key.target_type = tgt;
	new->key.target_class = class;
	new->datum.data = data;
	new->next = *bad;
	*bad = new;

	return 0;
}

static int bounds_check_rule(sepol_handle_t *handle, policydb_t *p,
			     avtab_t *global_avtab, avtab_t *cur_avtab,
			     uint32_t child, uint32_t parent, uint32_t src,
			     uint32_t tgt, uint32_t class, uint32_t data,
			     avtab_ptr_t *bad, int *numbad)
{
	int rc = 0;
	avtab_key_t avtab_key;
	type_datum_t *td;
	ebitmap_node_t *tnode;
	unsigned int i;
	uint32_t d;

	avtab_key.specified = AVTAB_ALLOWED;
	avtab_key.target_class = class;

	if (ebitmap_get_bit(&p->attr_type_map[src - 1], child - 1)) {
		avtab_key.source_type = parent;
		ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) {
			if (!ebitmap_node_get_bit(tnode, i))
				continue;
			td = p->type_val_to_struct[i];
			if (td && td->bounds) {
				avtab_key.target_type = td->bounds;
				d = bounds_not_covered(global_avtab, cur_avtab,
						       &avtab_key, data);
			} else {
				avtab_key.target_type = i + 1;
				d = bounds_not_covered(global_avtab, cur_avtab,
						       &avtab_key, data);
			}
			if (d) {
				(*numbad)++;
				rc = bounds_add_bad(handle, child, i+1, class, d, bad);
				if (rc) goto exit;
			}
		}
	}

exit:
	return rc;
}

static int bounds_check_cond_rules(sepol_handle_t *handle, policydb_t *p,
				   avtab_t *global_avtab, avtab_t *cond_avtab,
				   cond_av_list_t *rules, uint32_t child,
				   uint32_t parent, avtab_ptr_t *bad,
				   int *numbad)
{
	int rc = 0;
	cond_av_list_t *cur;

	for (cur = rules; cur; cur = cur->next) {
		avtab_ptr_t ap = cur->node;
		avtab_key_t *key = &ap->key;
		avtab_datum_t *datum = &ap->datum;
		if (!(key->specified & AVTAB_ALLOWED))
			continue;
		rc = bounds_check_rule(handle, p, global_avtab, cond_avtab,
				       child, parent, key->source_type,
				       key->target_type, key->target_class,
				       datum->data, bad, numbad);
		if (rc) goto exit;
	}

exit:
	return rc;
}

struct bounds_check_args {
	sepol_handle_t *handle;
	policydb_t *p;
	avtab_t *cur_avtab;
	uint32_t child;
	uint32_t parent;
	avtab_ptr_t bad;
	int numbad;
};

static int bounds_check_rule_callback(avtab_key_t *k, avtab_datum_t *d,
				      void *args)
{
	struct bounds_check_args *a = (struct bounds_check_args *)args;

	if (!(k->specified & AVTAB_ALLOWED))
		return 0;

	return bounds_check_rule(a->handle, a->p, NULL, a->cur_avtab, a->child,
				 a->parent, k->source_type, k->target_type,
				 k->target_class, d->data, &a->bad, &a->numbad);
}

static int bounds_check_child_rules(sepol_handle_t *handle, policydb_t *p,
				    avtab_t *global_avtab,
				    struct bounds_cond_info *cond_info,
				    uint32_t child, uint32_t parent,
				    avtab_ptr_t *bad, int *numbad)
{
	int rc;
	struct bounds_check_args args;
	struct bounds_cond_info *cur;

	args.handle = handle;
	args.p = p;
	args.cur_avtab = global_avtab;
	args.child = child;
	args.parent = parent;
	args.bad = NULL;
	args.numbad = 0;
	rc = avtab_map(&p->te_avtab, bounds_check_rule_callback, &args);
	if (rc) goto exit;

	for (cur = cond_info; cur; cur = cur->next) {
		cond_list_t *node = cur->cond_list;
		rc = bounds_check_cond_rules(handle, p, global_avtab,
					     &cur->true_avtab,
					     node->true_list, child, parent,
					     &args.bad, &args.numbad);
		if (rc) goto exit;

		rc = bounds_check_cond_rules(handle, p, global_avtab,
					     &cur->false_avtab,
					     node->false_list, child, parent,
					     &args.bad, &args.numbad);
		if (rc) goto exit;
	}

	*numbad += args.numbad;
	*bad = args.bad;

exit:
	return rc;
}

int bounds_check_type(sepol_handle_t *handle, policydb_t *p, uint32_t child,
		      uint32_t parent, avtab_ptr_t *bad, int *numbad)
{
	int rc = 0;
	avtab_t global_avtab;
	struct bounds_cond_info *cond_info = NULL;

	rc = bounds_expand_parent_rules(handle, p, &global_avtab, &cond_info, parent);
	if (rc) goto exit;

	rc = bounds_check_child_rules(handle, p, &global_avtab, cond_info,
				      child, parent, bad, numbad);

	bounds_destroy_cond_info(cond_info);
	avtab_destroy(&global_avtab);

exit:
	return rc;
}

struct bounds_args {
	sepol_handle_t *handle;
	policydb_t *p;
	int numbad;
};

static void bounds_report(sepol_handle_t *handle, policydb_t *p, uint32_t child,
			  uint32_t parent, avtab_ptr_t cur)
{
	ERR(handle, "Child type %s exceeds bounds of parent %s in the following rules:",
	    p->p_type_val_to_name[child - 1],
	    p->p_type_val_to_name[parent - 1]);
	for (; cur; cur = cur->next) {
		ERR(handle, "    %s %s : %s { %s }",
		    p->p_type_val_to_name[cur->key.source_type - 1],
		    p->p_type_val_to_name[cur->key.target_type - 1],
		    p->p_class_val_to_name[cur->key.target_class - 1],
		    sepol_av_to_string(p, cur->key.target_class,
				       cur->datum.data));
	}
}

void bounds_destroy_bad(avtab_ptr_t cur)
{
	avtab_ptr_t next;

	for (; cur; cur = next) {
		next = cur->next;
		cur->next = NULL;
		free(cur);
	}
}

static int bounds_check_type_callback(hashtab_key_t k __attribute__ ((unused)),
				      hashtab_datum_t d, void *args)
{
	int rc = 0;
	struct bounds_args *a = (struct bounds_args *)args;
	type_datum_t *t = (type_datum_t *)d;
	avtab_ptr_t bad = NULL;

	if (t->bounds) {
		rc = bounds_check_type(a->handle, a->p, t->s.value, t->bounds,
				       &bad, &a->numbad);
		if (bad) {
			bounds_report(a->handle, a->p, t->s.value, t->bounds,
				      bad);
			bounds_destroy_bad(bad);
		}
	}

	return rc;
}

int bounds_check_types(sepol_handle_t *handle, policydb_t *p)
{
	int rc;
	struct bounds_args args;

	args.handle = handle;
	args.p = p;
	args.numbad = 0;

	rc = hashtab_map(p->p_types.table, bounds_check_type_callback, &args);
	if (rc) goto exit;

	if (args.numbad > 0) {
		ERR(handle, "%d errors found during type bounds check",
		    args.numbad);
		rc = SEPOL_ERR;
	}

exit:
	return rc;
}

/* The role bounds is defined as: a child role cannot have a type that
 * its parent doesn't have.
 */
static int bounds_check_role_callback(hashtab_key_t k,
				      hashtab_datum_t d, void *args)
{
	struct bounds_args *a = (struct bounds_args *)args;
	role_datum_t *r = (role_datum_t *) d;
	role_datum_t *rp = NULL;

	if (!r->bounds)
		return 0;

	rp = a->p->role_val_to_struct[r->bounds - 1];

	if (rp && !ebitmap_contains(&rp->types.types, &r->types.types)) {
		ERR(a->handle, "Role bounds violation, %s exceeds %s",
		    (char *)k, a->p->p_role_val_to_name[rp->s.value - 1]);
		a->numbad++;
	}

	return 0;
}

int bounds_check_roles(sepol_handle_t *handle, policydb_t *p)
{
	struct bounds_args args;

	args.handle = handle;
	args.p = p;
	args.numbad = 0;

	hashtab_map(p->p_roles.table, bounds_check_role_callback, &args);

	if (args.numbad > 0) {
		ERR(handle, "%d errors found during role bounds check",
		    args.numbad);
		return SEPOL_ERR;
	}

	return 0;
}

/* The user bounds is defined as: a child user cannot have a role that
 * its parent doesn't have.
 */
static int bounds_check_user_callback(hashtab_key_t k,
				      hashtab_datum_t d, void *args)
{
	struct bounds_args *a = (struct bounds_args *)args;
	user_datum_t *u = (user_datum_t *) d;
	user_datum_t *up = NULL;

	if (!u->bounds)
		return 0;

	up = a->p->user_val_to_struct[u->bounds - 1];

	if (up && !ebitmap_contains(&up->roles.roles, &u->roles.roles)) {
		ERR(a->handle, "User bounds violation, %s exceeds %s",
		    (char *) k, a->p->p_user_val_to_name[up->s.value - 1]);
		a->numbad++;
	}

	return 0;
}

int bounds_check_users(sepol_handle_t *handle, policydb_t *p)
{
	struct bounds_args args;

	args.handle = handle;
	args.p = p;
	args.numbad = 0;

	hashtab_map(p->p_users.table, bounds_check_user_callback, &args);

	if (args.numbad > 0) {
		ERR(handle, "%d errors found during user bounds check",
		    args.numbad);
		return SEPOL_ERR;
	}

	return 0;
}

#define add_hierarchy_callback_template(prefix)				\
	int hierarchy_add_##prefix##_callback(hashtab_key_t k __attribute__ ((unused)), \
					    hashtab_datum_t d, void *args) \
{								\
	struct bounds_args *a = (struct bounds_args *)args;		\
	sepol_handle_t *handle = a->handle;				\
	policydb_t *p = a->p;						\
	prefix##_datum_t *datum = (prefix##_datum_t *)d;		\
	prefix##_datum_t *parent;					\
	char *parent_name, *datum_name, *tmp;				\
									\
	if (!datum->bounds) {						\
		datum_name = p->p_##prefix##_val_to_name[datum->s.value - 1]; \
									\
		tmp = strrchr(datum_name, '.');				\
		/* no '.' means it has no parent */			\
		if (!tmp) return 0;					\
									\
		parent_name = strdup(datum_name);			\
		if (!parent_name) {					\
			ERR(handle, "Insufficient memory");		\
			return SEPOL_ENOMEM;				\
		}							\
		parent_name[tmp - datum_name] = '\0';			\
									\
		parent = hashtab_search(p->p_##prefix##s.table, parent_name); \
		if (!parent) {						\
			/* Orphan type/role/user */			\
			ERR(handle, "%s doesn't exist, %s is an orphan",\
			    parent_name,				\
			    p->p_##prefix##_val_to_name[datum->s.value - 1]); \
			free(parent_name);				\
			a->numbad++;					\
			return 0;					\
		}							\
		datum->bounds = parent->s.value;			\
		free(parent_name);					\
	}								\
									\
	return 0;							\
}								\

static add_hierarchy_callback_template(type)
static add_hierarchy_callback_template(role)
static add_hierarchy_callback_template(user)

int hierarchy_add_bounds(sepol_handle_t *handle, policydb_t *p)
{
	int rc = 0;
	struct bounds_args args;

	args.handle = handle;
	args.p = p;
	args.numbad = 0;

	rc = hashtab_map(p->p_users.table, hierarchy_add_user_callback, &args);
	if (rc) goto exit;

	rc = hashtab_map(p->p_roles.table, hierarchy_add_role_callback, &args);
	if (rc) goto exit;

	rc = hashtab_map(p->p_types.table, hierarchy_add_type_callback, &args);
	if (rc) goto exit;

	if (args.numbad > 0) {
		ERR(handle, "%d errors found while adding hierarchies",
		    args.numbad);
		rc = SEPOL_ERR;
	}

exit:
	return rc;
}

int hierarchy_check_constraints(sepol_handle_t * handle, policydb_t * p)
{
	int rc = 0;
	int violation = 0;

	rc = hierarchy_add_bounds(handle, p);
	if (rc) goto exit;

	rc = bounds_check_users(handle, p);
	if (rc)
		violation = 1;

	rc = bounds_check_roles(handle, p);
	if (rc)
		violation = 1;

	rc = bounds_check_types(handle, p);
	if (rc) {
		if (rc == SEPOL_ERR)
			violation = 1;
		else
			goto exit;
	}

	if (violation)
		rc = SEPOL_ERR;

exit:
	return rc;
}
