diff options
-rw-r--r-- | net/netlabel/netlabel_kapi.c | 102 |
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 | */ |
425 | static struct netlbl_lsm_secattr_catmap *_netlbl_secattr_catmap_getnode( | 427 | static 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 | ||
449 | secattr_catmap_getnode_walk: | ||
450 | if (cm_flags & _CM_F_WALK) | ||
451 | return iter; | ||
445 | secattr_catmap_getnode_alloc: | 452 | secattr_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, | |||
532 | int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, | 537 | int 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; |