diff options
author | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2006-11-22 13:06:44 -0500 |
commit | 0bd2af46839ad6262d25714a6ec0365db9d6b98f (patch) | |
tree | dcced72d230d69fd0c5816ac6dd03ab84799a93e /security | |
parent | e138a5d2356729b8752e88520cc1525fae9794ac (diff) | |
parent | f26b90440cd74c78fe10c9bd5160809704a9627c (diff) |
Merge ../scsi-rc-fixes-2.6
Diffstat (limited to 'security')
-rw-r--r-- | security/dummy.c | 3 | ||||
-rw-r--r-- | security/selinux/hooks.c | 8 | ||||
-rw-r--r-- | security/selinux/include/selinux_netlabel.h | 10 | ||||
-rw-r--r-- | security/selinux/include/xfrm.h | 3 | ||||
-rw-r--r-- | security/selinux/ss/ebitmap.c | 8 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 17 | ||||
-rw-r--r-- | security/selinux/ss/policydb.c | 2 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 119 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 53 |
9 files changed, 160 insertions, 63 deletions
diff --git a/security/dummy.c b/security/dummy.c index aeee70565509..43874c1e6e23 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -881,7 +881,8 @@ static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x, | |||
881 | return 1; | 881 | return 1; |
882 | } | 882 | } |
883 | 883 | ||
884 | static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 884 | static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, |
885 | struct xfrm_policy *xp) | ||
885 | { | 886 | { |
886 | return 1; | 887 | return 1; |
887 | } | 888 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e9969a2fc846..8ab5679a37a3 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -3313,7 +3313,13 @@ static int selinux_socket_getpeername(struct socket *sock) | |||
3313 | 3313 | ||
3314 | static int selinux_socket_setsockopt(struct socket *sock,int level,int optname) | 3314 | static int selinux_socket_setsockopt(struct socket *sock,int level,int optname) |
3315 | { | 3315 | { |
3316 | return socket_has_perm(current, sock, SOCKET__SETOPT); | 3316 | int err; |
3317 | |||
3318 | err = socket_has_perm(current, sock, SOCKET__SETOPT); | ||
3319 | if (err) | ||
3320 | return err; | ||
3321 | |||
3322 | return selinux_netlbl_socket_setsockopt(sock, level, optname); | ||
3317 | } | 3323 | } |
3318 | 3324 | ||
3319 | static int selinux_socket_getsockopt(struct socket *sock, int level, | 3325 | static int selinux_socket_getsockopt(struct socket *sock, int level, |
diff --git a/security/selinux/include/selinux_netlabel.h b/security/selinux/include/selinux_netlabel.h index ecab4bddaaf4..9de10cc2cef2 100644 --- a/security/selinux/include/selinux_netlabel.h +++ b/security/selinux/include/selinux_netlabel.h | |||
@@ -53,6 +53,9 @@ void selinux_netlbl_sk_security_init(struct sk_security_struct *ssec, | |||
53 | void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, | 53 | void selinux_netlbl_sk_clone_security(struct sk_security_struct *ssec, |
54 | struct sk_security_struct *newssec); | 54 | struct sk_security_struct *newssec); |
55 | int selinux_netlbl_inode_permission(struct inode *inode, int mask); | 55 | int selinux_netlbl_inode_permission(struct inode *inode, int mask); |
56 | int selinux_netlbl_socket_setsockopt(struct socket *sock, | ||
57 | int level, | ||
58 | int optname); | ||
56 | #else | 59 | #else |
57 | static inline void selinux_netlbl_cache_invalidate(void) | 60 | static inline void selinux_netlbl_cache_invalidate(void) |
58 | { | 61 | { |
@@ -114,6 +117,13 @@ static inline int selinux_netlbl_inode_permission(struct inode *inode, | |||
114 | { | 117 | { |
115 | return 0; | 118 | return 0; |
116 | } | 119 | } |
120 | |||
121 | static inline int selinux_netlbl_socket_setsockopt(struct socket *sock, | ||
122 | int level, | ||
123 | int optname) | ||
124 | { | ||
125 | return 0; | ||
126 | } | ||
117 | #endif /* CONFIG_NETLABEL */ | 127 | #endif /* CONFIG_NETLABEL */ |
118 | 128 | ||
119 | #endif | 129 | #endif |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 81eb59890162..526b28019aca 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
@@ -19,7 +19,8 @@ int selinux_xfrm_state_delete(struct xfrm_state *x); | |||
19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); |
20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, | 20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, |
21 | struct xfrm_policy *xp, struct flowi *fl); | 21 | struct xfrm_policy *xp, struct flowi *fl); |
22 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); | 22 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, |
23 | struct xfrm_policy *xp); | ||
23 | 24 | ||
24 | 25 | ||
25 | /* | 26 | /* |
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index cfed1d30fa6a..d539346ab3a2 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
@@ -93,11 +93,15 @@ int ebitmap_export(const struct ebitmap *src, | |||
93 | size_t bitmap_byte; | 93 | size_t bitmap_byte; |
94 | unsigned char bitmask; | 94 | unsigned char bitmask; |
95 | 95 | ||
96 | if (src->highbit == 0) { | ||
97 | *dst = NULL; | ||
98 | *dst_len = 0; | ||
99 | return 0; | ||
100 | } | ||
101 | |||
96 | bitmap_len = src->highbit / 8; | 102 | bitmap_len = src->highbit / 8; |
97 | if (src->highbit % 7) | 103 | if (src->highbit % 7) |
98 | bitmap_len += 1; | 104 | bitmap_len += 1; |
99 | if (bitmap_len == 0) | ||
100 | return -EINVAL; | ||
101 | 105 | ||
102 | bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) + | 106 | bitmap = kzalloc((bitmap_len & ~(sizeof(MAPTYPE) - 1)) + |
103 | sizeof(MAPTYPE), | 107 | sizeof(MAPTYPE), |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index c713af23250a..2cca8e251624 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -640,8 +640,13 @@ int mls_export_cat(const struct context *context, | |||
640 | { | 640 | { |
641 | int rc = -EPERM; | 641 | int rc = -EPERM; |
642 | 642 | ||
643 | if (!selinux_mls_enabled) | 643 | if (!selinux_mls_enabled) { |
644 | *low = NULL; | ||
645 | *low_len = 0; | ||
646 | *high = NULL; | ||
647 | *high_len = 0; | ||
644 | return 0; | 648 | return 0; |
649 | } | ||
645 | 650 | ||
646 | if (low != NULL) { | 651 | if (low != NULL) { |
647 | rc = ebitmap_export(&context->range.level[0].cat, | 652 | rc = ebitmap_export(&context->range.level[0].cat, |
@@ -661,10 +666,16 @@ int mls_export_cat(const struct context *context, | |||
661 | return 0; | 666 | return 0; |
662 | 667 | ||
663 | export_cat_failure: | 668 | export_cat_failure: |
664 | if (low != NULL) | 669 | if (low != NULL) { |
665 | kfree(*low); | 670 | kfree(*low); |
666 | if (high != NULL) | 671 | *low = NULL; |
672 | *low_len = 0; | ||
673 | } | ||
674 | if (high != NULL) { | ||
667 | kfree(*high); | 675 | kfree(*high); |
676 | *high = NULL; | ||
677 | *high_len = 0; | ||
678 | } | ||
668 | return rc; | 679 | return rc; |
669 | } | 680 | } |
670 | 681 | ||
diff --git a/security/selinux/ss/policydb.c b/security/selinux/ss/policydb.c index b18895302555..ba48961f9d05 100644 --- a/security/selinux/ss/policydb.c +++ b/security/selinux/ss/policydb.c | |||
@@ -618,6 +618,7 @@ void policydb_destroy(struct policydb *p) | |||
618 | c = c->next; | 618 | c = c->next; |
619 | ocontext_destroy(ctmp,i); | 619 | ocontext_destroy(ctmp,i); |
620 | } | 620 | } |
621 | p->ocontexts[i] = NULL; | ||
621 | } | 622 | } |
622 | 623 | ||
623 | g = p->genfs; | 624 | g = p->genfs; |
@@ -633,6 +634,7 @@ void policydb_destroy(struct policydb *p) | |||
633 | g = g->next; | 634 | g = g->next; |
634 | kfree(gtmp); | 635 | kfree(gtmp); |
635 | } | 636 | } |
637 | p->genfs = NULL; | ||
636 | 638 | ||
637 | cond_policydb_destroy(p); | 639 | cond_policydb_destroy(p); |
638 | 640 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 0c219a1b3243..bfe122764c98 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2172,7 +2172,12 @@ struct netlbl_cache { | |||
2172 | */ | 2172 | */ |
2173 | static void selinux_netlbl_cache_free(const void *data) | 2173 | static void selinux_netlbl_cache_free(const void *data) |
2174 | { | 2174 | { |
2175 | struct netlbl_cache *cache = NETLBL_CACHE(data); | 2175 | struct netlbl_cache *cache; |
2176 | |||
2177 | if (data == NULL) | ||
2178 | return; | ||
2179 | |||
2180 | cache = NETLBL_CACHE(data); | ||
2176 | switch (cache->type) { | 2181 | switch (cache->type) { |
2177 | case NETLBL_CACHE_T_MLS: | 2182 | case NETLBL_CACHE_T_MLS: |
2178 | ebitmap_destroy(&cache->data.mls_label.level[0].cat); | 2183 | ebitmap_destroy(&cache->data.mls_label.level[0].cat); |
@@ -2197,17 +2202,20 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) | |||
2197 | struct netlbl_lsm_secattr secattr; | 2202 | struct netlbl_lsm_secattr secattr; |
2198 | 2203 | ||
2199 | netlbl_secattr_init(&secattr); | 2204 | netlbl_secattr_init(&secattr); |
2205 | secattr.cache = netlbl_secattr_cache_alloc(GFP_ATOMIC); | ||
2206 | if (secattr.cache == NULL) | ||
2207 | goto netlbl_cache_add_return; | ||
2200 | 2208 | ||
2201 | cache = kzalloc(sizeof(*cache), GFP_ATOMIC); | 2209 | cache = kzalloc(sizeof(*cache), GFP_ATOMIC); |
2202 | if (cache == NULL) | 2210 | if (cache == NULL) |
2203 | goto netlbl_cache_add_failure; | 2211 | goto netlbl_cache_add_return; |
2204 | secattr.cache.free = selinux_netlbl_cache_free; | 2212 | secattr.cache->free = selinux_netlbl_cache_free; |
2205 | secattr.cache.data = (void *)cache; | 2213 | secattr.cache->data = (void *)cache; |
2206 | 2214 | ||
2207 | cache->type = NETLBL_CACHE_T_MLS; | 2215 | cache->type = NETLBL_CACHE_T_MLS; |
2208 | if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, | 2216 | if (ebitmap_cpy(&cache->data.mls_label.level[0].cat, |
2209 | &ctx->range.level[0].cat) != 0) | 2217 | &ctx->range.level[0].cat) != 0) |
2210 | goto netlbl_cache_add_failure; | 2218 | goto netlbl_cache_add_return; |
2211 | cache->data.mls_label.level[1].cat.highbit = | 2219 | cache->data.mls_label.level[1].cat.highbit = |
2212 | cache->data.mls_label.level[0].cat.highbit; | 2220 | cache->data.mls_label.level[0].cat.highbit; |
2213 | cache->data.mls_label.level[1].cat.node = | 2221 | cache->data.mls_label.level[1].cat.node = |
@@ -2215,13 +2223,10 @@ static void selinux_netlbl_cache_add(struct sk_buff *skb, struct context *ctx) | |||
2215 | cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; | 2223 | cache->data.mls_label.level[0].sens = ctx->range.level[0].sens; |
2216 | cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; | 2224 | cache->data.mls_label.level[1].sens = ctx->range.level[0].sens; |
2217 | 2225 | ||
2218 | if (netlbl_cache_add(skb, &secattr) != 0) | 2226 | netlbl_cache_add(skb, &secattr); |
2219 | goto netlbl_cache_add_failure; | ||
2220 | |||
2221 | return; | ||
2222 | 2227 | ||
2223 | netlbl_cache_add_failure: | 2228 | netlbl_cache_add_return: |
2224 | netlbl_secattr_destroy(&secattr, 1); | 2229 | netlbl_secattr_destroy(&secattr); |
2225 | } | 2230 | } |
2226 | 2231 | ||
2227 | /** | 2232 | /** |
@@ -2263,8 +2268,8 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, | |||
2263 | 2268 | ||
2264 | POLICY_RDLOCK; | 2269 | POLICY_RDLOCK; |
2265 | 2270 | ||
2266 | if (secattr->cache.data) { | 2271 | if (secattr->cache) { |
2267 | cache = NETLBL_CACHE(secattr->cache.data); | 2272 | cache = NETLBL_CACHE(secattr->cache->data); |
2268 | switch (cache->type) { | 2273 | switch (cache->type) { |
2269 | case NETLBL_CACHE_T_SID: | 2274 | case NETLBL_CACHE_T_SID: |
2270 | *sid = cache->data.sid; | 2275 | *sid = cache->data.sid; |
@@ -2331,7 +2336,7 @@ static int selinux_netlbl_secattr_to_sid(struct sk_buff *skb, | |||
2331 | selinux_netlbl_cache_add(skb, &ctx_new); | 2336 | selinux_netlbl_cache_add(skb, &ctx_new); |
2332 | ebitmap_destroy(&ctx_new.range.level[0].cat); | 2337 | ebitmap_destroy(&ctx_new.range.level[0].cat); |
2333 | } else { | 2338 | } else { |
2334 | *sid = SECINITSID_UNLABELED; | 2339 | *sid = SECSID_NULL; |
2335 | rc = 0; | 2340 | rc = 0; |
2336 | } | 2341 | } |
2337 | 2342 | ||
@@ -2369,7 +2374,7 @@ static int selinux_netlbl_skbuff_getsid(struct sk_buff *skb, | |||
2369 | &secattr, | 2374 | &secattr, |
2370 | base_sid, | 2375 | base_sid, |
2371 | sid); | 2376 | sid); |
2372 | netlbl_secattr_destroy(&secattr, 0); | 2377 | netlbl_secattr_destroy(&secattr); |
2373 | 2378 | ||
2374 | return rc; | 2379 | return rc; |
2375 | } | 2380 | } |
@@ -2394,31 +2399,33 @@ static int selinux_netlbl_socket_setsid(struct socket *sock, u32 sid) | |||
2394 | if (!ss_initialized) | 2399 | if (!ss_initialized) |
2395 | return 0; | 2400 | return 0; |
2396 | 2401 | ||
2402 | netlbl_secattr_init(&secattr); | ||
2403 | |||
2397 | POLICY_RDLOCK; | 2404 | POLICY_RDLOCK; |
2398 | 2405 | ||
2399 | ctx = sidtab_search(&sidtab, sid); | 2406 | ctx = sidtab_search(&sidtab, sid); |
2400 | if (ctx == NULL) | 2407 | if (ctx == NULL) |
2401 | goto netlbl_socket_setsid_return; | 2408 | goto netlbl_socket_setsid_return; |
2402 | 2409 | ||
2403 | netlbl_secattr_init(&secattr); | ||
2404 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], | 2410 | secattr.domain = kstrdup(policydb.p_type_val_to_name[ctx->type - 1], |
2405 | GFP_ATOMIC); | 2411 | GFP_ATOMIC); |
2406 | mls_export_lvl(ctx, &secattr.mls_lvl, NULL); | 2412 | mls_export_lvl(ctx, &secattr.mls_lvl, NULL); |
2407 | secattr.mls_lvl_vld = 1; | 2413 | secattr.mls_lvl_vld = 1; |
2408 | mls_export_cat(ctx, | 2414 | rc = mls_export_cat(ctx, |
2409 | &secattr.mls_cat, | 2415 | &secattr.mls_cat, |
2410 | &secattr.mls_cat_len, | 2416 | &secattr.mls_cat_len, |
2411 | NULL, | 2417 | NULL, |
2412 | NULL); | 2418 | NULL); |
2419 | if (rc != 0) | ||
2420 | goto netlbl_socket_setsid_return; | ||
2413 | 2421 | ||
2414 | rc = netlbl_socket_setattr(sock, &secattr); | 2422 | rc = netlbl_socket_setattr(sock, &secattr); |
2415 | if (rc == 0) | 2423 | if (rc == 0) |
2416 | sksec->nlbl_state = NLBL_LABELED; | 2424 | sksec->nlbl_state = NLBL_LABELED; |
2417 | 2425 | ||
2418 | netlbl_secattr_destroy(&secattr, 0); | ||
2419 | |||
2420 | netlbl_socket_setsid_return: | 2426 | netlbl_socket_setsid_return: |
2421 | POLICY_RDUNLOCK; | 2427 | POLICY_RDUNLOCK; |
2428 | netlbl_secattr_destroy(&secattr); | ||
2422 | return rc; | 2429 | return rc; |
2423 | } | 2430 | } |
2424 | 2431 | ||
@@ -2514,10 +2521,10 @@ void selinux_netlbl_sock_graft(struct sock *sk, struct socket *sock) | |||
2514 | if (netlbl_sock_getattr(sk, &secattr) == 0 && | 2521 | if (netlbl_sock_getattr(sk, &secattr) == 0 && |
2515 | selinux_netlbl_secattr_to_sid(NULL, | 2522 | selinux_netlbl_secattr_to_sid(NULL, |
2516 | &secattr, | 2523 | &secattr, |
2517 | sksec->sid, | 2524 | SECINITSID_UNLABELED, |
2518 | &nlbl_peer_sid) == 0) | 2525 | &nlbl_peer_sid) == 0) |
2519 | sksec->peer_sid = nlbl_peer_sid; | 2526 | sksec->peer_sid = nlbl_peer_sid; |
2520 | netlbl_secattr_destroy(&secattr, 0); | 2527 | netlbl_secattr_destroy(&secattr); |
2521 | 2528 | ||
2522 | sksec->nlbl_state = NLBL_REQUIRE; | 2529 | sksec->nlbl_state = NLBL_REQUIRE; |
2523 | 2530 | ||
@@ -2547,9 +2554,6 @@ u32 selinux_netlbl_inet_conn_request(struct sk_buff *skb, u32 sock_sid) | |||
2547 | if (rc != 0) | 2554 | if (rc != 0) |
2548 | return SECSID_NULL; | 2555 | return SECSID_NULL; |
2549 | 2556 | ||
2550 | if (peer_sid == SECINITSID_UNLABELED) | ||
2551 | return SECSID_NULL; | ||
2552 | |||
2553 | return peer_sid; | 2557 | return peer_sid; |
2554 | } | 2558 | } |
2555 | 2559 | ||
@@ -2611,11 +2615,13 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | |||
2611 | u32 netlbl_sid; | 2615 | u32 netlbl_sid; |
2612 | u32 recv_perm; | 2616 | u32 recv_perm; |
2613 | 2617 | ||
2614 | rc = selinux_netlbl_skbuff_getsid(skb, SECINITSID_NETMSG, &netlbl_sid); | 2618 | rc = selinux_netlbl_skbuff_getsid(skb, |
2619 | SECINITSID_UNLABELED, | ||
2620 | &netlbl_sid); | ||
2615 | if (rc != 0) | 2621 | if (rc != 0) |
2616 | return rc; | 2622 | return rc; |
2617 | 2623 | ||
2618 | if (netlbl_sid == SECINITSID_UNLABELED) | 2624 | if (netlbl_sid == SECSID_NULL) |
2619 | return 0; | 2625 | return 0; |
2620 | 2626 | ||
2621 | switch (sksec->sclass) { | 2627 | switch (sksec->sclass) { |
@@ -2653,10 +2659,6 @@ int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, | |||
2653 | u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) | 2659 | u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) |
2654 | { | 2660 | { |
2655 | struct sk_security_struct *sksec = sock->sk->sk_security; | 2661 | struct sk_security_struct *sksec = sock->sk->sk_security; |
2656 | |||
2657 | if (sksec->peer_sid == SECINITSID_UNLABELED) | ||
2658 | return SECSID_NULL; | ||
2659 | |||
2660 | return sksec->peer_sid; | 2662 | return sksec->peer_sid; |
2661 | } | 2663 | } |
2662 | 2664 | ||
@@ -2672,18 +2674,49 @@ u32 selinux_netlbl_socket_getpeersec_stream(struct socket *sock) | |||
2672 | u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) | 2674 | u32 selinux_netlbl_socket_getpeersec_dgram(struct sk_buff *skb) |
2673 | { | 2675 | { |
2674 | int peer_sid; | 2676 | int peer_sid; |
2675 | struct sock *sk = skb->sk; | ||
2676 | struct inode_security_struct *isec; | ||
2677 | 2677 | ||
2678 | if (sk == NULL || sk->sk_socket == NULL) | 2678 | if (selinux_netlbl_skbuff_getsid(skb, |
2679 | return SECSID_NULL; | 2679 | SECINITSID_UNLABELED, |
2680 | 2680 | &peer_sid) != 0) | |
2681 | isec = SOCK_INODE(sk->sk_socket)->i_security; | ||
2682 | if (selinux_netlbl_skbuff_getsid(skb, isec->sid, &peer_sid) != 0) | ||
2683 | return SECSID_NULL; | ||
2684 | if (peer_sid == SECINITSID_UNLABELED) | ||
2685 | return SECSID_NULL; | 2681 | return SECSID_NULL; |
2686 | 2682 | ||
2687 | return peer_sid; | 2683 | return peer_sid; |
2688 | } | 2684 | } |
2685 | |||
2686 | /** | ||
2687 | * selinux_netlbl_socket_setsockopt - Do not allow users to remove a NetLabel | ||
2688 | * @sock: the socket | ||
2689 | * @level: the socket level or protocol | ||
2690 | * @optname: the socket option name | ||
2691 | * | ||
2692 | * Description: | ||
2693 | * Check the setsockopt() call and if the user is trying to replace the IP | ||
2694 | * options on a socket and a NetLabel is in place for the socket deny the | ||
2695 | * access; otherwise allow the access. Returns zero when the access is | ||
2696 | * allowed, -EACCES when denied, and other negative values on error. | ||
2697 | * | ||
2698 | */ | ||
2699 | int selinux_netlbl_socket_setsockopt(struct socket *sock, | ||
2700 | int level, | ||
2701 | int optname) | ||
2702 | { | ||
2703 | int rc = 0; | ||
2704 | struct inode *inode = SOCK_INODE(sock); | ||
2705 | struct sk_security_struct *sksec = sock->sk->sk_security; | ||
2706 | struct inode_security_struct *isec = inode->i_security; | ||
2707 | struct netlbl_lsm_secattr secattr; | ||
2708 | |||
2709 | mutex_lock(&isec->lock); | ||
2710 | if (level == IPPROTO_IP && optname == IP_OPTIONS && | ||
2711 | sksec->nlbl_state == NLBL_LABELED) { | ||
2712 | netlbl_secattr_init(&secattr); | ||
2713 | rc = netlbl_socket_getattr(sock, &secattr); | ||
2714 | if (rc == 0 && (secattr.cache || secattr.mls_lvl_vld)) | ||
2715 | rc = -EACCES; | ||
2716 | netlbl_secattr_destroy(&secattr); | ||
2717 | } | ||
2718 | mutex_unlock(&isec->lock); | ||
2719 | |||
2720 | return rc; | ||
2721 | } | ||
2689 | #endif /* CONFIG_NETLABEL */ | 2722 | #endif /* CONFIG_NETLABEL */ |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 3e742b850af6..675b995a67c3 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -77,8 +77,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) | |||
77 | */ | 77 | */ |
78 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 78 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) |
79 | { | 79 | { |
80 | int rc = 0; | 80 | int rc; |
81 | u32 sel_sid = SECINITSID_UNLABELED; | 81 | u32 sel_sid; |
82 | struct xfrm_sec_ctx *ctx; | 82 | struct xfrm_sec_ctx *ctx; |
83 | 83 | ||
84 | /* Context sid is either set to label or ANY_ASSOC */ | 84 | /* Context sid is either set to label or ANY_ASSOC */ |
@@ -88,11 +88,21 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | |||
88 | 88 | ||
89 | sel_sid = ctx->ctx_sid; | 89 | sel_sid = ctx->ctx_sid; |
90 | } | 90 | } |
91 | else | ||
92 | /* | ||
93 | * All flows should be treated as polmatch'ing an | ||
94 | * otherwise applicable "non-labeled" policy. This | ||
95 | * would prevent inadvertent "leaks". | ||
96 | */ | ||
97 | return 0; | ||
91 | 98 | ||
92 | rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, | 99 | rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, |
93 | ASSOCIATION__POLMATCH, | 100 | ASSOCIATION__POLMATCH, |
94 | NULL); | 101 | NULL); |
95 | 102 | ||
103 | if (rc == -EACCES) | ||
104 | rc = -ESRCH; | ||
105 | |||
96 | return rc; | 106 | return rc; |
97 | } | 107 | } |
98 | 108 | ||
@@ -108,15 +118,20 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * | |||
108 | u32 pol_sid; | 118 | u32 pol_sid; |
109 | int err; | 119 | int err; |
110 | 120 | ||
111 | if (x->security) | 121 | if (xp->security) { |
112 | state_sid = x->security->ctx_sid; | 122 | if (!x->security) |
113 | else | 123 | /* unlabeled SA and labeled policy can't match */ |
114 | state_sid = SECINITSID_UNLABELED; | 124 | return 0; |
115 | 125 | else | |
116 | if (xp->security) | 126 | state_sid = x->security->ctx_sid; |
117 | pol_sid = xp->security->ctx_sid; | 127 | pol_sid = xp->security->ctx_sid; |
118 | else | 128 | } else |
119 | pol_sid = SECINITSID_UNLABELED; | 129 | if (x->security) |
130 | /* unlabeled policy and labeled SA can't match */ | ||
131 | return 0; | ||
132 | else | ||
133 | /* unlabeled policy and unlabeled SA match all flows */ | ||
134 | return 1; | ||
120 | 135 | ||
121 | err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, | 136 | err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, |
122 | ASSOCIATION__POLMATCH, | 137 | ASSOCIATION__POLMATCH, |
@@ -125,7 +140,11 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * | |||
125 | if (err) | 140 | if (err) |
126 | return 0; | 141 | return 0; |
127 | 142 | ||
128 | return selinux_xfrm_flow_state_match(fl, x); | 143 | err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION, |
144 | ASSOCIATION__SENDTO, | ||
145 | NULL)? 0:1; | ||
146 | |||
147 | return err; | ||
129 | } | 148 | } |
130 | 149 | ||
131 | /* | 150 | /* |
@@ -133,12 +152,22 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy * | |||
133 | * can use a given security association. | 152 | * can use a given security association. |
134 | */ | 153 | */ |
135 | 154 | ||
136 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) | 155 | int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm, |
156 | struct xfrm_policy *xp) | ||
137 | { | 157 | { |
138 | int rc = 0; | 158 | int rc = 0; |
139 | u32 sel_sid = SECINITSID_UNLABELED; | 159 | u32 sel_sid = SECINITSID_UNLABELED; |
140 | struct xfrm_sec_ctx *ctx; | 160 | struct xfrm_sec_ctx *ctx; |
141 | 161 | ||
162 | if (!xp->security) | ||
163 | if (!xfrm->security) | ||
164 | return 1; | ||
165 | else | ||
166 | return 0; | ||
167 | else | ||
168 | if (!xfrm->security) | ||
169 | return 0; | ||
170 | |||
142 | /* Context sid is either set to label or ANY_ASSOC */ | 171 | /* Context sid is either set to label or ANY_ASSOC */ |
143 | if ((ctx = xfrm->security)) { | 172 | if ((ctx = xfrm->security)) { |
144 | if (!selinux_authorizable_ctx(ctx)) | 173 | if (!selinux_authorizable_ctx(ctx)) |