aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-08-02 08:58:02 -0400
committerJames Morris <james.l.morris@oracle.com>2014-08-02 08:58:02 -0400
commit103ae675b12dee75ec099abf3d22857d1384b3bc (patch)
treea6b4f71bc911e7283b6573ee5833cd36a3ac2469 /net
parenta3d64df849bcb84220bf6db5773a10eee1fad4dc (diff)
parent4fbe63d1c773cceef3fe1f6ed0c9c268f4f24760 (diff)
Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'net')
-rw-r--r--net/ipv4/cipso_ipv4.c47
-rw-r--r--net/netlabel/netlabel_kapi.c327
2 files changed, 243 insertions, 131 deletions
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 69e77c8ff285..05b708bbdb0d 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -890,8 +890,8 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
890 } 890 }
891 891
892 for (;;) { 892 for (;;) {
893 host_spot = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 893 host_spot = netlbl_catmap_walk(secattr->attr.mls.cat,
894 host_spot + 1); 894 host_spot + 1);
895 if (host_spot < 0) 895 if (host_spot < 0)
896 break; 896 break;
897 897
@@ -973,7 +973,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
973 return -EPERM; 973 return -EPERM;
974 break; 974 break;
975 } 975 }
976 ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat, 976 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
977 host_spot, 977 host_spot,
978 GFP_ATOMIC); 978 GFP_ATOMIC);
979 if (ret_val != 0) 979 if (ret_val != 0)
@@ -1039,8 +1039,7 @@ static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
1039 u32 cat_iter = 0; 1039 u32 cat_iter = 0;
1040 1040
1041 for (;;) { 1041 for (;;) {
1042 cat = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 1042 cat = netlbl_catmap_walk(secattr->attr.mls.cat, cat + 1);
1043 cat + 1);
1044 if (cat < 0) 1043 if (cat < 0)
1045 break; 1044 break;
1046 if ((cat_iter + 2) > net_cat_len) 1045 if ((cat_iter + 2) > net_cat_len)
@@ -1075,9 +1074,9 @@ static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1075 u32 iter; 1074 u32 iter;
1076 1075
1077 for (iter = 0; iter < net_cat_len; iter += 2) { 1076 for (iter = 0; iter < net_cat_len; iter += 2) {
1078 ret_val = netlbl_secattr_catmap_setbit(secattr->attr.mls.cat, 1077 ret_val = netlbl_catmap_setbit(&secattr->attr.mls.cat,
1079 get_unaligned_be16(&net_cat[iter]), 1078 get_unaligned_be16(&net_cat[iter]),
1080 GFP_ATOMIC); 1079 GFP_ATOMIC);
1081 if (ret_val != 0) 1080 if (ret_val != 0)
1082 return ret_val; 1081 return ret_val;
1083 } 1082 }
@@ -1155,8 +1154,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1155 return -ENOSPC; 1154 return -ENOSPC;
1156 1155
1157 for (;;) { 1156 for (;;) {
1158 iter = netlbl_secattr_catmap_walk(secattr->attr.mls.cat, 1157 iter = netlbl_catmap_walk(secattr->attr.mls.cat, iter + 1);
1159 iter + 1);
1160 if (iter < 0) 1158 if (iter < 0)
1161 break; 1159 break;
1162 cat_size += (iter == 0 ? 0 : sizeof(u16)); 1160 cat_size += (iter == 0 ? 0 : sizeof(u16));
@@ -1164,8 +1162,7 @@ static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1164 return -ENOSPC; 1162 return -ENOSPC;
1165 array[array_cnt++] = iter; 1163 array[array_cnt++] = iter;
1166 1164
1167 iter = netlbl_secattr_catmap_walk_rng(secattr->attr.mls.cat, 1165 iter = netlbl_catmap_walkrng(secattr->attr.mls.cat, iter);
1168 iter);
1169 if (iter < 0) 1166 if (iter < 0)
1170 return -EFAULT; 1167 return -EFAULT;
1171 cat_size += sizeof(u16); 1168 cat_size += sizeof(u16);
@@ -1217,10 +1214,10 @@ static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1217 else 1214 else
1218 cat_low = 0; 1215 cat_low = 0;
1219 1216
1220 ret_val = netlbl_secattr_catmap_setrng(secattr->attr.mls.cat, 1217 ret_val = netlbl_catmap_setrng(&secattr->attr.mls.cat,
1221 cat_low, 1218 cat_low,
1222 cat_high, 1219 cat_high,
1223 GFP_ATOMIC); 1220 GFP_ATOMIC);
1224 if (ret_val != 0) 1221 if (ret_val != 0)
1225 return ret_val; 1222 return ret_val;
1226 } 1223 }
@@ -1335,16 +1332,12 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1335 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1332 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1336 1333
1337 if (tag_len > 4) { 1334 if (tag_len > 4) {
1338 secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1339 if (secattr->attr.mls.cat == NULL)
1340 return -ENOMEM;
1341
1342 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, 1335 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1343 &tag[4], 1336 &tag[4],
1344 tag_len - 4, 1337 tag_len - 4,
1345 secattr); 1338 secattr);
1346 if (ret_val != 0) { 1339 if (ret_val != 0) {
1347 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1340 netlbl_catmap_free(secattr->attr.mls.cat);
1348 return ret_val; 1341 return ret_val;
1349 } 1342 }
1350 1343
@@ -1430,16 +1423,12 @@ static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1430 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1423 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1431 1424
1432 if (tag_len > 4) { 1425 if (tag_len > 4) {
1433 secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1434 if (secattr->attr.mls.cat == NULL)
1435 return -ENOMEM;
1436
1437 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def, 1426 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1438 &tag[4], 1427 &tag[4],
1439 tag_len - 4, 1428 tag_len - 4,
1440 secattr); 1429 secattr);
1441 if (ret_val != 0) { 1430 if (ret_val != 0) {
1442 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1431 netlbl_catmap_free(secattr->attr.mls.cat);
1443 return ret_val; 1432 return ret_val;
1444 } 1433 }
1445 1434
@@ -1524,16 +1513,12 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1524 secattr->flags |= NETLBL_SECATTR_MLS_LVL; 1513 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1525 1514
1526 if (tag_len > 4) { 1515 if (tag_len > 4) {
1527 secattr->attr.mls.cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1528 if (secattr->attr.mls.cat == NULL)
1529 return -ENOMEM;
1530
1531 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def, 1516 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1532 &tag[4], 1517 &tag[4],
1533 tag_len - 4, 1518 tag_len - 4,
1534 secattr); 1519 secattr);
1535 if (ret_val != 0) { 1520 if (ret_val != 0) {
1536 netlbl_secattr_catmap_free(secattr->attr.mls.cat); 1521 netlbl_catmap_free(secattr->attr.mls.cat);
1537 return ret_val; 1522 return ret_val;
1538 } 1523 }
1539 1524
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 3045a964f39c..05ea4a4cc0ac 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -405,8 +405,72 @@ out_entry:
405 * Security Attribute Functions 405 * Security Attribute Functions
406 */ 406 */
407 407
408#define _CM_F_NONE 0x00000000
409#define _CM_F_ALLOC 0x00000001
410#define _CM_F_WALK 0x00000002
411
408/** 412/**
409 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit 413 * _netlbl_catmap_getnode - Get a individual node from a catmap
414 * @catmap: pointer to the category bitmap
415 * @offset: the requested offset
416 * @cm_flags: catmap flags, see _CM_F_*
417 * @gfp_flags: memory allocation flags
418 *
419 * Description:
420 * Iterate through the catmap looking for the node associated with @offset.
421 * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
422 * one will be created and inserted into the catmap. If the _CM_F_WALK flag is
423 * set in @cm_flags and there is no associated node, the next highest node will
424 * be returned. Returns a pointer to the node on success, NULL on failure.
425 *
426 */
427static struct netlbl_lsm_catmap *_netlbl_catmap_getnode(
428 struct netlbl_lsm_catmap **catmap,
429 u32 offset,
430 unsigned int cm_flags,
431 gfp_t gfp_flags)
432{
433 struct netlbl_lsm_catmap *iter = *catmap;
434 struct netlbl_lsm_catmap *prev = NULL;
435
436 if (iter == NULL)
437 goto catmap_getnode_alloc;
438 if (offset < iter->startbit)
439 goto catmap_getnode_walk;
440 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
441 prev = iter;
442 iter = iter->next;
443 }
444 if (iter == NULL || offset < iter->startbit)
445 goto catmap_getnode_walk;
446
447 return iter;
448
449catmap_getnode_walk:
450 if (cm_flags & _CM_F_WALK)
451 return iter;
452catmap_getnode_alloc:
453 if (!(cm_flags & _CM_F_ALLOC))
454 return NULL;
455
456 iter = netlbl_catmap_alloc(gfp_flags);
457 if (iter == NULL)
458 return NULL;
459 iter->startbit = offset & ~(NETLBL_CATMAP_SIZE - 1);
460
461 if (prev == NULL) {
462 iter->next = *catmap;
463 *catmap = iter;
464 } else {
465 iter->next = prev->next;
466 prev->next = iter;
467 }
468
469 return iter;
470}
471
472/**
473 * netlbl_catmap_walk - Walk a LSM secattr catmap looking for a bit
410 * @catmap: the category bitmap 474 * @catmap: the category bitmap
411 * @offset: the offset to start searching at, in bits 475 * @offset: the offset to start searching at, in bits
412 * 476 *
@@ -415,54 +479,51 @@ out_entry:
415 * returns the spot of the first set bit or -ENOENT if no bits are set. 479 * returns the spot of the first set bit or -ENOENT if no bits are set.
416 * 480 *
417 */ 481 */
418int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, 482int netlbl_catmap_walk(struct netlbl_lsm_catmap *catmap, u32 offset)
419 u32 offset)
420{ 483{
421 struct netlbl_lsm_secattr_catmap *iter = catmap; 484 struct netlbl_lsm_catmap *iter = catmap;
422 u32 node_idx; 485 u32 idx;
423 u32 node_bit; 486 u32 bit;
424 NETLBL_CATMAP_MAPTYPE bitmap; 487 NETLBL_CATMAP_MAPTYPE bitmap;
425 488
489 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
490 if (iter == NULL)
491 return -ENOENT;
426 if (offset > iter->startbit) { 492 if (offset > iter->startbit) {
427 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 493 offset -= iter->startbit;
428 iter = iter->next; 494 idx = offset / NETLBL_CATMAP_MAPSIZE;
429 if (iter == NULL) 495 bit = offset % NETLBL_CATMAP_MAPSIZE;
430 return -ENOENT;
431 }
432 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
433 node_bit = offset - iter->startbit -
434 (NETLBL_CATMAP_MAPSIZE * node_idx);
435 } else { 496 } else {
436 node_idx = 0; 497 idx = 0;
437 node_bit = 0; 498 bit = 0;
438 } 499 }
439 bitmap = iter->bitmap[node_idx] >> node_bit; 500 bitmap = iter->bitmap[idx] >> bit;
440 501
441 for (;;) { 502 for (;;) {
442 if (bitmap != 0) { 503 if (bitmap != 0) {
443 while ((bitmap & NETLBL_CATMAP_BIT) == 0) { 504 while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
444 bitmap >>= 1; 505 bitmap >>= 1;
445 node_bit++; 506 bit++;
446 } 507 }
447 return iter->startbit + 508 return iter->startbit +
448 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit; 509 (NETLBL_CATMAP_MAPSIZE * idx) + bit;
449 } 510 }
450 if (++node_idx >= NETLBL_CATMAP_MAPCNT) { 511 if (++idx >= NETLBL_CATMAP_MAPCNT) {
451 if (iter->next != NULL) { 512 if (iter->next != NULL) {
452 iter = iter->next; 513 iter = iter->next;
453 node_idx = 0; 514 idx = 0;
454 } else 515 } else
455 return -ENOENT; 516 return -ENOENT;
456 } 517 }
457 bitmap = iter->bitmap[node_idx]; 518 bitmap = iter->bitmap[idx];
458 node_bit = 0; 519 bit = 0;
459 } 520 }
460 521
461 return -ENOENT; 522 return -ENOENT;
462} 523}
463 524
464/** 525/**
465 * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits 526 * netlbl_catmap_walkrng - Find the end of a string of set bits
466 * @catmap: the category bitmap 527 * @catmap: the category bitmap
467 * @offset: the offset to start searching at, in bits 528 * @offset: the offset to start searching at, in bits
468 * 529 *
@@ -472,57 +533,105 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
472 * the end of the bitmap. 533 * the end of the bitmap.
473 * 534 *
474 */ 535 */
475int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 536int netlbl_catmap_walkrng(struct netlbl_lsm_catmap *catmap, u32 offset)
476 u32 offset)
477{ 537{
478 struct netlbl_lsm_secattr_catmap *iter = catmap; 538 struct netlbl_lsm_catmap *iter;
479 u32 node_idx; 539 struct netlbl_lsm_catmap *prev = NULL;
480 u32 node_bit; 540 u32 idx;
541 u32 bit;
481 NETLBL_CATMAP_MAPTYPE bitmask; 542 NETLBL_CATMAP_MAPTYPE bitmask;
482 NETLBL_CATMAP_MAPTYPE bitmap; 543 NETLBL_CATMAP_MAPTYPE bitmap;
483 544
545 iter = _netlbl_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
546 if (iter == NULL)
547 return -ENOENT;
484 if (offset > iter->startbit) { 548 if (offset > iter->startbit) {
485 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 549 offset -= iter->startbit;
486 iter = iter->next; 550 idx = offset / NETLBL_CATMAP_MAPSIZE;
487 if (iter == NULL) 551 bit = offset % NETLBL_CATMAP_MAPSIZE;
488 return -ENOENT;
489 }
490 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
491 node_bit = offset - iter->startbit -
492 (NETLBL_CATMAP_MAPSIZE * node_idx);
493 } else { 552 } else {
494 node_idx = 0; 553 idx = 0;
495 node_bit = 0; 554 bit = 0;
496 } 555 }
497 bitmask = NETLBL_CATMAP_BIT << node_bit; 556 bitmask = NETLBL_CATMAP_BIT << bit;
498 557
499 for (;;) { 558 for (;;) {
500 bitmap = iter->bitmap[node_idx]; 559 bitmap = iter->bitmap[idx];
501 while (bitmask != 0 && (bitmap & bitmask) != 0) { 560 while (bitmask != 0 && (bitmap & bitmask) != 0) {
502 bitmask <<= 1; 561 bitmask <<= 1;
503 node_bit++; 562 bit++;
504 } 563 }
505 564
506 if (bitmask != 0) 565 if (prev && idx == 0 && bit == 0)
566 return prev->startbit + NETLBL_CATMAP_SIZE - 1;
567 else if (bitmask != 0)
507 return iter->startbit + 568 return iter->startbit +
508 (NETLBL_CATMAP_MAPSIZE * node_idx) + 569 (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1;
509 node_bit - 1; 570 else if (++idx >= NETLBL_CATMAP_MAPCNT) {
510 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
511 if (iter->next == NULL) 571 if (iter->next == NULL)
512 return iter->startbit + NETLBL_CATMAP_SIZE - 1; 572 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
573 prev = iter;
513 iter = iter->next; 574 iter = iter->next;
514 node_idx = 0; 575 idx = 0;
515 } 576 }
516 bitmask = NETLBL_CATMAP_BIT; 577 bitmask = NETLBL_CATMAP_BIT;
517 node_bit = 0; 578 bit = 0;
518 } 579 }
519 580
520 return -ENOENT; 581 return -ENOENT;
521} 582}
522 583
523/** 584/**
524 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap 585 * netlbl_catmap_getlong - Export an unsigned long bitmap
525 * @catmap: the category bitmap 586 * @catmap: pointer to the category bitmap
587 * @offset: pointer to the requested offset
588 * @bitmap: the exported bitmap
589 *
590 * Description:
591 * Export a bitmap with an offset greater than or equal to @offset and return
592 * it in @bitmap. The @offset must be aligned to an unsigned long and will be
593 * updated on return if different from what was requested; if the catmap is
594 * empty at the requested offset and beyond, the @offset is set to (u32)-1.
595 * Returns zero on sucess, negative values on failure.
596 *
597 */
598int netlbl_catmap_getlong(struct netlbl_lsm_catmap *catmap,
599 u32 *offset,
600 unsigned long *bitmap)
601{
602 struct netlbl_lsm_catmap *iter;
603 u32 off = *offset;
604 u32 idx;
605
606 /* only allow aligned offsets */
607 if ((off & (BITS_PER_LONG - 1)) != 0)
608 return -EINVAL;
609
610 if (off < catmap->startbit) {
611 off = catmap->startbit;
612 *offset = off;
613 }
614 iter = _netlbl_catmap_getnode(&catmap, off, _CM_F_NONE, 0);
615 if (iter == NULL) {
616 *offset = (u32)-1;
617 return 0;
618 }
619
620 if (off < iter->startbit) {
621 off = iter->startbit;
622 *offset = off;
623 } else
624 off -= iter->startbit;
625
626 idx = off / NETLBL_CATMAP_MAPSIZE;
627 *bitmap = iter->bitmap[idx] >> (off % NETLBL_CATMAP_SIZE);
628
629 return 0;
630}
631
632/**
633 * netlbl_catmap_setbit - Set a bit in a LSM secattr catmap
634 * @catmap: pointer to the category bitmap
526 * @bit: the bit to set 635 * @bit: the bit to set
527 * @flags: memory allocation flags 636 * @flags: memory allocation flags
528 * 637 *
@@ -531,36 +640,27 @@ int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
531 * negative values on failure. 640 * negative values on failure.
532 * 641 *
533 */ 642 */
534int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap, 643int netlbl_catmap_setbit(struct netlbl_lsm_catmap **catmap,
535 u32 bit, 644 u32 bit,
536 gfp_t flags) 645 gfp_t flags)
537{ 646{
538 struct netlbl_lsm_secattr_catmap *iter = catmap; 647 struct netlbl_lsm_catmap *iter;
539 u32 node_bit; 648 u32 idx;
540 u32 node_idx;
541 649
542 while (iter->next != NULL && 650 iter = _netlbl_catmap_getnode(catmap, bit, _CM_F_ALLOC, flags);
543 bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) 651 if (iter == NULL)
544 iter = iter->next; 652 return -ENOMEM;
545 if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
546 iter->next = netlbl_secattr_catmap_alloc(flags);
547 if (iter->next == NULL)
548 return -ENOMEM;
549 iter = iter->next;
550 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
551 }
552 653
553 /* gcc always rounds to zero when doing integer division */ 654 bit -= iter->startbit;
554 node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE; 655 idx = bit / NETLBL_CATMAP_MAPSIZE;
555 node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx); 656 iter->bitmap[idx] |= NETLBL_CATMAP_BIT << (bit % NETLBL_CATMAP_MAPSIZE);
556 iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
557 657
558 return 0; 658 return 0;
559} 659}
560 660
561/** 661/**
562 * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap 662 * netlbl_catmap_setrng - Set a range of bits in a LSM secattr catmap
563 * @catmap: the category bitmap 663 * @catmap: pointer to the category bitmap
564 * @start: the starting bit 664 * @start: the starting bit
565 * @end: the last bit in the string 665 * @end: the last bit in the string
566 * @flags: memory allocation flags 666 * @flags: memory allocation flags
@@ -570,36 +670,63 @@ int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
570 * on success, negative values on failure. 670 * on success, negative values on failure.
571 * 671 *
572 */ 672 */
573int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, 673int netlbl_catmap_setrng(struct netlbl_lsm_catmap **catmap,
574 u32 start, 674 u32 start,
575 u32 end, 675 u32 end,
576 gfp_t flags) 676 gfp_t flags)
577{ 677{
578 int ret_val = 0; 678 int rc = 0;
579 struct netlbl_lsm_secattr_catmap *iter = catmap; 679 u32 spot = start;
580 u32 iter_max_spot; 680
581 u32 spot; 681 while (rc == 0 && spot <= end) {
582 682 if (((spot & (BITS_PER_LONG - 1)) != 0) &&
583 /* XXX - This could probably be made a bit faster by combining writes 683 ((end - spot) > BITS_PER_LONG)) {
584 * to the catmap instead of setting a single bit each time, but for 684 rc = netlbl_catmap_setlong(catmap,
585 * right now skipping to the start of the range in the catmap should 685 spot,
586 * be a nice improvement over calling the individual setbit function 686 (unsigned long)-1,
587 * repeatedly from a loop. */ 687 flags);
588 688 spot += BITS_PER_LONG;
589 while (iter->next != NULL && 689 } else
590 start >= (iter->startbit + NETLBL_CATMAP_SIZE)) 690 rc = netlbl_catmap_setbit(catmap, spot++, flags);
591 iter = iter->next;
592 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
593
594 for (spot = start; spot <= end && ret_val == 0; spot++) {
595 if (spot >= iter_max_spot && iter->next != NULL) {
596 iter = iter->next;
597 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
598 }
599 ret_val = netlbl_secattr_catmap_setbit(iter, spot, flags);
600 } 691 }
601 692
602 return ret_val; 693 return rc;
694}
695
696/**
697 * netlbl_catmap_setlong - Import an unsigned long bitmap
698 * @catmap: pointer to the category bitmap
699 * @offset: offset to the start of the imported bitmap
700 * @bitmap: the bitmap to import
701 * @flags: memory allocation flags
702 *
703 * Description:
704 * Import the bitmap specified in @bitmap into @catmap, using the offset
705 * in @offset. The offset must be aligned to an unsigned long. Returns zero
706 * on success, negative values on failure.
707 *
708 */
709int netlbl_catmap_setlong(struct netlbl_lsm_catmap **catmap,
710 u32 offset,
711 unsigned long bitmap,
712 gfp_t flags)
713{
714 struct netlbl_lsm_catmap *iter;
715 u32 idx;
716
717 /* only allow aligned offsets */
718 if ((offset & (BITS_PER_LONG - 1)) != 0)
719 return -EINVAL;
720
721 iter = _netlbl_catmap_getnode(catmap, offset, _CM_F_ALLOC, flags);
722 if (iter == NULL)
723 return -ENOMEM;
724
725 offset -= iter->startbit;
726 idx = offset / NETLBL_CATMAP_MAPSIZE;
727 iter->bitmap[idx] |= bitmap << (offset % NETLBL_CATMAP_MAPSIZE);
728
729 return 0;
603} 730}
604 731
605/* 732/*