/*
 * Implementation of the extensible bitmap type.
 *
 * Author : Stephen Smalley, <sds@epoch.ncsc.mil>
 */
/*
 * Updated: Hewlett-Packard <paul.moore@hp.com>
 *
 *      Added support to import/export the NetLabel category bitmap
 *
 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
 */
/*
 * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com>
 *      Applied standard bit operations to improve bitmap scanning.
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <net/netlabel.h>
#include "ebitmap.h"
#include "policydb.h"

int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2)
{
	struct ebitmap_node *n1, *n2;

	if (e1->highbit != e2->highbit)
		return 0;

	n1 = e1->node;
	n2 = e2->node;
	while (n1 && n2 &&
	       (n1->startbit == n2->startbit) &&
	       !memcmp(n1->maps, n2->maps, EBITMAP_SIZE / 8)) {
		n1 = n1->next;
		n2 = n2->next;
	}

	if (n1 || n2)
		return 0;

	return 1;
}

int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src)
{
	struct ebitmap_node *n, *new, *prev;

	ebitmap_init(dst);
	n = src->node;
	prev = NULL;
	while (n) {
		new = kzalloc(sizeof(*new), GFP_ATOMIC);
		if (!new) {
			ebitmap_destroy(dst);
			return -ENOMEM;
		}
		new->startbit = n->startbit;
		memcpy(new->maps, n->maps, EBITMAP_SIZE / 8);
		new->next = NULL;
		if (prev)
			prev->next = new;
		else
			dst->node = new;
		prev = new;
		n = n->next;
	}

	dst->highbit = src->highbit;
	return 0;
}

#ifdef CONFIG_NETLABEL
/**
 * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap
 * @ebmap: the ebitmap to export
 * @catmap: the NetLabel category bitmap
 *
 * Description:
 * Export a SELinux extensibile bitmap into a NetLabel category bitmap.
 * Returns zero on success, negative values on error.
 *
 */
int ebitmap_netlbl_export(struct ebitmap *ebmap,
			  struct netlbl_lsm_secattr_catmap **catmap)
{
	struct ebitmap_node *e_iter = ebmap->node;
	struct netlbl_lsm_secattr_catmap *c_iter;
	u32 cmap_idx, cmap_sft;
	int i;

	/* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
	 * however, it is not always compatible with an array of unsigned long
	 * in ebitmap_node.
	 * In addition, you should pay attention the following implementation
	 * assumes unsigned long has a width equal with or less than 64-bit.
	 */

	if (e_iter == NULL) {
		*catmap = NULL;
		return 0;
	}

	c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
	if (c_iter == NULL)
		return -ENOMEM;
	*catmap = c_iter;
	c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1);

	while (e_iter != NULL) {
		for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
			unsigned int delta, e_startbit, c_endbit;

			e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE;
			c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE;
			if (e_startbit >= c_endbit) {
				c_iter->next
				  = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
				if (c_iter->next == NULL)
					goto netlbl_export_failure;
				c_iter = c_iter->next;
				c_iter->startbit
				  = e_startbit & ~(NETLBL_CATMAP_SIZE - 1);
			}
			delta = e_startbit - c_iter->startbit;
			cmap_idx = delta / NETLBL_CATMAP_MAPSIZE;
			cmap_sft = delta % NETLBL_CATMAP_MAPSIZE;
			c_iter->bitmap[cmap_idx]
				|= e_iter->maps[cmap_idx] << cmap_sft;
		}
		e_iter = e_iter->next;
	}

	return 0;

netlbl_export_failure:
	netlbl_secattr_catmap_free(*catmap);
	return -ENOMEM;
}

/**
 * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap
 * @ebmap: the ebitmap to import
 * @catmap: the NetLabel category bitmap
 *
 * Description:
 * Import a NetLabel category bitmap into a SELinux extensibile bitmap.
 * Returns zero on success, negative values on error.
 *
 */
