| .. | .. |
|---|
| 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", |
|---|