Commit 701a90bad99b8081a824cca52c178c8fc8f46bb2

Authored by Paul Moore
Committed by David S. Miller
1 parent c6fa82a9dd

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 }