int ebitmap_netlbl_import(struct ebitmap *ebmap,
			  struct netlbl_lsm_secattr_catmap *catmap)
{
	struct ebitmap_node *e_iter = NULL;
	struct ebitmap_node *emap_prev = NULL;
	struct netlbl_lsm_secattr_catmap *c_iter = catmap;
	u32 c_idx, c_pos, e_idx, e_sft;

	/* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64,
	 * however, it is not always compatible with an array of unsigned long
	 * in ebitmap_node.
	 * In addition, you should pay attention the following implementation
	 * assumes unsigned long has a width equal with or less than 64-bit.
	 */

	do {
		for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) {
			unsigned int delta;
			u64 map = c_iter->bitmap[c_idx];

			if (!map)
				continue;

			c_pos = c_iter->startbit
				+ c_idx * NETLBL_CATMAP_MAPSIZE;
			if (!e_iter
			    || c_pos >= e_iter->startbit + EBITMAP_SIZE) {
				e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC);
				if (!e_iter)
					goto netlbl_import_failure;
				e_iter->startbit
					= c_pos - (c_pos % EBITMAP_SIZE);
				if (emap_prev == NULL)
					ebmap->node = e_iter;
				else
					emap_prev->next = e_iter;
				emap_prev = e_iter;
			}
			delta = c_pos - e_iter->startbit;
			e_idx = delta / EBITMAP_UNIT_SIZE;
			e_sft = delta % EBITMAP_UNIT_SIZE;
			while (map) {
				e_iter->maps[e_idx++] |= map & (-1UL);
				map = EBITMAP_SHIFT_UNIT_SIZE(map);
			}
		}
		c_iter = c_iter->next;
	} while (c_iter != NULL);
	if (e_iter != NULL)
		ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
	else
		ebitmap_destroy(ebmap);

	return 0;

netlbl_import_failure:
	ebitmap_destroy(ebmap);
	return -ENOMEM;
}
#endif /* CONFIG_NETLABEL */

int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
{
	struct ebitmap_node *n1, *n2;
	int i;

	if (e1->highbit < e2->highbit)
		return 0;

	n1 = e1->node;
	n2 = e2->node;
	while (n1 && n2 && (n1->startbit <= n2->startbit)) {
		if (n1->startbit < n2->startbit) {
			n1 = n1->next;
			continue;
		}
		for (i = 0; i < EBITMAP_UNIT_NUMS; i++) {
			if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
				return 0;
		}

		n1 = n1->next;
		n2 = n2->next;
	}

	if (n2)
		return 0;

	return 1;
}

int ebitmap_get_bit(struct ebitmap *e, unsigned long bit)
{
	struct ebitmap_node *n;

	if (e->highbit < bit)
		return 0;

	n = e->node;
	while (n && (n->startbit <= bit)) {
		if ((n->startbit + EBITMAP_SIZE) > bit)
			return ebitmap_node_get_bit(n, bit);
		n = n->next;
	}

	return 0;
}

int ebitmap_set_bit(struct ebitmap *e, unsigned long bit, int value)
{
	struct ebitmap_node *n, *prev, *new;

	prev = NULL;
	n = e->node;
	while (n && n->startbit <= bit) {
		if ((n->startbit + EBITMAP_SIZE) > bit) {
			if (value) {
				ebitmap_node_set_bit(n, bit);
			} else {
				unsigned int s;

				ebitmap_node_clr_bit(n, bit);

				s = find_first_bit(n->maps, EBITMAP_SIZE);
				if (s < EBITMAP_SIZE)
					return 0;

				/* drop this node from the bitmap */
				if (!n->next) {
					/*
					 * this was the highest map
					 * within the bitmap
					 */
					if (prev)
						e->highbit = prev->startbit
							     + EBITMAP_SIZE;
					else
						e->highbit = 0;
				}
				if (prev)
					prev->next = n->next;
				else
					e->node = n->next;
				kfree(n);
			}
			return 0;
		}
		prev = n;
		n = n->next;
	}

	if (!value)
		return 0;

	new = kzalloc(sizeof(*new), GFP_ATOMIC);
	if (!new)
		return -ENOMEM;

	new->startbit = bit - (bit % EBITMAP_SIZE);
	ebitmap_node_set_bit(new, bit);

	if (!n)
		/* this node will be the highest map within the bitmap */
		e->highbit = new->startbit + EBITMAP_SIZE;

	if (prev) {
		new->next = prev->next;
		prev->next = new;
	} else {
		new->next = e->node;
		e->node = new;
	}

	return 0;
}

