diff options
-rw-r--r-- | include/linux/security.h | 48 | ||||
-rw-r--r-- | net/key/af_key.c | 23 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 24 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 33 | ||||
-rw-r--r-- | security/dummy.c | 14 | ||||
-rw-r--r-- | security/security.c | 21 | ||||
-rw-r--r-- | security/selinux/include/xfrm.h | 13 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 39 |
8 files changed, 109 insertions, 106 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index c673dfd4dffc..f5eb9ff47ac5 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -910,24 +910,24 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
910 | * Security hooks for XFRM operations. | 910 | * Security hooks for XFRM operations. |
911 | * | 911 | * |
912 | * @xfrm_policy_alloc_security: | 912 | * @xfrm_policy_alloc_security: |
913 | * @xp contains the xfrm_policy being added to Security Policy Database | 913 | * @ctxp is a pointer to the xfrm_sec_ctx being added to Security Policy |
914 | * used by the XFRM system. | 914 | * Database used by the XFRM system. |
915 | * @sec_ctx contains the security context information being provided by | 915 | * @sec_ctx contains the security context information being provided by |
916 | * the user-level policy update program (e.g., setkey). | 916 | * the user-level policy update program (e.g., setkey). |
917 | * Allocate a security structure to the xp->security field; the security | 917 | * Allocate a security structure to the xp->security field; the security |
918 | * field is initialized to NULL when the xfrm_policy is allocated. | 918 | * field is initialized to NULL when the xfrm_policy is allocated. |
919 | * Return 0 if operation was successful (memory to allocate, legal context) | 919 | * Return 0 if operation was successful (memory to allocate, legal context) |
920 | * @xfrm_policy_clone_security: | 920 | * @xfrm_policy_clone_security: |
921 | * @old contains an existing xfrm_policy in the SPD. | 921 | * @old_ctx contains an existing xfrm_sec_ctx. |
922 | * @new contains a new xfrm_policy being cloned from old. | 922 | * @new_ctxp contains a new xfrm_sec_ctx being cloned from old. |
923 | * Allocate a security structure to the new->security field | 923 | * Allocate a security structure in new_ctxp that contains the |
924 | * that contains the information from the old->security field. | 924 | * information from the old_ctx structure. |
925 | * Return 0 if operation was successful (memory to allocate). | 925 | * Return 0 if operation was successful (memory to allocate). |
926 | * @xfrm_policy_free_security: | 926 | * @xfrm_policy_free_security: |
927 | * @xp contains the xfrm_policy | 927 | * @ctx contains the xfrm_sec_ctx |
928 | * Deallocate xp->security. | 928 | * Deallocate xp->security. |
929 | * @xfrm_policy_delete_security: | 929 | * @xfrm_policy_delete_security: |
930 | * @xp contains the xfrm_policy. | 930 | * @ctx contains the xfrm_sec_ctx. |
931 | * Authorize deletion of xp->security. | 931 | * Authorize deletion of xp->security. |
932 | * @xfrm_state_alloc_security: | 932 | * @xfrm_state_alloc_security: |
933 | * @x contains the xfrm_state being added to the Security Association | 933 | * @x contains the xfrm_state being added to the Security Association |
@@ -947,7 +947,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
947 | * @x contains the xfrm_state. | 947 | * @x contains the xfrm_state. |
948 | * Authorize deletion of x->security. | 948 | * Authorize deletion of x->security. |
949 | * @xfrm_policy_lookup: | 949 | * @xfrm_policy_lookup: |
950 | * @xp contains the xfrm_policy for which the access control is being | 950 | * @ctx contains the xfrm_sec_ctx for which the access control is being |
951 | * checked. | 951 | * checked. |
952 | * @fl_secid contains the flow security label that is used to authorize | 952 | * @fl_secid contains the flow security label that is used to authorize |
953 | * access to the policy xp. | 953 | * access to the policy xp. |
@@ -1454,17 +1454,17 @@ struct security_operations { | |||
1454 | #endif /* CONFIG_SECURITY_NETWORK */ | 1454 | #endif /* CONFIG_SECURITY_NETWORK */ |
1455 | 1455 | ||
1456 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1456 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1457 | int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, | 1457 | int (*xfrm_policy_alloc_security) (struct xfrm_sec_ctx **ctxp, |
1458 | struct xfrm_user_sec_ctx *sec_ctx); | 1458 | struct xfrm_user_sec_ctx *sec_ctx); |
1459 | int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); | 1459 | int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx); |
1460 | void (*xfrm_policy_free_security) (struct xfrm_policy *xp); | 1460 | void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx); |
1461 | int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); | 1461 | int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx); |
1462 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, | 1462 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, |
1463 | struct xfrm_user_sec_ctx *sec_ctx, | 1463 | struct xfrm_user_sec_ctx *sec_ctx, |
1464 | u32 secid); | 1464 | u32 secid); |
1465 | void (*xfrm_state_free_security) (struct xfrm_state *x); | 1465 | void (*xfrm_state_free_security) (struct xfrm_state *x); |
1466 | int (*xfrm_state_delete_security) (struct xfrm_state *x); | 1466 | int (*xfrm_state_delete_security) (struct xfrm_state *x); |
1467 | int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 1467 | int (*xfrm_policy_lookup)(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); |
1468 | int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, | 1468 | int (*xfrm_state_pol_flow_match)(struct xfrm_state *x, |
1469 | struct xfrm_policy *xp, struct flowi *fl); | 1469 | struct xfrm_policy *xp, struct flowi *fl); |
1470 | int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); | 1470 | int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall); |
@@ -2562,16 +2562,16 @@ static inline void security_inet_conn_established(struct sock *sk, | |||
2562 | 2562 | ||
2563 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 2563 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
2564 | 2564 | ||
2565 | int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); | 2565 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx); |
2566 | int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); | 2566 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp); |
2567 | void security_xfrm_policy_free(struct xfrm_policy *xp); | 2567 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx); |
2568 | int security_xfrm_policy_delete(struct xfrm_policy *xp); | 2568 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); |
2569 | int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); | 2569 | int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); |
2570 | int security_xfrm_state_alloc_acquire(struct xfrm_state *x, | 2570 | int security_xfrm_state_alloc_acquire(struct xfrm_state *x, |
2571 | struct xfrm_sec_ctx *polsec, u32 secid); | 2571 | struct xfrm_sec_ctx *polsec, u32 secid); |
2572 | int security_xfrm_state_delete(struct xfrm_state *x); | 2572 | int security_xfrm_state_delete(struct xfrm_state *x); |
2573 | void security_xfrm_state_free(struct xfrm_state *x); | 2573 | void security_xfrm_state_free(struct xfrm_state *x); |
2574 | int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 2574 | int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); |
2575 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | 2575 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, |
2576 | struct xfrm_policy *xp, struct flowi *fl); | 2576 | struct xfrm_policy *xp, struct flowi *fl); |
2577 | int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid); | 2577 | int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid); |
@@ -2579,21 +2579,21 @@ void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl); | |||
2579 | 2579 | ||
2580 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ | 2580 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ |
2581 | 2581 | ||
2582 | static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | 2582 | static inline int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) |
2583 | { | 2583 | { |
2584 | return 0; | 2584 | return 0; |
2585 | } | 2585 | } |
2586 | 2586 | ||
2587 | static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 2587 | static inline int security_xfrm_policy_clone(struct xfrm_sec_ctx *old, struct xfrm_sec_ctx **new_ctxp) |
2588 | { | 2588 | { |
2589 | return 0; | 2589 | return 0; |
2590 | } | 2590 | } |
2591 | 2591 | ||
2592 | static inline void security_xfrm_policy_free(struct xfrm_policy *xp) | 2592 | static inline void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
2593 | { | 2593 | { |
2594 | } | 2594 | } |
2595 | 2595 | ||
2596 | static inline int security_xfrm_policy_delete(struct xfrm_policy *xp) | 2596 | static inline int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
2597 | { | 2597 | { |
2598 | return 0; | 2598 | return 0; |
2599 | } | 2599 | } |
@@ -2619,7 +2619,7 @@ static inline int security_xfrm_state_delete(struct xfrm_state *x) | |||
2619 | return 0; | 2619 | return 0; |
2620 | } | 2620 | } |
2621 | 2621 | ||
2622 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 2622 | static inline int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) |
2623 | { | 2623 | { |
2624 | return 0; | 2624 | return 0; |
2625 | } | 2625 | } |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 6db58924368a..1fb0fe42a72e 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2292,7 +2292,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
2292 | goto out; | 2292 | goto out; |
2293 | } | 2293 | } |
2294 | 2294 | ||
2295 | err = security_xfrm_policy_alloc(xp, uctx); | 2295 | err = security_xfrm_policy_alloc(&xp->security, uctx); |
2296 | kfree(uctx); | 2296 | kfree(uctx); |
2297 | 2297 | ||
2298 | if (err) | 2298 | if (err) |
@@ -2352,10 +2352,11 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2352 | int err; | 2352 | int err; |
2353 | struct sadb_address *sa; | 2353 | struct sadb_address *sa; |
2354 | struct sadb_x_policy *pol; | 2354 | struct sadb_x_policy *pol; |
2355 | struct xfrm_policy *xp, tmp; | 2355 | struct xfrm_policy *xp; |
2356 | struct xfrm_selector sel; | 2356 | struct xfrm_selector sel; |
2357 | struct km_event c; | 2357 | struct km_event c; |
2358 | struct sadb_x_sec_ctx *sec_ctx; | 2358 | struct sadb_x_sec_ctx *sec_ctx; |
2359 | struct xfrm_sec_ctx *pol_ctx; | ||
2359 | 2360 | ||
2360 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], | 2361 | if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC-1], |
2361 | ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || | 2362 | ext_hdrs[SADB_EXT_ADDRESS_DST-1]) || |
@@ -2385,25 +2386,23 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
2385 | sel.dport_mask = htons(0xffff); | 2386 | sel.dport_mask = htons(0xffff); |
2386 | 2387 | ||
2387 | sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1]; | 2388 | sec_ctx = (struct sadb_x_sec_ctx *) ext_hdrs[SADB_X_EXT_SEC_CTX-1]; |
2388 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
2389 | |||
2390 | if (sec_ctx != NULL) { | 2389 | if (sec_ctx != NULL) { |
2391 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | 2390 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); |
2392 | 2391 | ||
2393 | if (!uctx) | 2392 | if (!uctx) |
2394 | return -ENOMEM; | 2393 | return -ENOMEM; |
2395 | 2394 | ||
2396 | err = security_xfrm_policy_alloc(&tmp, uctx); | 2395 | err = security_xfrm_policy_alloc(&pol_ctx, uctx); |
2397 | kfree(uctx); | 2396 | kfree(uctx); |
2398 | |||
2399 | if (err) | 2397 | if (err) |
2400 | return err; | 2398 | return err; |
2401 | } | 2399 | } else |
2402 | 2400 | pol_ctx = NULL; | |
2403 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, | ||
2404 | &sel, tmp.security, 1, &err); | ||
2405 | security_xfrm_policy_free(&tmp); | ||
2406 | 2401 | ||
2402 | xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, | ||
2403 | pol->sadb_x_policy_dir - 1, &sel, pol_ctx, | ||
2404 | 1, &err); | ||
2405 | security_xfrm_policy_free(pol_ctx); | ||
2407 | if (xp == NULL) | 2406 | if (xp == NULL) |
2408 | return -ENOENT; | 2407 | return -ENOENT; |
2409 | 2408 | ||
@@ -3298,7 +3297,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
3298 | if ((*dir = verify_sec_ctx_len(p))) | 3297 | if ((*dir = verify_sec_ctx_len(p))) |
3299 | goto out; | 3298 | goto out; |
3300 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | 3299 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); |
3301 | *dir = security_xfrm_policy_alloc(xp, uctx); | 3300 | *dir = security_xfrm_policy_alloc(&xp->security, uctx); |
3302 | kfree(uctx); | 3301 | kfree(uctx); |
3303 | 3302 | ||
3304 | if (*dir) | 3303 | if (*dir) |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 15d73e47cc2c..ab4d0e598a2c 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -263,7 +263,7 @@ void xfrm_policy_destroy(struct xfrm_policy *policy) | |||
263 | list_del(&policy->bytype); | 263 | list_del(&policy->bytype); |
264 | write_unlock_bh(&xfrm_policy_lock); | 264 | write_unlock_bh(&xfrm_policy_lock); |
265 | 265 | ||
266 | security_xfrm_policy_free(policy); | 266 | security_xfrm_policy_free(policy->security); |
267 | kfree(policy); | 267 | kfree(policy); |
268 | } | 268 | } |
269 | EXPORT_SYMBOL(xfrm_policy_destroy); | 269 | EXPORT_SYMBOL(xfrm_policy_destroy); |
@@ -676,7 +676,8 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir, | |||
676 | xfrm_sec_ctx_match(ctx, pol->security)) { | 676 | xfrm_sec_ctx_match(ctx, pol->security)) { |
677 | xfrm_pol_hold(pol); | 677 | xfrm_pol_hold(pol); |
678 | if (delete) { | 678 | if (delete) { |
679 | *err = security_xfrm_policy_delete(pol); | 679 | *err = security_xfrm_policy_delete( |
680 | pol->security); | ||
680 | if (*err) { | 681 | if (*err) { |
681 | write_unlock_bh(&xfrm_policy_lock); | 682 | write_unlock_bh(&xfrm_policy_lock); |
682 | return pol; | 683 | return pol; |
@@ -718,7 +719,8 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete, | |||
718 | if (pol->type == type && pol->index == id) { | 719 | if (pol->type == type && pol->index == id) { |
719 | xfrm_pol_hold(pol); | 720 | xfrm_pol_hold(pol); |
720 | if (delete) { | 721 | if (delete) { |
721 | *err = security_xfrm_policy_delete(pol); | 722 | *err = security_xfrm_policy_delete( |
723 | pol->security); | ||
722 | if (*err) { | 724 | if (*err) { |
723 | write_unlock_bh(&xfrm_policy_lock); | 725 | write_unlock_bh(&xfrm_policy_lock); |
724 | return pol; | 726 | return pol; |
@@ -756,7 +758,7 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | |||
756 | &xfrm_policy_inexact[dir], bydst) { | 758 | &xfrm_policy_inexact[dir], bydst) { |
757 | if (pol->type != type) | 759 | if (pol->type != type) |
758 | continue; | 760 | continue; |
759 | err = security_xfrm_policy_delete(pol); | 761 | err = security_xfrm_policy_delete(pol->security); |
760 | if (err) { | 762 | if (err) { |
761 | xfrm_audit_policy_delete(pol, 0, | 763 | xfrm_audit_policy_delete(pol, 0, |
762 | audit_info->loginuid, | 764 | audit_info->loginuid, |
@@ -770,7 +772,8 @@ xfrm_policy_flush_secctx_check(u8 type, struct xfrm_audit *audit_info) | |||
770 | bydst) { | 772 | bydst) { |
771 | if (pol->type != type) | 773 | if (pol->type != type) |
772 | continue; | 774 | continue; |
773 | err = security_xfrm_policy_delete(pol); | 775 | err = security_xfrm_policy_delete( |
776 | pol->security); | ||
774 | if (err) { | 777 | if (err) { |
775 | xfrm_audit_policy_delete(pol, 0, | 778 | xfrm_audit_policy_delete(pol, 0, |
776 | audit_info->loginuid, | 779 | audit_info->loginuid, |
@@ -931,7 +934,8 @@ static int xfrm_policy_match(struct xfrm_policy *pol, struct flowi *fl, | |||
931 | 934 | ||
932 | match = xfrm_selector_match(sel, fl, family); | 935 | match = xfrm_selector_match(sel, fl, family); |
933 | if (match) | 936 | if (match) |
934 | ret = security_xfrm_policy_lookup(pol, fl->secid, dir); | 937 | ret = security_xfrm_policy_lookup(pol->security, fl->secid, |
938 | dir); | ||
935 | 939 | ||
936 | return ret; | 940 | return ret; |
937 | } | 941 | } |
@@ -1048,8 +1052,9 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(struct sock *sk, int dir, struc | |||
1048 | int err = 0; | 1052 | int err = 0; |
1049 | 1053 | ||
1050 | if (match) { | 1054 | if (match) { |
1051 | err = security_xfrm_policy_lookup(pol, fl->secid, | 1055 | err = security_xfrm_policy_lookup(pol->security, |
1052 | policy_to_flow_dir(dir)); | 1056 | fl->secid, |
1057 | policy_to_flow_dir(dir)); | ||
1053 | if (!err) | 1058 | if (!err) |
1054 | xfrm_pol_hold(pol); | 1059 | xfrm_pol_hold(pol); |
1055 | else if (err == -ESRCH) | 1060 | else if (err == -ESRCH) |
@@ -1138,7 +1143,8 @@ static struct xfrm_policy *clone_policy(struct xfrm_policy *old, int dir) | |||
1138 | 1143 | ||
1139 | if (newp) { | 1144 | if (newp) { |
1140 | newp->selector = old->selector; | 1145 | newp->selector = old->selector; |
1141 | if (security_xfrm_policy_clone(old, newp)) { | 1146 | if (security_xfrm_policy_clone(old->security, |
1147 | &newp->security)) { | ||
1142 | kfree(newp); | 1148 | kfree(newp); |
1143 | return NULL; /* ENOMEM */ | 1149 | return NULL; /* ENOMEM */ |
1144 | } | 1150 | } |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5578c909fcf6..ecf9d67daef5 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -959,7 +959,7 @@ static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs | |||
959 | return 0; | 959 | return 0; |
960 | 960 | ||
961 | uctx = nla_data(rt); | 961 | uctx = nla_data(rt); |
962 | return security_xfrm_policy_alloc(pol, uctx); | 962 | return security_xfrm_policy_alloc(&pol->security, uctx); |
963 | } | 963 | } |
964 | 964 | ||
965 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 965 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, |
@@ -1143,7 +1143,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1143 | NETLINK_CB(skb).sid); | 1143 | NETLINK_CB(skb).sid); |
1144 | 1144 | ||
1145 | if (err) { | 1145 | if (err) { |
1146 | security_xfrm_policy_free(xp); | 1146 | security_xfrm_policy_free(xp->security); |
1147 | kfree(xp); | 1147 | kfree(xp); |
1148 | return err; | 1148 | return err; |
1149 | } | 1149 | } |
@@ -1337,22 +1337,23 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1337 | xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); | 1337 | xp = xfrm_policy_byid(type, p->dir, p->index, delete, &err); |
1338 | else { | 1338 | else { |
1339 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1339 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1340 | struct xfrm_policy tmp; | 1340 | struct xfrm_sec_ctx *ctx; |
1341 | 1341 | ||
1342 | err = verify_sec_ctx_len(attrs); | 1342 | err = verify_sec_ctx_len(attrs); |
1343 | if (err) | 1343 | if (err) |
1344 | return err; | 1344 | return err; |
1345 | 1345 | ||
1346 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
1347 | if (rt) { | 1346 | if (rt) { |
1348 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1347 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1349 | 1348 | ||
1350 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1349 | err = security_xfrm_policy_alloc(&ctx, uctx); |
1350 | if (err) | ||
1351 | return err; | 1351 | return err; |
1352 | } | 1352 | } else |
1353 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, | 1353 | ctx = NULL; |
1354 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, | ||
1354 | delete, &err); | 1355 | delete, &err); |
1355 | security_xfrm_policy_free(&tmp); | 1356 | security_xfrm_policy_free(ctx); |
1356 | } | 1357 | } |
1357 | if (xp == NULL) | 1358 | if (xp == NULL) |
1358 | return -ENOENT; | 1359 | return -ENOENT; |
@@ -1572,26 +1573,26 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1572 | xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); | 1573 | xp = xfrm_policy_byid(type, p->dir, p->index, 0, &err); |
1573 | else { | 1574 | else { |
1574 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; | 1575 | struct nlattr *rt = attrs[XFRMA_SEC_CTX]; |
1575 | struct xfrm_policy tmp; | 1576 | struct xfrm_sec_ctx *ctx; |
1576 | 1577 | ||
1577 | err = verify_sec_ctx_len(attrs); | 1578 | err = verify_sec_ctx_len(attrs); |
1578 | if (err) | 1579 | if (err) |
1579 | return err; | 1580 | return err; |
1580 | 1581 | ||
1581 | memset(&tmp, 0, sizeof(struct xfrm_policy)); | ||
1582 | if (rt) { | 1582 | if (rt) { |
1583 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1583 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1584 | 1584 | ||
1585 | if ((err = security_xfrm_policy_alloc(&tmp, uctx))) | 1585 | err = security_xfrm_policy_alloc(&ctx, uctx); |
1586 | if (err) | ||
1586 | return err; | 1587 | return err; |
1587 | } | 1588 | } else |
1588 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, | 1589 | ctx = NULL; |
1589 | 0, &err); | 1590 | xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, ctx, 0, &err); |
1590 | security_xfrm_policy_free(&tmp); | 1591 | security_xfrm_policy_free(ctx); |
1591 | } | 1592 | } |
1592 | |||
1593 | if (xp == NULL) | 1593 | if (xp == NULL) |
1594 | return -ENOENT; | 1594 | return -ENOENT; |
1595 | |||
1595 | read_lock(&xp->lock); | 1596 | read_lock(&xp->lock); |
1596 | if (xp->dead) { | 1597 | if (xp->dead) { |
1597 | read_unlock(&xp->lock); | 1598 | read_unlock(&xp->lock); |
diff --git a/security/dummy.c b/security/dummy.c index 78d8f92310a4..480366f9c41d 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -876,22 +876,23 @@ static inline void dummy_req_classify_flow(const struct request_sock *req, | |||
876 | #endif /* CONFIG_SECURITY_NETWORK */ | 876 | #endif /* CONFIG_SECURITY_NETWORK */ |
877 | 877 | ||
878 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 878 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
879 | static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, | 879 | static int dummy_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, |
880 | struct xfrm_user_sec_ctx *sec_ctx) | 880 | struct xfrm_user_sec_ctx *sec_ctx) |
881 | { | 881 | { |
882 | return 0; | 882 | return 0; |
883 | } | 883 | } |
884 | 884 | ||
885 | static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new) | 885 | static inline int dummy_xfrm_policy_clone_security(struct xfrm_sec_ctx *old_ctx, |
886 | struct xfrm_sec_ctx **new_ctxp) | ||
886 | { | 887 | { |
887 | return 0; | 888 | return 0; |
888 | } | 889 | } |
889 | 890 | ||
890 | static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp) | 891 | static void dummy_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx) |
891 | { | 892 | { |
892 | } | 893 | } |
893 | 894 | ||
894 | static int dummy_xfrm_policy_delete_security(struct xfrm_policy *xp) | 895 | static int dummy_xfrm_policy_delete_security(struct xfrm_sec_ctx *ctx) |
895 | { | 896 | { |
896 | return 0; | 897 | return 0; |
897 | } | 898 | } |
@@ -911,7 +912,8 @@ static int dummy_xfrm_state_delete_security(struct xfrm_state *x) | |||
911 | return 0; | 912 | return 0; |
912 | } | 913 | } |
913 | 914 | ||
914 | static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | 915 | static int dummy_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, |
916 | u32 sk_sid, u8 dir) | ||
915 | { | 917 | { |
916 | return 0; | 918 | return 0; |
917 | } | 919 | } |
diff --git a/security/security.c b/security/security.c index b1387a6b416d..c9ff7d18c2f4 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1014,26 +1014,27 @@ void security_inet_conn_established(struct sock *sk, | |||
1014 | 1014 | ||
1015 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1015 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1016 | 1016 | ||
1017 | int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | 1017 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) |
1018 | { | 1018 | { |
1019 | return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); | 1019 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx); |
1020 | } | 1020 | } |
1021 | EXPORT_SYMBOL(security_xfrm_policy_alloc); | 1021 | EXPORT_SYMBOL(security_xfrm_policy_alloc); |
1022 | 1022 | ||
1023 | int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 1023 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
1024 | struct xfrm_sec_ctx **new_ctxp) | ||
1024 | { | 1025 | { |
1025 | return security_ops->xfrm_policy_clone_security(old, new); | 1026 | return security_ops->xfrm_policy_clone_security(old_ctx, new_ctxp); |
1026 | } | 1027 | } |
1027 | 1028 | ||
1028 | void security_xfrm_policy_free(struct xfrm_policy *xp) | 1029 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
1029 | { | 1030 | { |
1030 | security_ops->xfrm_policy_free_security(xp); | 1031 | security_ops->xfrm_policy_free_security(ctx); |
1031 | } | 1032 | } |
1032 | EXPORT_SYMBOL(security_xfrm_policy_free); | 1033 | EXPORT_SYMBOL(security_xfrm_policy_free); |
1033 | 1034 | ||
1034 | int security_xfrm_policy_delete(struct xfrm_policy *xp) | 1035 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
1035 | { | 1036 | { |
1036 | return security_ops->xfrm_policy_delete_security(xp); | 1037 | return security_ops->xfrm_policy_delete_security(ctx); |
1037 | } | 1038 | } |
1038 | 1039 | ||
1039 | int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 1040 | int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) |
@@ -1065,9 +1066,9 @@ void security_xfrm_state_free(struct xfrm_state *x) | |||
1065 | security_ops->xfrm_state_free_security(x); | 1066 | security_ops->xfrm_state_free_security(x); |
1066 | } | 1067 | } |
1067 | 1068 | ||
1068 | int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 1069 | int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) |
1069 | { | 1070 | { |
1070 | return security_ops->xfrm_policy_lookup(xp, fl_secid, dir); | 1071 | return security_ops->xfrm_policy_lookup(ctx, fl_secid, dir); |
1071 | } | 1072 | } |
1072 | 1073 | ||
1073 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | 1074 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 36b0510efa7b..289e24b39e3e 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
@@ -7,16 +7,17 @@ | |||
7 | #ifndef _SELINUX_XFRM_H_ | 7 | #ifndef _SELINUX_XFRM_H_ |
8 | #define _SELINUX_XFRM_H_ | 8 | #define _SELINUX_XFRM_H_ |
9 | 9 | ||
10 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, | 10 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
11 | struct xfrm_user_sec_ctx *sec_ctx); | 11 | struct xfrm_user_sec_ctx *sec_ctx); |
12 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); | 12 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
13 | void selinux_xfrm_policy_free(struct xfrm_policy *xp); | 13 | struct xfrm_sec_ctx **new_ctxp); |
14 | int selinux_xfrm_policy_delete(struct xfrm_policy *xp); | 14 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); |
15 | int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); | ||
15 | int selinux_xfrm_state_alloc(struct xfrm_state *x, | 16 | int selinux_xfrm_state_alloc(struct xfrm_state *x, |
16 | struct xfrm_user_sec_ctx *sec_ctx, u32 secid); | 17 | struct xfrm_user_sec_ctx *sec_ctx, u32 secid); |
17 | void selinux_xfrm_state_free(struct xfrm_state *x); | 18 | void selinux_xfrm_state_free(struct xfrm_state *x); |
18 | int selinux_xfrm_state_delete(struct xfrm_state *x); | 19 | int selinux_xfrm_state_delete(struct xfrm_state *x); |
19 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); | 20 | int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir); |
20 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, | 21 | int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, |
21 | struct xfrm_policy *xp, struct flowi *fl); | 22 | struct xfrm_policy *xp, struct flowi *fl); |
22 | 23 | ||
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 7e158205d081..874d17c83c61 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -77,20 +77,18 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) | |||
77 | * LSM hook implementation that authorizes that a flow can use | 77 | * LSM hook implementation that authorizes that a flow can use |
78 | * a xfrm policy rule. | 78 | * a xfrm policy rule. |
79 | */ | 79 | */ |
80 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 80 | int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) |
81 | { | 81 | { |
82 | int rc; | 82 | int rc; |
83 | u32 sel_sid; | 83 | u32 sel_sid; |
84 | struct xfrm_sec_ctx *ctx; | ||
85 | 84 | ||
86 | /* Context sid is either set to label or ANY_ASSOC */ | 85 | /* Context sid is either set to label or ANY_ASSOC */ |
87 | if ((ctx = xp->security)) { | 86 | if (ctx) { |
88 | if (!selinux_authorizable_ctx(ctx)) | 87 | if (!selinux_authorizable_ctx(ctx)) |
89 | return -EINVAL; | 88 | return -EINVAL; |
90 | 89 | ||
91 | sel_sid = ctx->ctx_sid; | 90 | sel_sid = ctx->ctx_sid; |
92 | } | 91 | } else |
93 | else | ||
94 | /* | 92 | /* |
95 | * All flows should be treated as polmatch'ing an | 93 | * All flows should be treated as polmatch'ing an |
96 | * otherwise applicable "non-labeled" policy. This | 94 | * otherwise applicable "non-labeled" policy. This |
@@ -103,7 +101,7 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | |||
103 | NULL); | 101 | NULL); |
104 | 102 | ||
105 | if (rc == -EACCES) | 103 | if (rc == -EACCES) |
106 | rc = -ESRCH; | 104 | return -ESRCH; |
107 | 105 | ||
108 | return rc; | 106 | return rc; |
109 | } | 107 | } |
@@ -287,15 +285,14 @@ out2: | |||
287 | * LSM hook implementation that allocs and transfers uctx spec to | 285 | * LSM hook implementation that allocs and transfers uctx spec to |
288 | * xfrm_policy. | 286 | * xfrm_policy. |
289 | */ | 287 | */ |
290 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, | 288 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
291 | struct xfrm_user_sec_ctx *uctx) | 289 | struct xfrm_user_sec_ctx *uctx) |
292 | { | 290 | { |
293 | int err; | 291 | int err; |
294 | 292 | ||
295 | BUG_ON(!xp); | ||
296 | BUG_ON(!uctx); | 293 | BUG_ON(!uctx); |
297 | 294 | ||
298 | err = selinux_xfrm_sec_ctx_alloc(&xp->security, uctx, 0); | 295 | err = selinux_xfrm_sec_ctx_alloc(ctxp, uctx, 0); |
299 | if (err == 0) | 296 | if (err == 0) |
300 | atomic_inc(&selinux_xfrm_refcount); | 297 | atomic_inc(&selinux_xfrm_refcount); |
301 | 298 | ||
@@ -307,32 +304,29 @@ int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, | |||
307 | * LSM hook implementation that copies security data structure from old to | 304 | * LSM hook implementation that copies security data structure from old to |
308 | * new for policy cloning. | 305 | * new for policy cloning. |
309 | */ | 306 | */ |
310 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 307 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
308 | struct xfrm_sec_ctx **new_ctxp) | ||
311 | { | 309 | { |
312 | struct xfrm_sec_ctx *old_ctx, *new_ctx; | 310 | struct xfrm_sec_ctx *new_ctx; |
313 | |||
314 | old_ctx = old->security; | ||
315 | 311 | ||
316 | if (old_ctx) { | 312 | if (old_ctx) { |
317 | new_ctx = new->security = kmalloc(sizeof(*new_ctx) + | 313 | new_ctx = kmalloc(sizeof(*old_ctx) + old_ctx->ctx_len, |
318 | old_ctx->ctx_len, | 314 | GFP_KERNEL); |
319 | GFP_KERNEL); | ||
320 | |||
321 | if (!new_ctx) | 315 | if (!new_ctx) |
322 | return -ENOMEM; | 316 | return -ENOMEM; |
323 | 317 | ||
324 | memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); | 318 | memcpy(new_ctx, old_ctx, sizeof(*new_ctx)); |
325 | memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); | 319 | memcpy(new_ctx->ctx_str, old_ctx->ctx_str, new_ctx->ctx_len); |
320 | *new_ctxp = new_ctx; | ||
326 | } | 321 | } |
327 | return 0; | 322 | return 0; |
328 | } | 323 | } |
329 | 324 | ||
330 | /* | 325 | /* |
331 | * LSM hook implementation that frees xfrm_policy security information. | 326 | * LSM hook implementation that frees xfrm_sec_ctx security information. |
332 | */ | 327 | */ |
333 | void selinux_xfrm_policy_free(struct xfrm_policy *xp) | 328 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
334 | { | 329 | { |
335 | struct xfrm_sec_ctx *ctx = xp->security; | ||
336 | if (ctx) | 330 | if (ctx) |
337 | kfree(ctx); | 331 | kfree(ctx); |
338 | } | 332 | } |
@@ -340,10 +334,9 @@ void selinux_xfrm_policy_free(struct xfrm_policy *xp) | |||
340 | /* | 334 | /* |
341 | * LSM hook implementation that authorizes deletion of labeled policies. | 335 | * LSM hook implementation that authorizes deletion of labeled policies. |
342 | */ | 336 | */ |
343 | int selinux_xfrm_policy_delete(struct xfrm_policy *xp) | 337 | int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
344 | { | 338 | { |
345 | struct task_security_struct *tsec = current->security; | 339 | struct task_security_struct *tsec = current->security; |
346 | struct xfrm_sec_ctx *ctx = xp->security; | ||
347 | int rc = 0; | 340 | int rc = 0; |
348 | 341 | ||
349 | if (ctx) { | 342 | if (ctx) { |