diff options
Diffstat (limited to 'security/selinux/ss/ebitmap.c')
| -rw-r--r-- | security/selinux/ss/ebitmap.c | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index 04b6145d767f..d42951fcbe87 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
| @@ -22,6 +22,8 @@ | |||
| 22 | #include "ebitmap.h" | 22 | #include "ebitmap.h" |
| 23 | #include "policydb.h" | 23 | #include "policydb.h" |
| 24 | 24 | ||
| 25 | #define BITS_PER_U64 (sizeof(u64) * 8) | ||
| 26 | |||
| 25 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) | 27 | int ebitmap_cmp(struct ebitmap *e1, struct ebitmap *e2) |
| 26 | { | 28 | { |
| 27 | struct ebitmap_node *n1, *n2; | 29 | struct ebitmap_node *n1, *n2; |
| @@ -363,10 +365,10 @@ int ebitmap_read(struct ebitmap *e, void *fp) | |||
| 363 | e->highbit = le32_to_cpu(buf[1]); | 365 | e->highbit = le32_to_cpu(buf[1]); |
| 364 | count = le32_to_cpu(buf[2]); | 366 | count = le32_to_cpu(buf[2]); |
| 365 | 367 | ||
| 366 | if (mapunit != sizeof(u64) * 8) { | 368 | if (mapunit != BITS_PER_U64) { |
| 367 | printk(KERN_ERR "SELinux: ebitmap: map size %u does not " | 369 | printk(KERN_ERR "SELinux: ebitmap: map size %u does not " |
| 368 | "match my size %Zd (high bit was %d)\n", | 370 | "match my size %Zd (high bit was %d)\n", |
| 369 | mapunit, sizeof(u64) * 8, e->highbit); | 371 | mapunit, BITS_PER_U64, e->highbit); |
| 370 | goto bad; | 372 | goto bad; |
| 371 | } | 373 | } |
| 372 | 374 | ||
| @@ -446,3 +448,78 @@ bad: | |||
| 446 | ebitmap_destroy(e); | 448 | ebitmap_destroy(e); |
| 447 | goto out; | 449 | goto out; |
| 448 | } | 450 | } |
| 451 | |||
| 452 | int ebitmap_write(struct ebitmap *e, void *fp) | ||
| 453 | { | ||
| 454 | struct ebitmap_node *n; | ||
| 455 | u32 count; | ||
| 456 | __le32 buf[3]; | ||
| 457 | u64 map; | ||
| 458 | int bit, last_bit, last_startbit, rc; | ||
| 459 | |||
| 460 | buf[0] = cpu_to_le32(BITS_PER_U64); | ||
| 461 | |||
| 462 | count = 0; | ||
| 463 | last_bit = 0; | ||
| 464 | last_startbit = -1; | ||
| 465 | ebitmap_for_each_positive_bit(e, n, bit) { | ||
| 466 | if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) { | ||
| 467 | count++; | ||
| 468 | last_startbit = rounddown(bit, BITS_PER_U64); | ||
| 469 | } | ||
| 470 | last_bit = roundup(bit + 1, BITS_PER_U64); | ||
| 471 | } | ||
| 472 | buf[1] = cpu_to_le32(last_bit); | ||
| 473 | buf[2] = cpu_to_le32(count); | ||
| 474 | |||
| 475 | rc = put_entry(buf, sizeof(u32), 3, fp); | ||
| 476 | if (rc) | ||
| 477 | return rc; | ||
| 478 | |||
| 479 | map = 0; | ||
| 480 | last_startbit = INT_MIN; | ||
| 481 | ebitmap_for_each_positive_bit(e, n, bit) { | ||
| 482 | if (rounddown(bit, (int)BITS_PER_U64) > last_startbit) { | ||
| 483 | __le64 buf64[1]; | ||
| 484 | |||
| 485 | /* this is the very first bit */ | ||
| 486 | if (!map) { | ||
| 487 | last_startbit = rounddown(bit, BITS_PER_U64); | ||
| 488 | map = (u64)1 << (bit - last_startbit); | ||
| 489 | continue; | ||
| 490 | } | ||
| 491 | |||
| 492 | /* write the last node */ | ||
| 493 | buf[0] = cpu_to_le32(last_startbit); | ||
| 494 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
| 495 | if (rc) | ||
| 496 | return rc; | ||
| 497 | |||
| 498 | buf64[0] = cpu_to_le64(map); | ||
| 499 | rc = put_entry(buf64, sizeof(u64), 1, fp); | ||
| 500 | if (rc) | ||
| 501 | return rc; | ||
| 502 | |||
| 503 | /* set up for the next node */ | ||
| 504 | map = 0; | ||
| 505 | last_startbit = rounddown(bit, BITS_PER_U64); | ||
| 506 | } | ||
| 507 | map |= (u64)1 << (bit - last_startbit); | ||
| 508 | } | ||
| 509 | /* write the last node */ | ||
| 510 | if (map) { | ||
| 511 | __le64 buf64[1]; | ||
| 512 | |||
| 513 | /* write the last node */ | ||
| 514 | buf[0] = cpu_to_le32(last_startbit); | ||
| 515 | rc = put_entry(buf, sizeof(u32), 1, fp); | ||
| 516 | if (rc) | ||
| 517 | return rc; | ||
| 518 | |||
| 519 | buf64[0] = cpu_to_le64(map); | ||
| 520 | rc = put_entry(buf64, sizeof(u64), 1, fp); | ||
| 521 | if (rc) | ||
| 522 | return rc; | ||
| 523 | } | ||
| 524 | return 0; | ||
| 525 | } | ||
