diff options
-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 | } |