aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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) {