.. | .. |
---|
19 | 19 | #include <linux/kernel.h> |
---|
20 | 20 | #include <linux/slab.h> |
---|
21 | 21 | #include <linux/errno.h> |
---|
| 22 | +#include <linux/jhash.h> |
---|
22 | 23 | #include <net/netlabel.h> |
---|
23 | 24 | #include "ebitmap.h" |
---|
24 | 25 | #include "policydb.h" |
---|
.. | .. |
---|
76 | 77 | dst->highbit = src->highbit; |
---|
77 | 78 | return 0; |
---|
78 | 79 | } |
---|
| 80 | + |
---|
| 81 | +int ebitmap_and(struct ebitmap *dst, struct ebitmap *e1, struct ebitmap *e2) |
---|
| 82 | +{ |
---|
| 83 | + struct ebitmap_node *n; |
---|
| 84 | + int bit, rc; |
---|
| 85 | + |
---|
| 86 | + ebitmap_init(dst); |
---|
| 87 | + |
---|
| 88 | + ebitmap_for_each_positive_bit(e1, n, bit) { |
---|
| 89 | + if (ebitmap_get_bit(e2, bit)) { |
---|
| 90 | + rc = ebitmap_set_bit(dst, bit, 1); |
---|
| 91 | + if (rc < 0) |
---|
| 92 | + return rc; |
---|
| 93 | + } |
---|
| 94 | + } |
---|
| 95 | + return 0; |
---|
| 96 | +} |
---|
| 97 | + |
---|
79 | 98 | |
---|
80 | 99 | #ifdef CONFIG_NETLABEL |
---|
81 | 100 | /** |
---|
.. | .. |
---|
347 | 366 | { |
---|
348 | 367 | struct ebitmap_node *n = NULL; |
---|
349 | 368 | u32 mapunit, count, startbit, index; |
---|
| 369 | + __le32 ebitmap_start; |
---|
350 | 370 | u64 map; |
---|
| 371 | + __le64 mapbits; |
---|
351 | 372 | __le32 buf[3]; |
---|
352 | 373 | int rc, i; |
---|
353 | 374 | |
---|
.. | .. |
---|
381 | 402 | goto bad; |
---|
382 | 403 | |
---|
383 | 404 | for (i = 0; i < count; i++) { |
---|
384 | | - rc = next_entry(&startbit, fp, sizeof(u32)); |
---|
| 405 | + rc = next_entry(&ebitmap_start, fp, sizeof(u32)); |
---|
385 | 406 | if (rc < 0) { |
---|
386 | 407 | pr_err("SELinux: ebitmap: truncated map\n"); |
---|
387 | 408 | goto bad; |
---|
388 | 409 | } |
---|
389 | | - startbit = le32_to_cpu(startbit); |
---|
| 410 | + startbit = le32_to_cpu(ebitmap_start); |
---|
390 | 411 | |
---|
391 | 412 | if (startbit & (mapunit - 1)) { |
---|
392 | 413 | pr_err("SELinux: ebitmap start bit (%d) is " |
---|
.. | .. |
---|
423 | 444 | goto bad; |
---|
424 | 445 | } |
---|
425 | 446 | |
---|
426 | | - rc = next_entry(&map, fp, sizeof(u64)); |
---|
| 447 | + rc = next_entry(&mapbits, fp, sizeof(u64)); |
---|
427 | 448 | if (rc < 0) { |
---|
428 | 449 | pr_err("SELinux: ebitmap: truncated map\n"); |
---|
429 | 450 | goto bad; |
---|
430 | 451 | } |
---|
431 | | - map = le64_to_cpu(map); |
---|
| 452 | + map = le64_to_cpu(mapbits); |
---|
432 | 453 | |
---|
433 | 454 | index = (startbit - n->startbit) / EBITMAP_UNIT_SIZE; |
---|
434 | 455 | while (map) { |
---|
.. | .. |
---|
522 | 543 | return 0; |
---|
523 | 544 | } |
---|
524 | 545 | |
---|
| 546 | +u32 ebitmap_hash(const struct ebitmap *e, u32 hash) |
---|
| 547 | +{ |
---|
| 548 | + struct ebitmap_node *node; |
---|
| 549 | + |
---|
| 550 | + /* need to change hash even if ebitmap is empty */ |
---|
| 551 | + hash = jhash_1word(e->highbit, hash); |
---|
| 552 | + for (node = e->node; node; node = node->next) { |
---|
| 553 | + hash = jhash_1word(node->startbit, hash); |
---|
| 554 | + hash = jhash(node->maps, sizeof(node->maps), hash); |
---|
| 555 | + } |
---|
| 556 | + return hash; |
---|
| 557 | +} |
---|
| 558 | + |
---|
525 | 559 | void __init ebitmap_cache_init(void) |
---|
526 | 560 | { |
---|
527 | 561 | ebitmap_node_cachep = kmem_cache_create("ebitmap_node", |
---|