aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c124
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
2557struct 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 */
2574static 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 */
2601static void security_netlbl_cache_add(struct netlbl_lsm_secattr *secattr, 2561static 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 */
2648int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 2596int 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 {