aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/netlabel/netlabel_kapi.c102
1 files changed, 54 insertions, 48 deletions
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index d9e10466b928..bc3883814890 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -407,6 +407,7 @@ out_entry:
407 407
408#define _CM_F_NONE 0x00000000 408#define _CM_F_NONE 0x00000000
409#define _CM_F_ALLOC 0x00000001 409#define _CM_F_ALLOC 0x00000001
410#define _CM_F_WALK 0x00000002
410 411
411/** 412/**
412 * _netlbl_secattr_catmap_getnode - Get a individual node from a catmap 413 * _netlbl_secattr_catmap_getnode - Get a individual node from a catmap
@@ -416,10 +417,11 @@ out_entry:
416 * @gfp_flags: memory allocation flags 417 * @gfp_flags: memory allocation flags
417 * 418 *
418 * Description: 419 * Description:
419 * Iterate through the catmap looking for the node associated with @offset; if 420 * Iterate through the catmap looking for the node associated with @offset.
420 * the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node, 421 * If the _CM_F_ALLOC flag is set in @cm_flags and there is no associated node,
421 * one will be created and inserted into the catmap. Returns a pointer to the 422 * one will be created and inserted into the catmap. If the _CM_F_WALK flag is
422 * node on success, NULL on failure. 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.
423 * 425 *
424 */ 426 */
425static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode( 427static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode(
@@ -431,17 +433,22 @@ static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode(
431 struct netlbl_lsm_secattr_catmap *iter = *catmap; 433 struct netlbl_lsm_secattr_catmap *iter = *catmap;
432 struct netlbl_lsm_secattr_catmap *prev = NULL; 434 struct netlbl_lsm_secattr_catmap *prev = NULL;
433 435
434 if (iter == NULL || offset < iter->startbit) 436 if (iter == NULL)
435 goto secattr_catmap_getnode_alloc; 437 goto secattr_catmap_getnode_alloc;
438 if (offset < iter->startbit)
439 goto secattr_catmap_getnode_walk;
436 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 440 while (iter && offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
437 prev = iter; 441 prev = iter;
438 iter = iter->next; 442 iter = iter->next;
439 } 443 }
440 if (iter == NULL || offset < iter->startbit) 444 if (iter == NULL || offset < iter->startbit)
441 goto secattr_catmap_getnode_alloc; 445 goto secattr_catmap_getnode_walk;
442 446
443 return iter; 447 return iter;
444 448
449secattr_catmap_getnode_walk:
450 if (cm_flags & _CM_F_WALK)
451 return iter;
445secattr_catmap_getnode_alloc: 452secattr_catmap_getnode_alloc:
446 if (!(cm_flags & _CM_F_ALLOC)) 453 if (!(cm_flags & _CM_F_ALLOC))
447 return NULL; 454 return NULL;
@@ -476,43 +483,41 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
476 u32 offset) 483 u32 offset)
477{ 484{
478 struct netlbl_lsm_secattr_catmap *iter = catmap; 485 struct netlbl_lsm_secattr_catmap *iter = catmap;
479 u32 node_idx; 486 u32 idx;
480 u32 node_bit; 487 u32 bit;
481 NETLBL_CATMAP_MAPTYPE bitmap; 488 NETLBL_CATMAP_MAPTYPE bitmap;
482 489
490 iter = _netlbl_secattr_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
491 if (iter == NULL)
492 return -ENOENT;
483 if (offset > iter->startbit) { 493 if (offset > iter->startbit) {
484 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 494 offset -= iter->startbit;
485 iter = iter->next; 495 idx = offset / NETLBL_CATMAP_MAPSIZE;
486 if (iter == NULL) 496 bit = offset % NETLBL_CATMAP_MAPSIZE;
487 return -ENOENT;
488 }
489 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
490 node_bit = offset - iter->startbit -
491 (NETLBL_CATMAP_MAPSIZE * node_idx);
492 } else { 497 } else {
493 node_idx = 0; 498 idx = 0;
494 node_bit = 0; 499 bit = 0;
495 } 500 }
496 bitmap = iter->bitmap[node_idx] >> node_bit; 501 bitmap = iter->bitmap[idx] >> bit;
497 502
498 for (;;) { 503 for (;;) {
499 if (bitmap != 0) { 504 if (bitmap != 0) {
500 while ((bitmap & NETLBL_CATMAP_BIT) == 0) { 505 while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
501 bitmap >>= 1; 506 bitmap >>= 1;
502 node_bit++; 507 bit++;
503 } 508 }
504 return iter->startbit + 509 return iter->startbit +
505 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit; 510 (NETLBL_CATMAP_MAPSIZE * idx) + bit;
506 } 511 }
507 if (++node_idx >= NETLBL_CATMAP_MAPCNT) { 512 if (++idx >= NETLBL_CATMAP_MAPCNT) {
508 if (iter->next != NULL) { 513 if (iter->next != NULL) {
509 iter = iter->next; 514 iter = iter->next;
510 node_idx = 0; 515 idx = 0;
511 } else 516 } else
512 return -ENOENT; 517 return -ENOENT;
513 } 518 }
514 bitmap = iter->bitmap[node_idx]; 519 bitmap = iter->bitmap[idx];
515 node_bit = 0; 520 bit = 0;
516 } 521 }
517 522
518 return -ENOENT; 523 return -ENOENT;
@@ -532,46 +537,47 @@ int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
532int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, 537int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
533 u32 offset) 538 u32 offset)
534{ 539{
535 struct netlbl_lsm_secattr_catmap *iter = catmap; 540 struct netlbl_lsm_secattr_catmap *iter;
536 u32 node_idx; 541 struct netlbl_lsm_secattr_catmap *prev = NULL;
537 u32 node_bit; 542 u32 idx;
543 u32 bit;
538 NETLBL_CATMAP_MAPTYPE bitmask; 544 NETLBL_CATMAP_MAPTYPE bitmask;
539 NETLBL_CATMAP_MAPTYPE bitmap; 545 NETLBL_CATMAP_MAPTYPE bitmap;
540 546
547 iter = _netlbl_secattr_catmap_getnode(&catmap, offset, _CM_F_WALK, 0);
548 if (iter == NULL)
549 return -ENOENT;
541 if (offset > iter->startbit) { 550 if (offset > iter->startbit) {
542 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) { 551 offset -= iter->startbit;
543 iter = iter->next; 552 idx = offset / NETLBL_CATMAP_MAPSIZE;
544 if (iter == NULL) 553 bit = offset % NETLBL_CATMAP_MAPSIZE;
545 return -ENOENT;
546 }
547 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
548 node_bit = offset - iter->startbit -
549 (NETLBL_CATMAP_MAPSIZE * node_idx);
550 } else { 554 } else {
551 node_idx = 0; 555 idx = 0;
552 node_bit = 0; 556 bit = 0;
553 } 557 }
554 bitmask = NETLBL_CATMAP_BIT << node_bit; 558 bitmask = NETLBL_CATMAP_BIT << bit;
555 559
556 for (;;) { 560 for (;;) {
557 bitmap = iter->bitmap[node_idx]; 561 bitmap = iter->bitmap[idx];
558 while (bitmask != 0 && (bitmap & bitmask) != 0) { 562 while (bitmask != 0 && (bitmap & bitmask) != 0) {
559 bitmask <<= 1; 563 bitmask <<= 1;
560 node_bit++; 564 bit++;
561 } 565 }
562 566
563 if (bitmask != 0) 567 if (prev && idx == 0 && bit == 0)
568 return prev->startbit + NETLBL_CATMAP_SIZE - 1;
569 else if (bitmask != 0)
564 return iter->startbit + 570 return iter->startbit +
565 (NETLBL_CATMAP_MAPSIZE * node_idx) + 571 (NETLBL_CATMAP_MAPSIZE * idx) + bit - 1;
566 node_bit - 1; 572 else if (++idx >= NETLBL_CATMAP_MAPCNT) {
567 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
568 if (iter->next == NULL) 573 if (iter->next == NULL)
569 return iter->startbit + NETLBL_CATMAP_SIZE - 1; 574 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
575 prev = iter;
570 iter = iter->next; 576 iter = iter->next;
571 node_idx = 0; 577 idx = 0;
572 } 578 }
573 bitmask = NETLBL_CATMAP_BIT; 579 bitmask = NETLBL_CATMAP_BIT;
574 node_bit = 0; 580 bit = 0;
575 } 581 }
576 582
577 return -ENOENT; 583 return -ENOENT;