aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Moore <paul.moore@hp.com>2008-04-12 22:07:52 -0400
committerDavid S. Miller <davem@davemloft.net>2008-04-12 22:07:52 -0400
commit03e1ad7b5d871d4189b1da3125c2f12d1b5f7d0b (patch)
tree1e7f291ac6bd0c1f3a95e8252c32fcce7ff47ea7
parent00447872a643787411c2c0cb1df6169dda8b0c47 (diff)
LSM: Make the Labeled IPsec hooks more stack friendly
The xfrm_get_policy() and xfrm_add_pol_expire() put some rather large structs on the stack to work around the LSM API. This patch attempts to fix that problem by changing the LSM API to require only the relevant "security" pointers instead of the entire SPD entry; we do this for all of the security_xfrm_policy*() functions to keep things consistent. Signed-off-by: Paul Moore <paul.moore@hp.com> Acked-by: James Morris <jmorris@namei.org> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/security.h48
-rw-r--r--net/key/af_key.c23
-rw-r--r--net/xfrm/xfrm_policy.c24
-rw-r--r--net/xfrm/xfrm_user.c33
-rw-r--r--security/dummy.c14
-rw-r--r--security/security.c21
-rw-r--r--security/selinux/include/xfrm.h13
-rw-r--r--security/selinux/xfrm.c39
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
2565int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); 2565int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx);
2566int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); 2566int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp);
2567void security_xfrm_policy_free(struct xfrm_policy *xp); 2567void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
2568int security_xfrm_policy_delete(struct xfrm_policy *xp); 2568int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
2569int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); 2569int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
2570int security_xfrm_state_alloc_acquire(struct xfrm_state *x, 2570int 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);
2572int security_xfrm_state_delete(struct xfrm_state *x); 2572int security_xfrm_state_delete(struct xfrm_state *x);
2573void security_xfrm_state_free(struct xfrm_state *x); 2573void security_xfrm_state_free(struct xfrm_state *x);
2574int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 2574int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
2575int security_xfrm_state_pol_flow_match(struct xfrm_state *x, 2575int 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);
2577int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid); 2577int 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
2582static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) 2582static 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
2587static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 2587static 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
2592static inline void security_xfrm_policy_free(struct xfrm_policy *xp) 2592static inline void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx)
2593{ 2593{
2594} 2594}
2595 2595
2596static inline int security_xfrm_policy_delete(struct xfrm_policy *xp) 2596static 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
2622static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 2622static 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}
269EXPORT_SYMBOL(xfrm_policy_destroy); 269EXPORT_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
965static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, 965static 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
879static int dummy_xfrm_policy_alloc_security(struct xfrm_policy *xp, 879static 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
885static inline int dummy_xfrm_policy_clone_security(struct xfrm_policy *old, struct xfrm_policy *new) 885static 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
890static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp) 891static void dummy_xfrm_policy_free_security(struct xfrm_sec_ctx *ctx)
891{ 892{
892} 893}
893 894
894static int dummy_xfrm_policy_delete_security(struct xfrm_policy *xp) 895static 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
914static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) 915static 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
1017int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) 1017int 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}
1021EXPORT_SYMBOL(security_xfrm_policy_alloc); 1021EXPORT_SYMBOL(security_xfrm_policy_alloc);
1022 1022
1023int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 1023int 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
1028void security_xfrm_policy_free(struct xfrm_policy *xp) 1029void 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}
1032EXPORT_SYMBOL(security_xfrm_policy_free); 1033EXPORT_SYMBOL(security_xfrm_policy_free);
1033 1034
1034int security_xfrm_policy_delete(struct xfrm_policy *xp) 1035int 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
1039int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) 1040int 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
1068int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 1069int 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
1073int security_xfrm_state_pol_flow_match(struct xfrm_state *x, 1074int 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
10int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, 10int 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);
12int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); 12int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx,
13void selinux_xfrm_policy_free(struct xfrm_policy *xp); 13 struct xfrm_sec_ctx **new_ctxp);
14int selinux_xfrm_policy_delete(struct xfrm_policy *xp); 14void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx);
15int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx);
15int selinux_xfrm_state_alloc(struct xfrm_state *x, 16int 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);
17void selinux_xfrm_state_free(struct xfrm_state *x); 18void selinux_xfrm_state_free(struct xfrm_state *x);
18int selinux_xfrm_state_delete(struct xfrm_state *x); 19int selinux_xfrm_state_delete(struct xfrm_state *x);
19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 20int selinux_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir);
20int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 21int 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 */
80int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 80int 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 */
290int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, 288int 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 */
310int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) 307int 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 */
333void selinux_xfrm_policy_free(struct xfrm_policy *xp) 328void 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 */
343int selinux_xfrm_policy_delete(struct xfrm_policy *xp) 337int 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) {