diff options
author | Paul Moore <paul.moore@hp.com> | 2008-01-29 08:44:18 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-01-29 16:17:27 -0500 |
commit | 5dbe1eb0cfc144a2b0cb1466e22bcb6fc34229a8 (patch) | |
tree | e1e028acaf0dd08cbcacd2c125f60230f820b442 /security/selinux/ss | |
parent | d621d35e576aa20a0ddae8022c3810f38357c8ff (diff) |
SELinux: Allow NetLabel to directly cache SIDs
Now that the SELinux NetLabel "base SID" is always the netmsg initial SID we
can do a big optimization - caching the SID and not just the MLS attributes.
This not only saves a lot of per-packet memory allocations and copies but it
has a nice side effect of removing a chunk of code.
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss')
-rw-r--r-- | security/selinux/ss/services.c | 124 |
1 files changed, 20 insertions, 104 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 7f0ee1b91e1d..f96dec1f9258 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2547,50 +2547,10 @@ void selinux_audit_set_callback(int (*callback)(void)) | |||
2547 | } | 2547 | } |
2548 | 2548 | ||
2549 | #ifdef CONFIG_NETLABEL | 2549 | #ifdef CONFIG_NETLABEL |
2550 | /* | ||
2551 | * NetLabel cache structure | ||
2552 | */ | ||
2553 | #define NETLBL_CACHE(x) ((struct selinux_netlbl_cache *)(x)) | ||
2554 | #define NETLBL_CACHE_T_NONE 0 | ||
2555 | #define NETLBL_CACHE_T_SID 1 | ||
2556 | #define NETLBL_CACHE_T_MLS 2 | ||
2557 | struct selinux_netlbl_cache { | ||
2558 | u32 type; | ||
2559 | union { | ||
2560 | u32 sid; | ||
2561 | struct mls_range mls_label; | ||
2562 | } data; | ||
2563 | }; | ||
2564 | |||
2565 | /** | ||
2566 | * security_netlbl_cache_free - Free the NetLabel cached data | ||
2567 | * @data: the data to free | ||
2568 | * | ||
2569 | * Description: | ||
2570 | * This function is intended to be used as the free() callback inside the | ||
2571 | * netlbl_lsm_cache structure. | ||
2572 | * | ||
2573 | */ | ||
2574 | static void security_netlbl_cache_free(const void *data) | ||
2575 | { | ||
2576 | struct selinux_netlbl_cache *cache; | ||
2577 | |||
2578 | if (data == NULL) | ||
2579 | return; | ||
2580 | |||
2581 | cache = NETLBL_CACHE(data); | ||
2582 | switch (cache->type) { | ||
2583 | case NETLBL_CACHE_T_MLS: | ||
2584 | ebitmap_destroy(&cache->data.mls_label.level[0].cat); | ||
2585 | break; | ||
2586 | } | ||
2587 | kfree(data); | ||
2588 | } | ||
2589 | |||
2590 | /** | 2550 | /** |
2591 | * security_netlbl_cache_add - Add an entry to the NetLabel cache | 2551 | * security_netlbl_cache_add - Add an entry to the NetLabel cache |
2592 | * @secattr: the NetLabel packet security attributes | 2552 | * @secattr: the NetLabel packet security attributes |
2593 | * @ctx: the SELinux context | 2553 | * @sid: the SELinux SID |
2594 | * | 2554 | * |
2595 | * Description: | 2555 | * Description: |
2596 | * Attempt to cache the context in @ctx, which was derived from the packet in | 2556 | * Attempt to cache the context in @ctx, which was derived from the packet in |
@@ -2599,60 +2559,46 @@ static void security_netlbl_cache_free(const void *data) | |||
2599 | * | 2559 | * |
2600 | */ | 2560 | */ |
2601 | static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, | 2561 | static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, |
2602 | struct context *ctx) | 2562 | u32 sid) |
2603 | { | 2563 | { |
2604 | struct selinux_netlbl_cache *cache = NULL; | 2564 | u32 *sid_cache; |
2605 | 2565 | ||
2606 | secattr->cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); | 2566 | sid_cache = kmalloc(sizeof(*sid_cache), GFP_ATOMIC); |
2607 | if (secattr->cache == NULL) | 2567 | if (sid_cache == NULL) |
2608 | return; | ||
2609 | |||
2610 | cache = kzalloc(sizeof(*cache), GFP_ATOMIC); | ||
2611 | if (cache == NULL) | ||
2612 | return; | 2568 | return; |
2613 | 2569 | secattr->cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); | |
2614 | cache->type = NETLBL_CACHE_T_MLS; | 2570 | if (secattr->cache == NULL) { |
2615 | if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, | 2571 | kfree(sid_cache); |
2616 | &ctx->range.level[0].cat) != 0) { | ||
2617 | kfree(cache); | ||
2618 | return; | 2572 | return; |
2619 | } | 2573 | } |
2620 | cache->data.mls_label.level[1].cat.highbit = | ||
2621 | cache->data.mls_label.level[0].cat.highbit; | ||
2622 | cache->data.mls_label.level[1].cat.node = | ||
2623 | cache->data.mls_label.level[0].cat.node; | ||
2624 | cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; | ||
2625 | cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; | ||
2626 | 2574 | ||
2627 | secattr->cache->free = security_netlbl_cache_free; | 2575 | *sid_cache = sid; |
2628 | secattr->cache->data = (void *)cache; | 2576 | secattr->cache->free = kfree; |
2577 | secattr->cache->data = sid_cache; | ||
2629 | secattr->flags |= NETLBL_SECATTR_CACHE; | 2578 | secattr->flags |= NETLBL_SECATTR_CACHE; |
2630 | } | 2579 | } |
2631 | 2580 | ||
2632 | /** | 2581 | /** |
2633 | * security_netlbl_secattr_to_sid - Convert a NetLabel secattr to a SELinux SID | 2582 | * security_netlbl_secattr_to_sid - Convert a NetLabel secattr to a SELinux SID |
2634 | * @secattr: the NetLabel packet security attributes | 2583 | * @secattr: the NetLabel packet security attributes |
2635 | * @base_sid: the SELinux SID to use as a context for MLS only attributes | ||
2636 | * @sid: the SELinux SID | 2584 | * @sid: the SELinux SID |
2637 | * | 2585 | * |
2638 | * Description: | 2586 | * Description: |
2639 | * Convert the given NetLabel security attributes in @secattr into a | 2587 | * Convert the given NetLabel security attributes in @secattr into a |
2640 | * SELinux SID. If the @secattr field does not contain a full SELinux | 2588 | * SELinux SID. If the @secattr field does not contain a full SELinux |
2641 | * SID/context then use the context in @base_sid as the foundation. If | 2589 | * SID/context then use SECINITSID_NETMSG as the foundation. If possibile the |
2642 | * possibile the 'cache' field of @secattr is set and the CACHE flag is set; | 2590 | * 'cache' field of @secattr is set and the CACHE flag is set; this is to |
2643 | * this is to allow the @secattr to be used by NetLabel to cache the secattr to | 2591 | * allow the @secattr to be used by NetLabel to cache the secattr to SID |
2644 | * SID conversion for future lookups. Returns zero on success, negative | 2592 | * conversion for future lookups. Returns zero on success, negative values on |
2645 | * values on failure. | 2593 | * failure. |
2646 | * | 2594 | * |
2647 | */ | 2595 | */ |
2648 | int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | 2596 | int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, |
2649 | u32 base_sid, | ||
2650 | u32 *sid) | 2597 | u32 *sid) |
2651 | { | 2598 | { |
2652 | int rc = -EIDRM; | 2599 | int rc = -EIDRM; |
2653 | struct context *ctx; | 2600 | struct context *ctx; |
2654 | struct context ctx_new; | 2601 | struct context ctx_new; |
2655 | struct selinux_netlbl_cache *cache; | ||
2656 | 2602 | ||
2657 | if (!ss_initialized) { | 2603 | if (!ss_initialized) { |
2658 | *sid = SECSID_NULL; | 2604 | *sid = SECSID_NULL; |
@@ -2662,43 +2608,13 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | |||
2662 | POLICY_RDLOCK; | 2608 | POLICY_RDLOCK; |
2663 | 2609 | ||
2664 | if (secattr->flags & NETLBL_SECATTR_CACHE) { | 2610 | if (secattr->flags & NETLBL_SECATTR_CACHE) { |
2665 | cache = NETLBL_CACHE(secattr->cache->data); | 2611 | *sid = *(u32 *)secattr->cache->data; |
2666 | switch (cache->type) { | 2612 | rc = 0; |
2667 | case NETLBL_CACHE_T_SID: | ||
2668 | *sid = cache->data.sid; | ||
2669 | rc = 0; | ||
2670 | break; | ||
2671 | case NETLBL_CACHE_T_MLS: | ||
2672 | ctx = sidtab_search(&sidtab, base_sid); | ||
2673 | if (ctx == NULL) | ||
2674 | goto netlbl_secattr_to_sid_return; | ||
2675 | |||
2676 | ctx_new.user = ctx->user; | ||
2677 | ctx_new.role = ctx->role; | ||
2678 | ctx_new.type = ctx->type; | ||
2679 | ctx_new.range.level[0].sens = | ||
2680 | cache->data.mls_label.level[0].sens; | ||
2681 | ctx_new.range.level[0].cat.highbit = | ||
2682 | cache->data.mls_label.level[0].cat.highbit; | ||
2683 | ctx_new.range.level[0].cat.node = | ||
2684 | cache->data.mls_label.level[0].cat.node; | ||
2685 | ctx_new.range.level[1].sens = | ||
2686 | cache->data.mls_label.level[1].sens; | ||
2687 | ctx_new.range.level[1].cat.highbit = | ||
2688 | cache->data.mls_label.level[1].cat.highbit; | ||
2689 | ctx_new.range.level[1].cat.node = | ||
2690 | cache->data.mls_label.level[1].cat.node; | ||
2691 | |||
2692 | rc = sidtab_context_to_sid(&sidtab, &ctx_new, sid); | ||
2693 | break; | ||
2694 | default: | ||
2695 | goto netlbl_secattr_to_sid_return; | ||
2696 | } | ||
2697 | } else if (secattr->flags & NETLBL_SECATTR_SECID) { | 2613 | } else if (secattr->flags & NETLBL_SECATTR_SECID) { |
2698 | *sid = secattr->attr.secid; | 2614 | *sid = secattr->attr.secid; |
2699 | rc = 0; | 2615 | rc = 0; |
2700 | } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { | 2616 | } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { |
2701 | ctx = sidtab_search(&sidtab, base_sid); | 2617 | ctx = sidtab_search(&sidtab, SECINITSID_NETMSG); |
2702 | if (ctx == NULL) | 2618 | if (ctx == NULL) |
2703 | goto netlbl_secattr_to_sid_return; | 2619 | goto netlbl_secattr_to_sid_return; |
2704 | 2620 | ||
@@ -2725,7 +2641,7 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | |||
2725 | if (rc != 0) | 2641 | if (rc != 0) |
2726 | goto netlbl_secattr_to_sid_return_cleanup; | 2642 | goto netlbl_secattr_to_sid_return_cleanup; |
2727 | 2643 | ||
2728 | security_netlbl_cache_add(secattr, &ctx_new); | 2644 | security_netlbl_cache_add(secattr, *sid); |
2729 | 2645 | ||
2730 | ebitmap_destroy(&ctx_new.range.level[0].cat); | 2646 | ebitmap_destroy(&ctx_new.range.level[0].cat); |
2731 | } else { | 2647 | } else { |