1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Implementation of the extensible bitmap type.
5 * Author : Stephen Smalley, <stephen.smalley.work@gmail.com>
8 * Updated: Hewlett-Packard <paul@paul-moore.com>
9 * Added support to import/export the NetLabel category bitmap
10 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
12 * Updated: KaiGai Kohei <kaigai@ak.jp.nec.com>
13 * Applied standard bit operations to improve bitmap scanning.
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
18 #include <linux/errno.h>
19 #include <linux/jhash.h>
20 #include <net/netlabel.h>
24 #define BITS_PER_U64 ((u32)(sizeof(u64) * 8))
26 static struct kmem_cache *ebitmap_node_cachep __ro_after_init;
28 int ebitmap_cmp(const struct ebitmap *e1, const struct ebitmap *e2)
30 const struct ebitmap_node *n1, *n2;
32 if (e1->highbit != e2->highbit)
37 while (n1 && n2 && (n1->startbit == n2->startbit) &&
38 !memcmp(n1->maps, n2->maps, EBITMAP_SIZE / 8)) {
49 int ebitmap_cpy(struct ebitmap *dst, const struct ebitmap *src)
51 struct ebitmap_node *new, *prev;
52 const struct ebitmap_node *n;
58 new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
63 new->startbit = n->startbit;
64 memcpy(new->maps, n->maps, EBITMAP_SIZE / 8);
74 dst->highbit = src->highbit;
78 int ebitmap_and(struct ebitmap *dst, const struct ebitmap *e1,
79 const struct ebitmap *e2)
81 struct ebitmap_node *n;
87 ebitmap_for_each_positive_bit(e1, n, bit)
89 if (ebitmap_get_bit(e2, bit)) {
90 rc = ebitmap_set_bit(dst, bit, 1);
98 #ifdef CONFIG_NETLABEL
100 * ebitmap_netlbl_export - Export an ebitmap into a NetLabel category bitmap
101 * @ebmap: the ebitmap to export
102 * @catmap: the NetLabel category bitmap
105 * Export a SELinux extensibile bitmap into a NetLabel category bitmap.
106 * Returns zero on success, negative values on error.
109 int ebitmap_netlbl_export(struct ebitmap *ebmap,
110 struct netlbl_lsm_catmap **catmap)
112 struct ebitmap_node *e_iter = ebmap->node;
118 if (e_iter == NULL) {
124 netlbl_catmap_free(*catmap);
128 offset = e_iter->startbit;
129 for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) {
130 e_map = e_iter->maps[iter];
132 rc = netlbl_catmap_setlong(catmap, offset,
135 goto netlbl_export_failure;
137 offset += EBITMAP_UNIT_SIZE;
139 e_iter = e_iter->next;
144 netlbl_export_failure:
145 netlbl_catmap_free(*catmap);
150 * ebitmap_netlbl_import - Import a NetLabel category bitmap into an ebitmap
151 * @ebmap: the ebitmap to import
152 * @catmap: the NetLabel category bitmap
155 * Import a NetLabel category bitmap into a SELinux extensibile bitmap.
156 * Returns zero on success, negative values on error.
159 int ebitmap_netlbl_import(struct ebitmap *ebmap,
160 struct netlbl_lsm_catmap *catmap)
163 struct ebitmap_node *e_iter = NULL;
164 struct ebitmap_node *e_prev = NULL;
166 unsigned long bitmap;
169 rc = netlbl_catmap_getlong(catmap, &offset, &bitmap);
171 goto netlbl_import_failure;
172 if (offset == (u32)-1)
175 /* don't waste ebitmap space if the netlabel bitmap is empty */
177 offset += EBITMAP_UNIT_SIZE;
181 if (e_iter == NULL ||
182 offset >= e_iter->startbit + EBITMAP_SIZE) {
184 e_iter = kmem_cache_zalloc(ebitmap_node_cachep,
187 goto netlbl_import_failure;
188 e_iter->startbit = offset - (offset % EBITMAP_SIZE);
190 ebmap->node = e_iter;
192 e_prev->next = e_iter;
193 ebmap->highbit = e_iter->startbit + EBITMAP_SIZE;
196 /* offset will always be aligned to an unsigned long */
197 idx = EBITMAP_NODE_INDEX(e_iter, offset);
198 e_iter->maps[idx] = bitmap;
201 offset += EBITMAP_UNIT_SIZE;
204 /* NOTE: we should never reach this return */
207 netlbl_import_failure:
208 ebitmap_destroy(ebmap);
211 #endif /* CONFIG_NETLABEL */
214 * Check to see if all the bits set in e2 are also set in e1. Optionally,
215 * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
218 int ebitmap_contains(const struct ebitmap *e1, const struct ebitmap *e2,
221 const struct ebitmap_node *n1, *n2;
224 if (e1->highbit < e2->highbit)
230 while (n1 && n2 && (n1->startbit <= n2->startbit)) {
231 if (n1->startbit < n2->startbit) {
235 for (i = EBITMAP_UNIT_NUMS - 1; (i >= 0) && !n2->maps[i];)
236 i--; /* Skip trailing NULL map entries */
237 if (last_e2bit && (i >= 0)) {
238 u32 lastsetbit = n2->startbit + i * EBITMAP_UNIT_SIZE +
240 if (lastsetbit > last_e2bit)
245 if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
260 int ebitmap_get_bit(const struct ebitmap *e, u32 bit)
262 const struct ebitmap_node *n;
264 if (e->highbit < bit)
268 while (n && (n->startbit <= bit)) {
269 if ((n->startbit + EBITMAP_SIZE) > bit)
270 return ebitmap_node_get_bit(n, bit);
277 int ebitmap_set_bit(struct ebitmap *e, u32 bit, int value)
279 struct ebitmap_node *n, *prev, *new;
283 while (n && n->startbit <= bit) {
284 if ((n->startbit + EBITMAP_SIZE) > bit) {
286 ebitmap_node_set_bit(n, bit);
290 ebitmap_node_clr_bit(n, bit);
292 s = find_first_bit(n->maps, EBITMAP_SIZE);
293 if (s < EBITMAP_SIZE)
296 /* drop this node from the bitmap */
299 * this was the highest map
303 e->highbit = prev->startbit +
309 prev->next = n->next;
312 kmem_cache_free(ebitmap_node_cachep, n);
323 new = kmem_cache_zalloc(ebitmap_node_cachep, GFP_ATOMIC);
327 new->startbit = bit - (bit % EBITMAP_SIZE);
328 ebitmap_node_set_bit(new, bit);
331 /* this node will be the highest map within the bitmap */
332 e->highbit = new->startbit + EBITMAP_SIZE;
335 new->next = prev->next;
345 void ebitmap_destroy(struct ebitmap *e)
347 struct ebitmap_node *n, *temp;
356 kmem_cache_free(ebitmap_node_cachep, temp);
363 int ebitmap_read(struct ebitmap *e, void *fp)
365 struct ebitmap_node *n = NULL;
366 u32 mapunit, count, startbit, index, i;
367 __le32 ebitmap_start;
375 rc = next_entry(buf, fp, sizeof buf);
379 mapunit = le32_to_cpu(buf[0]);
380 e->highbit = le32_to_cpu(buf[1]);
381 count = le32_to_cpu(buf[2]);
383 if (mapunit != BITS_PER_U64) {
384 pr_err("SELinux: ebitmap: map size %u does not "
385 "match my size %u (high bit was %u)\n",
386 mapunit, BITS_PER_U64, e->highbit);
390 /* round up e->highbit */
391 e->highbit += EBITMAP_SIZE - 1;
392 e->highbit -= (e->highbit % EBITMAP_SIZE);
399 if (e->highbit && !count)
402 for (i = 0; i < count; i++) {
403 rc = next_entry(&ebitmap_start, fp, sizeof(u32));
405 pr_err("SELinux: ebitmap: truncated map\n");
408 startbit = le32_to_cpu(ebitmap_start);
410 if (startbit & (mapunit - 1)) {
411 pr_err("SELinux: ebitmap start bit (%u) is "
412 "not a multiple of the map unit size (%u)\n",
416 if (startbit > e->highbit - mapunit) {
417 pr_err("SELinux: ebitmap start bit (%u) is "
418 "beyond the end of the bitmap (%u)\n",
419 startbit, (e->highbit - mapunit));
423 if (!n || startbit >= n->startbit + EBITMAP_SIZE) {
424 struct ebitmap_node *tmp;
425 tmp = kmem_cache_zalloc(ebitmap_node_cachep,
428 pr_err("SELinux: ebitmap: out of memory\n");
433 tmp->startbit = startbit - (startbit % EBITMAP_SIZE);
439 } else if (startbit <= n->startbit) {
440 pr_err("SELinux: ebitmap: start bit %u"
441 " comes after start bit %u\n",
442 startbit, n->startbit);
446 rc = next_entry(&mapbits, fp, sizeof(u64));
448 pr_err("SELinux: ebitmap: truncated map\n");
451 map = le64_to_cpu(mapbits);
453 pr_err("SELinux: ebitmap: empty map\n");
457 index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE;
459 n->maps[index++] = map & (-1UL);
460 map = EBITMAP_SHIFT_UNIT_SIZE(map);
464 if (n && n->startbit + EBITMAP_SIZE != e->highbit) {
465 pr_err("SELinux: ebitmap: high bit %u is not equal to the expected value %zu\n",
466 e->highbit, n->startbit + EBITMAP_SIZE);
481 int ebitmap_write(const struct ebitmap *e, void *fp)
483 struct ebitmap_node *n;
484 u32 bit, count, last_bit, last_startbit;
489 buf[0] = cpu_to_le32(BITS_PER_U64);
493 last_startbit = U32_MAX;
494 ebitmap_for_each_positive_bit(e, n, bit)
496 if (last_startbit == U32_MAX ||
497 rounddown(bit, BITS_PER_U64) > last_startbit) {
499 last_startbit = rounddown(bit, BITS_PER_U64);
501 last_bit = roundup(bit + 1, BITS_PER_U64);
503 buf[1] = cpu_to_le32(last_bit);
504 buf[2] = cpu_to_le32(count);
506 rc = put_entry(buf, sizeof(u32), 3, fp);
511 last_startbit = U32_MAX;
512 ebitmap_for_each_positive_bit(e, n, bit)
514 if (last_startbit == U32_MAX ||
515 rounddown(bit, BITS_PER_U64) > last_startbit) {
518 /* this is the very first bit */
520 last_startbit = rounddown(bit, BITS_PER_U64);
521 map = (u64)1 << (bit - last_startbit);
525 /* write the last node */
526 buf[0] = cpu_to_le32(last_startbit);
527 rc = put_entry(buf, sizeof(u32), 1, fp);
531 buf64[0] = cpu_to_le64(map);
532 rc = put_entry(buf64, sizeof(u64), 1, fp);
536 /* set up for the next node */
538 last_startbit = rounddown(bit, BITS_PER_U64);
540 map |= (u64)1 << (bit - last_startbit);
542 /* write the last node */
546 /* write the last node */
547 buf[0] = cpu_to_le32(last_startbit);
548 rc = put_entry(buf, sizeof(u32), 1, fp);
552 buf64[0] = cpu_to_le64(map);
553 rc = put_entry(buf64, sizeof(u64), 1, fp);
560 u32 ebitmap_hash(const struct ebitmap *e, u32 hash)
562 struct ebitmap_node *node;
564 /* need to change hash even if ebitmap is empty */
565 hash = jhash_1word(e->highbit, hash);
566 for (node = e->node; node; node = node->next) {
567 hash = jhash_1word(node->startbit, hash);
568 hash = jhash(node->maps, sizeof(node->maps), hash);
573 void __init ebitmap_cache_init(void)
575 ebitmap_node_cachep = KMEM_CACHE(ebitmap_node, SLAB_PANIC);