aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-01-29 08:44:18 -0500
committerJames Morris <jmorris@namei.org>2008-01-29 16:17:27 -0500
commit5dbe1eb0cfc144a2b0cb1466e22bcb6fc34229a8 (patch)
treee1e028acaf0dd08cbcacd2c125f60230f820b442 /security/selinux
parentd621d35e576aa20a0ddae8022c3810f38357c8ff (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')
-rw-r--r--security/selinux/hooks.c6
-rw-r--r--security/selinux/include/netlabel.h2
-rw-r--r--security/selinux/include/security.h2
-rw-r--r--security/selinux/netlabel.c55
-rw-r--r--security/selinux/ss/services.c124
5 files changed, 55 insertions, 134 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6156241c8770..c90e865a8603 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3468,11 +3468,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
3468 u32 nlbl_type; 3468 u32 nlbl_type;
3469 3469
3470 selinux_skb_xfrm_sid(skb, &xfrm_sid); 3470 selinux_skb_xfrm_sid(skb, &xfrm_sid);
3471 selinux_netlbl_skbuff_getsid(skb, 3471 selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
3472 family,
3473 SECINITSID_NETMSG,
3474 &nlbl_type,
3475 &nlbl_sid);
3476 3472
3477 if (security_net_peersid_resolve(nlbl_sid, nlbl_type, 3473 if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
3478 xfrm_sid, 3474 xfrm_sid,
diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h
index c8c05a6f298c..00a2809c8506 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -48,7 +48,6 @@ void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
48 48
49int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, 49int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
50 u16 family, 50 u16 family,
51 u32 base_sid,
52 u32 *type, 51 u32 *type,
53 u32 *sid); 52 u32 *sid);
54 53
@@ -89,7 +88,6 @@ static inline void selinux_netlbl_sk_security_clone(
89 88
90static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, 89static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
91 u16 family, 90 u16 family,
92 u32 base_sid,
93 u32 *type, 91 u32 *type,
94 u32 *sid) 92 u32 *sid)
95{ 93{
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h
index 9347e2daa8d4..23137c17f917 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -124,7 +124,6 @@ int security_genfs_sid(const char *fstype, char *name, u16 sclass,
124 124
125#ifdef CONFIG_NETLABEL 125#ifdef CONFIG_NETLABEL
126int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, 126int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
127 u32 base_sid,
128 u32 *sid); 127 u32 *sid);
129 128
130int security_netlbl_sid_to_secattr(u32 sid, 129int security_netlbl_sid_to_secattr(u32 sid,
@@ -132,7 +131,6 @@ int security_netlbl_sid_to_secattr(u32 sid,
132#else 131#else
133static inline int security_netlbl_secattr_to_sid( 132static inline int security_netlbl_secattr_to_sid(
134 struct netlbl_lsm_secattr *secattr, 133 struct netlbl_lsm_secattr *secattr,
135 u32 base_sid,
136 u32 *sid) 134 u32 *sid)
137{ 135{
138 return -EIDRM; 136 return -EIDRM;
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index b54d28fd3b5d..0fa2be4149e8 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -36,6 +36,33 @@
36#include "security.h" 36#include "security.h"
37 37
38/** 38/**
39 * selinux_netlbl_sidlookup_cached - Cache a SID lookup
40 * @skb: the packet
41 * @secattr: the NetLabel security attributes
42 * @sid: the SID
43 *
44 * Description:
45 * Query the SELinux security server to lookup the correct SID for the given
46 * security attributes. If the query is successful, cache the result to speed
47 * up future lookups. Returns zero on success, negative values on failure.
48 *
49 */
50static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
51 struct netlbl_lsm_secattr *secattr,
52 u32 *sid)
53{
54 int rc;
55
56 rc = security_netlbl_secattr_to_sid(secattr, sid);
57 if (rc == 0 &&
58 (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
59 (secattr->flags & NETLBL_SECATTR_CACHE))
60 netlbl_cache_add(skb, secattr);
61
62 return rc;
63}
64
65/**
39 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism 66 * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
40 * @sk: the socket to label 67 * @sk: the socket to label
41 * @sid: the SID to use 68 * @sid: the SID to use
@@ -144,7 +171,6 @@ void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
144 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel 171 * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
145 * @skb: the packet 172 * @skb: the packet
146 * @family: protocol family 173 * @family: protocol family
147 * @base_sid: the SELinux SID to use as a context for MLS only attributes
148 * @type: NetLabel labeling protocol type 174 * @type: NetLabel labeling protocol type
149 * @sid: the SID 175 * @sid: the SID
150 * 176 *
@@ -156,7 +182,6 @@ void selinux_netlbl_sk_security_clone(struct sk_security_struct *ssec,
156 */ 182 */
157int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, 183int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
158 u16 family, 184 u16 family,
159 u32 base_sid,
160 u32 *type, 185 u32 *type,
161 u32 *sid) 186 u32 *sid)
162{ 187{
@@ -170,13 +195,9 @@ int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
170 195
171 netlbl_secattr_init(&secattr); 196 netlbl_secattr_init(&secattr);
172 rc = netlbl_skbuff_getattr(skb, family, &secattr); 197 rc = netlbl_skbuff_getattr(skb, family, &secattr);
173 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) { 198 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
174 rc = security_netlbl_secattr_to_sid(&secattr, base_sid, sid); 199 rc = selinux_netlbl_sidlookup_cached(skb, &secattr, sid);
175 if (rc == 0 && 200 else
176 (secattr.flags & NETLBL_SECATTR_CACHEABLE) &&
177 (secattr.flags & NETLBL_SECATTR_CACHE))
178 netlbl_cache_add(skb, &secattr);
179 } else
180 *sid = SECSID_NULL; 201 *sid = SECSID_NULL;
181 *type = secattr.type; 202 *type = secattr.type;
182 netlbl_secattr_destroy(&secattr); 203 netlbl_secattr_destroy(&secattr);
@@ -210,9 +231,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock)
210 netlbl_secattr_init(&secattr); 231 netlbl_secattr_init(&secattr);
211 if (netlbl_sock_getattr(sk, &secattr) == 0 && 232 if (netlbl_sock_getattr(sk, &secattr) == 0 &&
212 secattr.flags != NETLBL_SECATTR_NONE && 233 secattr.flags != NETLBL_SECATTR_NONE &&
213 security_netlbl_secattr_to_sid(&secattr, 234 security_netlbl_secattr_to_sid(&secattr, &nlbl_peer_sid) == 0)
214 SECINITSID_NETMSG,
215 &nlbl_peer_sid) == 0)
216 sksec->peer_sid = nlbl_peer_sid; 235 sksec->peer_sid = nlbl_peer_sid;
217 netlbl_secattr_destroy(&secattr); 236 netlbl_secattr_destroy(&secattr);
218 237
@@ -316,15 +335,9 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec,
316 335
317 netlbl_secattr_init(&secattr); 336 netlbl_secattr_init(&secattr);
318 rc = netlbl_skbuff_getattr(skb, family, &secattr); 337 rc = netlbl_skbuff_getattr(skb, family, &secattr);
319 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) { 338 if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE)
320 rc = security_netlbl_secattr_to_sid(&secattr, 339 rc = selinux_netlbl_sidlookup_cached(skb, &secattr, &nlbl_sid);
321 SECINITSID_NETMSG, 340 else
322 &nlbl_sid);
323 if (rc == 0 &&
324 (secattr.flags & NETLBL_SECATTR_CACHEABLE) &&
325 (secattr.flags & NETLBL_SECATTR_CACHE))
326 netlbl_cache_add(skb, &secattr);
327 } else
328 nlbl_sid = SECINITSID_UNLABELED; 341 nlbl_sid = SECINITSID_UNLABELED;
329 netlbl_secattr_destroy(&secattr); 342 netlbl_secattr_destroy(&secattr);
330 if (rc != 0) 343 if (rc != 0)
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 {