aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/netlabel.h13
-rw-r--r--net/ipv4/cipso_ipv4.c22
-rw-r--r--net/netlabel/netlabel_kapi.c5
-rw-r--r--security/selinux/ss/services.c24
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
114struct netlbl_lsm_secattr { 119struct 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 */
175static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) 181static 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)
200int netlbl_cache_add(const struct sk_buff *skb, 203int 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
2273netlbl_cache_add_return: 2275netlbl_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 }