diff options
| author | Paul Moore <paul.moore@hp.com> | 2006-11-17 17:38:46 -0500 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2006-12-03 00:24:07 -0500 |
| commit | 701a90bad99b8081a824cca52c178c8fc8f46bb2 (patch) | |
| tree | 5fed88e6707e9122d7f16e4c5d8fea7c69e090ac | |
| parent | c6fa82a9dd6160e0bc980cb0401c16bf62f2fe66 (diff) | |
NetLabel: make netlbl_lsm_secattr struct easier/quicker to understand
The existing netlbl_lsm_secattr struct required the LSM to check all of the
fields to determine if any security attributes were present resulting in a lot
of work in the common case of no attributes. This patch adds a 'flags' field
which is used to indicate which attributes are present in the structure; this
should allow the LSM to do a quick comparison to determine if the structure
holds any security attributes.
Example:
if (netlbl_lsm_secattr->flags)
/* security attributes present */
else
/* NO security attributes present */
Signed-off-by: Paul Moore <paul.moore@hp.com>
Signed-off-by: James Morris <jmorris@namei.org>
| -rw-r--r-- | include/net/netlabel.h | 13 | ||||
| -rw-r--r-- | net/ipv4/cipso_ipv4.c | 22 | ||||
| -rw-r--r-- | net/netlabel/netlabel_kapi.c | 5 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 24 |
4 files changed, 45 insertions, 19 deletions
diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 4e223aa25e5b..d605d7954013 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h | |||
| @@ -111,11 +111,17 @@ struct netlbl_lsm_cache { | |||
| 111 | void (*free) (const void *data); | 111 | void (*free) (const void *data); |
| 112 | void *data; | 112 | void *data; |
| 113 | }; | 113 | }; |
| 114 | #define NETLBL_SECATTR_NONE 0x00000000 | ||
| 115 | #define NETLBL_SECATTR_DOMAIN 0x00000001 | ||
| 116 | #define NETLBL_SECATTR_CACHE 0x00000002 | ||
| 117 | #define NETLBL_SECATTR_MLS_LVL 0x00000004 | ||
| 118 | #define NETLBL_SECATTR_MLS_CAT 0x00000008 | ||
| 114 | struct netlbl_lsm_secattr { | 119 | struct netlbl_lsm_secattr { |
| 120 | u32 flags; | ||
| 121 | |||
| 115 | char *domain; | 122 | char *domain; |
| 116 | 123 | ||
| 117 | u32 mls_lvl; | 124 | u32 mls_lvl; |
| 118 | u32 mls_lvl_vld; | ||
| 119 | unsigned char *mls_cat; | 125 | unsigned char *mls_cat; |
| 120 | size_t mls_cat_len; | 126 | size_t mls_cat_len; |
| 121 | 127 | ||
| @@ -174,7 +180,10 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache) | |||
| 174 | */ | 180 | */ |
| 175 | static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) | 181 | static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) |
| 176 | { | 182 | { |
| 177 | memset(secattr, 0, sizeof(*secattr)); | 183 | secattr->flags = 0; |
| 184 | secattr->domain = NULL; | ||
| 185 | secattr->mls_cat = NULL; | ||
| 186 | secattr->cache = NULL; | ||
| 178 | } | 187 | } |
| 179 | 188 | ||
| 180 | /** | 189 | /** |
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 095038ad72a4..f0a0785047fe 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -319,6 +319,7 @@ static int cipso_v4_cache_check(const unsigned char *key, | |||
| 319 | entry->activity += 1; | 319 | entry->activity += 1; |
| 320 | atomic_inc(&entry->lsm_data->refcount); | 320 | atomic_inc(&entry->lsm_data->refcount); |
| 321 | secattr->cache = entry->lsm_data; | 321 | secattr->cache = entry->lsm_data; |
| 322 | secattr->flags |= NETLBL_SECATTR_CACHE; | ||
| 322 | if (prev_entry == NULL) { | 323 | if (prev_entry == NULL) { |
| 323 | spin_unlock_bh(&cipso_v4_cache[bkt].lock); | 324 | spin_unlock_bh(&cipso_v4_cache[bkt].lock); |
| 324 | return 0; | 325 | return 0; |
| @@ -991,12 +992,15 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, | |||
| 991 | unsigned char **buffer, | 992 | unsigned char **buffer, |
| 992 | u32 *buffer_len) | 993 | u32 *buffer_len) |
| 993 | { | 994 | { |
| 994 | int ret_val = -EPERM; | 995 | int ret_val; |
| 995 | unsigned char *buf = NULL; | 996 | unsigned char *buf = NULL; |
| 996 | u32 buf_len; | 997 | u32 buf_len; |
| 997 | u32 level; | 998 | u32 level; |
| 998 | 999 | ||
| 999 | if (secattr->mls_cat) { | 1000 | if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0) |
| 1001 | return -EPERM; | ||
| 1002 | |||
| 1003 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { | ||
| 1000 | buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN, | 1004 | buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN, |
| 1001 | GFP_ATOMIC); | 1005 | GFP_ATOMIC); |
| 1002 | if (buf == NULL) | 1006 | if (buf == NULL) |
| @@ -1013,10 +1017,10 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, | |||
| 1013 | /* This will send packets using the "optimized" format when | 1017 | /* This will send packets using the "optimized" format when |
| 1014 | * possibile as specified in section 3.4.2.6 of the | 1018 | * possibile as specified in section 3.4.2.6 of the |
| 1015 | * CIPSO draft. */ | 1019 | * CIPSO draft. */ |
| 1016 | if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10)) | 1020 | if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10) |
| 1017 | ret_val = 10; | 1021 | buf_len = 14; |
| 1018 | 1022 | else | |
| 1019 | buf_len = 4 + ret_val; | 1023 | buf_len = 4 + ret_val; |
| 1020 | } else { | 1024 | } else { |
| 1021 | buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC); | 1025 | buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC); |
| 1022 | if (buf == NULL) | 1026 | if (buf == NULL) |
| @@ -1070,7 +1074,7 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, | |||
| 1070 | if (ret_val != 0) | 1074 | if (ret_val != 0) |
| 1071 | return ret_val; | 1075 | return ret_val; |
| 1072 | secattr->mls_lvl = level; | 1076 | secattr->mls_lvl = level; |
| 1073 | secattr->mls_lvl_vld = 1; | 1077 | secattr->flags |= NETLBL_SECATTR_MLS_LVL; |
| 1074 | 1078 | ||
| 1075 | if (tag_len > 4) { | 1079 | if (tag_len > 4) { |
| 1076 | switch (doi_def->type) { | 1080 | switch (doi_def->type) { |
| @@ -1094,8 +1098,10 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, | |||
| 1094 | if (ret_val < 0) { | 1098 | if (ret_val < 0) { |
| 1095 | kfree(secattr->mls_cat); | 1099 | kfree(secattr->mls_cat); |
| 1096 | return ret_val; | 1100 | return ret_val; |
| 1101 | } else if (ret_val > 0) { | ||
| 1102 | secattr->mls_cat_len = ret_val; | ||
| 1103 | secattr->flags |= NETLBL_SECATTR_MLS_CAT; | ||
| 1097 | } | 1104 | } |
| 1098 | secattr->mls_cat_len = ret_val; | ||
| 1099 | } | 1105 | } |
| 1100 | 1106 | ||
| 1101 | return 0; | 1107 | return 0; |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index ff971103fd0c..da2f1975a042 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
| @@ -62,6 +62,9 @@ int netlbl_socket_setattr(const struct socket *sock, | |||
| 62 | int ret_val = -ENOENT; | 62 | int ret_val = -ENOENT; |
| 63 | struct netlbl_dom_map *dom_entry; | 63 | struct netlbl_dom_map *dom_entry; |
| 64 | 64 | ||
| 65 | if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0) | ||
| 66 | return -ENOENT; | ||
| 67 | |||
| 65 | rcu_read_lock(); | 68 | rcu_read_lock(); |
| 66 | dom_entry = netlbl_domhsh_getentry(secattr->domain); | 69 | dom_entry = netlbl_domhsh_getentry(secattr->domain); |
| 67 | if (dom_entry == NULL) | 70 | if (dom_entry == NULL) |
| @@ -200,7 +203,7 @@ void netlbl_cache_invalidate(void) | |||
| 200 | int netlbl_cache_add(const struct sk_buff *skb, | 203 | int netlbl_cache_add(const struct sk_buff *skb, |
| 201 | const struct netlbl_lsm_secattr *secattr) | 204 | const struct netlbl_lsm_secattr *secattr) |
| 202 | { | 205 | { |
| 203 | if (secattr->cache == NULL) | 206 | if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0) |
| 204 | return -ENOMSG; | 207 | return -ENOMSG; |
| 205 | 208 | ||
| 206 | if (CIPSO_V4_OPTEXIST(skb)) | 209 | if (CIPSO_V4_OPTEXIST(skb)) |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 408820486af0..1f5bbb246d28 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -2254,8 +2254,6 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) | |||
| 2254 | cache = kzalloc(sizeof(*cache), GFP_ATOMIC); | 2254 | cache = kzalloc(sizeof(*cache), GFP_ATOMIC); |
| 2255 | if (cache == NULL) | 2255 | if (cache == NULL) |
| 2256 | goto netlbl_cache_add_return; | 2256 | goto netlbl_cache_add_return; |
| 2257 | secattr.cache->free = selinux_netlbl_cache_free; | ||
| 2258 | secattr.cache->data = (void *)cache; | ||
| 2259 | 2257 | ||
| 2260 | cache->type = NETLBL_CACHE_T_MLS; | 2258 | cache->type = NETLBL_CACHE_T_MLS; |
| 2261 | if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, | 2259 | if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, |
| @@ -2268,6 +2266,10 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) | |||
| 2268 | cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; | 2266 | cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; |
| 2269 | cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; | 2267 | cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; |
| 2270 | 2268 | ||
| 2269 | secattr.cache->free = selinux_netlbl_cache_free; | ||
| 2270 | secattr.cache->data = (void *)cache; | ||
| 2271 | secattr.flags = NETLBL_SECATTR_CACHE; | ||
| 2272 | |||
| 2271 | netlbl_cache_add(skb, &secattr); | 2273 | netlbl_cache_add(skb, &secattr); |
| 2272 | 2274 | ||
| 2273 | netlbl_cache_add_return: | 2275 | netlbl_cache_add_return: |
| @@ -2313,7 +2315,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, | |||
| 2313 | 2315 | ||
| 2314 | POLICY_RDLOCK; | 2316 | POLICY_RDLOCK; |
| 2315 | 2317 | ||
| 2316 | if (secattr->cache) { | 2318 | if (secattr->flags & NETLBL_SECATTR_CACHE) { |
| 2317 | cache = NETLBL_CACHE(secattr->cache->data); | 2319 | cache = NETLBL_CACHE(secattr->cache->data); |
| 2318 | switch (cache->type) { | 2320 | switch (cache->type) { |
| 2319 | case NETLBL_CACHE_T_SID: | 2321 | case NETLBL_CACHE_T_SID: |
| @@ -2346,7 +2348,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, | |||
| 2346 | default: | 2348 | default: |
| 2347 | goto netlbl_secattr_to_sid_return; | 2349 | goto netlbl_secattr_to_sid_return; |
| 2348 | } | 2350 | } |
| 2349 | } else if (secattr->mls_lvl_vld) { | 2351 | } else if (secattr->flags & NETLBL_SECATTR_MLS_LVL) { |
| 2350 | ctx = sidtab_search(&sidtab, base_sid); | 2352 | ctx = sidtab_search(&sidtab, base_sid); |
| 2351 | if (ctx == NULL) | 2353 | if (ctx == NULL) |
| 2352 | goto netlbl_secattr_to_sid_return; | 2354 | goto netlbl_secattr_to_sid_return; |
| @@ -2355,7 +2357,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, | |||
| 2355 | ctx_new.role = ctx->role; | 2357 | ctx_new.role = ctx->role; |
| 2356 | ctx_new.type = ctx->type; | 2358 | ctx_new.type = ctx->type; |
| 2357 | mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl); | 2359 | mls_import_lvl(&ctx_new, secattr->mls_lvl, secattr->mls_lvl); |
| 2358 | if (secattr->mls_cat) { | 2360 | if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { |
| 2359 | if (mls_import_cat(&ctx_new, | 2361 | if (mls_import_cat(&ctx_new, |
| 2360 | secattr->mls_cat, | 2362 | secattr->mls_cat, |
| 2361 | secattr->mls_cat_len, | 2363 | secattr->mls_cat_len, |
| @@ -2414,11 +2416,13 @@ static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | |||
| 2414 | 2416 | ||
| 2415 | netlbl_secattr_init(&secattr); | 2417 | netlbl_secattr_init(&secattr); |
| 2416 | rc = netlbl_skbuff_getattr(skb, &secattr); | 2418 | rc = netlbl_skbuff_getattr(skb, &secattr); |
| 2417 | if (rc == 0) | 2419 | if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) |
| 2418 | rc = selinux_netlbl_secattr_to_sid(skb, | 2420 | rc = selinux_netlbl_secattr_to_sid(skb, |
| 2419 | &secattr, | 2421 | &secattr, |
| 2420 | base_sid, | 2422 | base_sid, |
| 2421 | sid); | 2423 | sid); |
| 2424 | else | ||
| 2425 | *sid = SECSID_NULL; | ||
| 2422 | netlbl_secattr_destroy(&secattr); | 2426 | netlbl_secattr_destroy(&secattr); |
| 2423 | 2427 | ||
| 2424 | return rc; | 2428 | return rc; |
| @@ -2455,7 +2459,6 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) | |||
| 2455 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], | 2459 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], |
| 2456 | GFP_ATOMIC); | 2460 | GFP_ATOMIC); |
| 2457 | mls_export_lvl(ctx, &secattr.mls_lvl, NULL); | 2461 | mls_export_lvl(ctx, &secattr.mls_lvl, NULL); |
| 2458 | secattr.mls_lvl_vld = 1; | ||
| 2459 | rc = mls_export_cat(ctx, | 2462 | rc = mls_export_cat(ctx, |
| 2460 | &secattr.mls_cat, | 2463 | &secattr.mls_cat, |
| 2461 | &secattr.mls_cat_len, | 2464 | &secattr.mls_cat_len, |
| @@ -2464,6 +2467,10 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) | |||
| 2464 | if (rc != 0) | 2467 | if (rc != 0) |
| 2465 | goto netlbl_socket_setsid_return; | 2468 | goto netlbl_socket_setsid_return; |
| 2466 | 2469 | ||
| 2470 | secattr.flags |= NETLBL_SECATTR_DOMAIN | NETLBL_SECATTR_MLS_LVL; | ||
| 2471 | if (secattr.mls_cat) | ||
| 2472 | secattr.flags |= NETLBL_SECATTR_MLS_CAT; | ||
| 2473 | |||
| 2467 | rc = netlbl_socket_setattr(sock, &secattr); | 2474 | rc = netlbl_socket_setattr(sock, &secattr); |
| 2468 | if (rc == 0) | 2475 | if (rc == 0) |
| 2469 | sksec->nlbl_state = NLBL_LABELED; | 2476 | sksec->nlbl_state = NLBL_LABELED; |
| @@ -2564,6 +2571,7 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
| 2564 | 2571 | ||
| 2565 | netlbl_secattr_init(&secattr); | 2572 | netlbl_secattr_init(&secattr); |
| 2566 | if (netlbl_sock_getattr(sk, &secattr) == 0 && | 2573 | if (netlbl_sock_getattr(sk, &secattr) == 0 && |
| 2574 | secattr.flags != NETLBL_SECATTR_NONE && | ||
| 2567 | selinux_netlbl_secattr_to_sid(NULL, | 2575 | selinux_netlbl_secattr_to_sid(NULL, |
| 2568 | &secattr, | 2576 | &secattr, |
| 2569 | SECINITSID_UNLABELED, | 2577 | SECINITSID_UNLABELED, |
| @@ -2756,7 +2764,7 @@ int selinux_netlbl_socket_setsockopt(struct socket *sock, | |||
| 2756 | sksec->nlbl_state == NLBL_LABELED) { | 2764 | sksec->nlbl_state == NLBL_LABELED) { |
| 2757 | netlbl_secattr_init(&secattr); | 2765 | netlbl_secattr_init(&secattr); |
| 2758 | rc = netlbl_socket_getattr(sock, &secattr); | 2766 | rc = netlbl_socket_getattr(sock, &secattr); |
| 2759 | if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld)) | 2767 | if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) |
| 2760 | rc = -EACCES; | 2768 | rc = -EACCES; |
| 2761 | netlbl_secattr_destroy(&secattr); | 2769 | netlbl_secattr_destroy(&secattr); |
| 2762 | } | 2770 | } |