void ebitmap_destroy(struct ebitmap *e)
{
	struct ebitmap_node *n, *temp;

	if (!e)
		return;

	n = e->node;
	while (n) {
		temp = n;
		n = n->next;
		kfree(temp);
	}

	e->highbit = 0;
	e->node = NULL;
	return;
}

int ebitmap_read(struct ebitmap *e, void *fp)
{
	struct ebitmap_node *n = NULL;
	u32 mapunit, count, startbit, index;
	u64 map;
	__le32 buf[3];
	int rc, i;

	ebitmap_init(e);

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

	mapunit = le32_to_cpu(buf[0]);
	e->highbit = le32_to_cpu(buf[1]);
	count = le32_to_cpu(buf[2]);

	if (mapunit != sizeof(u64) * 8) {
		printk(KERN_ERR "SELinux: ebitmap: map size %u does not "
		       "match my size %Zd (high bit was %d)\n",
		       mapunit, sizeof(u64) * 8, e->highbit);
		goto bad;
	}

	/* round up e->highbit */
	e->highbit += EBITMAP_SIZE - 1;
	e->highbit -= (e->highbit % EBITMAP_SIZE);

	if (!e->highbit) {
		e->node = NULL;
		goto ok;
	}

	for (i = 0; i < count; i++) {
		rc = next_entry(&startbit, fp, sizeof(u32));
		if (rc < 0) {
			printk(KERN_ERR "SELinux: ebitmap: truncated map\n");
			goto bad;
		}
		startbit = le32_to_cpu(startbit);

		if (startbit & (mapunit - 1)) {
			printk(KERN_ERR "SELinux: ebitmap start bit (%d) is "
			       "not a multiple of the map unit size (%u)\n",
			       startbit, mapunit);
			goto bad;
		}
		if (startbit > e->highbit - mapunit) {
			printk(KERN_ERR "SELinux: ebitmap start bit (%d) is "
			       "beyond the end of the bitmap (%u)\n",
			       startbit, (e->highbit - mapunit));
			goto bad;
		}

		if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
			struct ebitmap_node *tmp;
			tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
			if (!tmp) {
				printk(KERN_ERR
				       "SELinux: ebitmap: out of memory\n");
				rc = -ENOMEM;
				goto bad;
			}
			/* round down */
			tmp->startbit = startbit - (startbit % EBITMAP_SIZE);
			if (n)
				n->next = tmp;
			else
				e->node = tmp;
			n = tmp;
		} else if (startbit <= n->startbit) {
			printk(KERN_ERR "SELinux: ebitmap: start bit %d"
			       " comes after start bit %d\n",
			       startbit, n->startbit);
			goto bad;
		}

		rc = next_entry(&map, fp, sizeof(u64));
		if (rc < 0) {
			printk(KERN_ERR "SELinux: ebitmap: truncated map\n");
			goto bad;
		}
		map = le64_to_cpu(map);

		index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE;
		while (map) {
			n->maps[index++] = map & (-1UL);
			map = EBITMAP_SHIFT_UNIT_SIZE(map);
		}
	}
ok:
	rc = 0;
out:
	return rc;
bad:
	if (!rc)
		rc = -EINVAL;
	ebitmap_destroy(e);
	goto out;
}
