Commit 701a90bad99b8081a824cca52c178c8fc8f46bb2
Committed by
David S. Miller
1 parent
c6fa82a9dd
Exists in
master
and in
20 other branches
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>
Showing 4 changed files with 45 additions and 19 deletions Side-by-side Diff
include/net/netlabel.h
... | ... | @@ -111,11 +111,17 @@ |
111 | 111 | void (*free) (const void *data); |
112 | 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 | 119 | struct netlbl_lsm_secattr { |
120 | + u32 flags; | |
121 | + | |
115 | 122 | char *domain; |
116 | 123 | |
117 | 124 | u32 mls_lvl; |
118 | - u32 mls_lvl_vld; | |
119 | 125 | unsigned char *mls_cat; |
120 | 126 | size_t mls_cat_len; |
121 | 127 | |
... | ... | @@ -174,7 +180,10 @@ |
174 | 180 | */ |
175 | 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 | /** |
net/ipv4/cipso_ipv4.c
... | ... | @@ -319,6 +319,7 @@ |
319 | 319 | entry->activity += 1; |
320 | 320 | atomic_inc(&entry->lsm_data->refcount); |
321 | 321 | secattr->cache = entry->lsm_data; |
322 | + secattr->flags |= NETLBL_SECATTR_CACHE; | |
322 | 323 | if (prev_entry == NULL) { |
323 | 324 | spin_unlock_bh(&cipso_v4_cache[bkt].lock); |
324 | 325 | return 0; |
325 | 326 | |
... | ... | @@ -991,12 +992,15 @@ |
991 | 992 | unsigned char **buffer, |
992 | 993 | u32 *buffer_len) |
993 | 994 | { |
994 | - int ret_val = -EPERM; | |
995 | + int ret_val; | |
995 | 996 | unsigned char *buf = NULL; |
996 | 997 | u32 buf_len; |
997 | 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 | 1004 | buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN, |
1001 | 1005 | GFP_ATOMIC); |
1002 | 1006 | if (buf == NULL) |
... | ... | @@ -1013,10 +1017,10 @@ |
1013 | 1017 | /* This will send packets using the "optimized" format when |
1014 | 1018 | * possibile as specified in section 3.4.2.6 of the |
1015 | 1019 | * CIPSO draft. */ |
1016 | - if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10)) | |
1017 | - ret_val = 10; | |
1018 | - | |
1019 | - buf_len = 4 + ret_val; | |
1020 | + if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10) | |
1021 | + buf_len = 14; | |
1022 | + else | |
1023 | + buf_len = 4 + ret_val; | |
1020 | 1024 | } else { |
1021 | 1025 | buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC); |
1022 | 1026 | if (buf == NULL) |
... | ... | @@ -1070,7 +1074,7 @@ |
1070 | 1074 | if (ret_val != 0) |
1071 | 1075 | return ret_val; |
1072 | 1076 | secattr->mls_lvl = level; |
1073 | - secattr->mls_lvl_vld = 1; | |
1077 | + secattr->flags |= NETLBL_SECATTR_MLS_LVL; | |
1074 | 1078 | |
1075 | 1079 | if (tag_len > 4) { |
1076 | 1080 | switch (doi_def->type) { |
1077 | 1081 | |
... | ... | @@ -1094,8 +1098,10 @@ |
1094 | 1098 | if (ret_val < 0) { |
1095 | 1099 | kfree(secattr->mls_cat); |
1096 | 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 | 1107 | return 0; |
net/netlabel/netlabel_kapi.c
... | ... | @@ -62,6 +62,9 @@ |
62 | 62 | int ret_val = -ENOENT; |
63 | 63 | struct netlbl_dom_map *dom_entry; |
64 | 64 | |
65 | + if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0) | |
66 | + return -ENOENT; | |
67 | + | |
65 | 68 | rcu_read_lock(); |
66 | 69 | dom_entry = netlbl_domhsh_getentry(secattr->domain); |
67 | 70 | if (dom_entry == NULL) |
... | ... | @@ -200,7 +203,7 @@ |
200 | 203 | int netlbl_cache_add(const struct sk_buff *skb, |
201 | 204 | const struct netlbl_lsm_secattr *secattr) |
202 | 205 | { |
203 | - if (secattr->cache == NULL) | |
206 | + if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0) | |
204 | 207 | return -ENOMSG; |
205 | 208 | |
206 | 209 | if (CIPSO_V4_OPTEXIST(skb)) |
security/selinux/ss/services.c
... | ... | @@ -2254,8 +2254,6 @@ |
2254 | 2254 | cache = kzalloc(sizeof(*cache), GFP_ATOMIC); |
2255 | 2255 | if (cache == NULL) |
2256 | 2256 | goto netlbl_cache_add_return; |
2257 | - secattr.cache->free = selinux_netlbl_cache_free; | |
2258 | - secattr.cache->data = (void *)cache; | |
2259 | 2257 | |
2260 | 2258 | cache->type = NETLBL_CACHE_T_MLS; |
2261 | 2259 | if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, |
... | ... | @@ -2268,6 +2266,10 @@ |
2268 | 2266 | cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; |
2269 | 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 | 2273 | netlbl_cache_add(skb, &secattr); |
2272 | 2274 | |
2273 | 2275 | netlbl_cache_add_return: |
... | ... | @@ -2313,7 +2315,7 @@ |
2313 | 2315 | |
2314 | 2316 | POLICY_RDLOCK; |
2315 | 2317 | |
2316 | - if (secattr->cache) { | |
2318 | + if (secattr->flags & NETLBL_SECATTR_CACHE) { | |
2317 | 2319 | cache = NETLBL_CACHE(secattr->cache->data); |
2318 | 2320 | switch (cache->type) { |
2319 | 2321 | case NETLBL_CACHE_T_SID: |
... | ... | @@ -2346,7 +2348,7 @@ |
2346 | 2348 | default: |
2347 | 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 | 2352 | ctx = sidtab_search(&sidtab, base_sid); |
2351 | 2353 | if (ctx == NULL) |
2352 | 2354 | goto netlbl_secattr_to_sid_return; |
... | ... | @@ -2355,7 +2357,7 @@ |
2355 | 2357 | ctx_new.role = ctx->role; |
2356 | 2358 | ctx_new.type = ctx->type; |
2357 | 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 | 2361 | if (mls_import_cat(&ctx_new, |
2360 | 2362 | secattr->mls_cat, |
2361 | 2363 | secattr->mls_cat_len, |
2362 | 2364 | |
... | ... | @@ -2414,11 +2416,13 @@ |
2414 | 2416 | |
2415 | 2417 | netlbl_secattr_init(&secattr); |
2416 | 2418 | rc = netlbl_skbuff_getattr(skb, &secattr); |
2417 | - if (rc == 0) | |
2419 | + if (rc == 0 && secattr.flags != NETLBL_SECATTR_NONE) | |
2418 | 2420 | rc = selinux_netlbl_secattr_to_sid(skb, |
2419 | 2421 | &secattr, |
2420 | 2422 | base_sid, |
2421 | 2423 | sid); |
2424 | + else | |
2425 | + *sid = SECSID_NULL; | |
2422 | 2426 | netlbl_secattr_destroy(&secattr); |
2423 | 2427 | |
2424 | 2428 | return rc; |
... | ... | @@ -2455,7 +2459,6 @@ |
2455 | 2459 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], |
2456 | 2460 | GFP_ATOMIC); |
2457 | 2461 | mls_export_lvl(ctx, &secattr.mls_lvl, NULL); |
2458 | - secattr.mls_lvl_vld = 1; | |
2459 | 2462 | rc = mls_export_cat(ctx, |
2460 | 2463 | &secattr.mls_cat, |
2461 | 2464 | &secattr.mls_cat_len, |
... | ... | @@ -2464,6 +2467,10 @@ |
2464 | 2467 | if (rc != 0) |
2465 | 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 | 2474 | rc = netlbl_socket_setattr(sock, &secattr); |
2468 | 2475 | if (rc == 0) |
2469 | 2476 | sksec->nlbl_state = NLBL_LABELED; |
... | ... | @@ -2564,6 +2571,7 @@ |
2564 | 2571 | |
2565 | 2572 | netlbl_secattr_init(&secattr); |
2566 | 2573 | if (netlbl_sock_getattr(sk, &secattr) == 0 && |
2574 | + secattr.flags != NETLBL_SECATTR_NONE && | |
2567 | 2575 | selinux_netlbl_secattr_to_sid(NULL, |
2568 | 2576 | &secattr, |
2569 | 2577 | SECINITSID_UNLABELED, |
... | ... | @@ -2756,7 +2764,7 @@ |
2756 | 2764 | sksec->nlbl_state == NLBL_LABELED) { |
2757 | 2765 | netlbl_secattr_init(&secattr); |
2758 | 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 | 2768 | rc = -EACCES; |
2761 | 2769 | netlbl_secattr_destroy(&secattr); |
2762 | 2770 | } |