diff options
| -rw-r--r-- | security/selinux/hooks.c | 6 | ||||
| -rw-r--r-- | security/selinux/include/netlabel.h | 2 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 2 | ||||
| -rw-r--r-- | security/selinux/netlabel.c | 55 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 124 |
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 | ||
| 49 | int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | 49 | int 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 | ||
| 90 | static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | 89 | static 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 |
| 126 | int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, | 126 | int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, |
| 127 | u32 base_sid, | ||
| 128 | u32 *sid); | 127 | u32 *sid); |
| 129 | 128 | ||
| 130 | int security_netlbl_sid_to_secattr(u32 sid, | 129 | int security_netlbl_sid_to_secattr(u32 sid, |
| @@ -132,7 +131,6 @@ int security_netlbl_sid_to_secattr(u32 sid, | |||
| 132 | #else | 131 | #else |
| 133 | static inline int security_netlbl_secattr_to_sid( | 132 | static 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 | */ | ||
| 50 | static 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 | */ |
| 157 | int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | 183 | int 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 | ||
| 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 { |
