diff options
author | David S. Miller <davem@davemloft.net> | 2014-03-18 12:42:33 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-18 12:42:33 -0400 |
commit | 72c2dfdefa42c747c8e61f3d3ebfafc8e8d5762f (patch) | |
tree | 36ffd7b181a7b72fe02015014086001e440a043d /net | |
parent | b085f311e85b1d6f75d610097c2f20583b776fda (diff) | |
parent | 52a4c6404f91f2d2c5592ee6365a8418c4565f53 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec
Steffen Klassert says:
====================
1) Fix a sleep in atomic when pfkey_sadb2xfrm_user_sec_ctx()
is called from pfkey_compile_policy().
Fix from Nikolay Aleksandrov.
2) security_xfrm_policy_alloc() can be called in process and atomic
context. Add an argument to let the callers choose the appropriate
way. Fix from Nikolay Aleksandrov.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/key/af_key.c | 19 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 6 |
2 files changed, 13 insertions, 12 deletions
diff --git a/net/key/af_key.c b/net/key/af_key.c index 1a04c1329362..79326978517a 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -433,12 +433,13 @@ static inline int verify_sec_ctx_len(const void *p) | |||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
435 | 435 | ||
436 | static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(const struct sadb_x_sec_ctx *sec_ctx) | 436 | static inline struct xfrm_user_sec_ctx *pfkey_sadb2xfrm_user_sec_ctx(const struct sadb_x_sec_ctx *sec_ctx, |
437 | gfp_t gfp) | ||
437 | { | 438 | { |
438 | struct xfrm_user_sec_ctx *uctx = NULL; | 439 | struct xfrm_user_sec_ctx *uctx = NULL; |
439 | int ctx_size = sec_ctx->sadb_x_ctx_len; | 440 | int ctx_size = sec_ctx->sadb_x_ctx_len; |
440 | 441 | ||
441 | uctx = kmalloc((sizeof(*uctx)+ctx_size), GFP_KERNEL); | 442 | uctx = kmalloc((sizeof(*uctx)+ctx_size), gfp); |
442 | 443 | ||
443 | if (!uctx) | 444 | if (!uctx) |
444 | return NULL; | 445 | return NULL; |
@@ -1124,7 +1125,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net, | |||
1124 | 1125 | ||
1125 | sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1]; | 1126 | sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1]; |
1126 | if (sec_ctx != NULL) { | 1127 | if (sec_ctx != NULL) { |
1127 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | 1128 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_KERNEL); |
1128 | 1129 | ||
1129 | if (!uctx) | 1130 | if (!uctx) |
1130 | goto out; | 1131 | goto out; |
@@ -2231,14 +2232,14 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_ | |||
2231 | 2232 | ||
2232 | sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1]; | 2233 | sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1]; |
2233 | if (sec_ctx != NULL) { | 2234 | if (sec_ctx != NULL) { |
2234 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | 2235 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_KERNEL); |
2235 | 2236 | ||
2236 | if (!uctx) { | 2237 | if (!uctx) { |
2237 | err = -ENOBUFS; | 2238 | err = -ENOBUFS; |
2238 | goto out; | 2239 | goto out; |
2239 | } | 2240 | } |
2240 | 2241 | ||
2241 | err = security_xfrm_policy_alloc(&xp->security, uctx); | 2242 | err = security_xfrm_policy_alloc(&xp->security, uctx, GFP_KERNEL); |
2242 | kfree(uctx); | 2243 | kfree(uctx); |
2243 | 2244 | ||
2244 | if (err) | 2245 | if (err) |
@@ -2335,12 +2336,12 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa | |||
2335 | 2336 | ||
2336 | sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1]; | 2337 | sec_ctx = ext_hdrs[SADB_X_EXT_SEC_CTX - 1]; |
2337 | if (sec_ctx != NULL) { | 2338 | if (sec_ctx != NULL) { |
2338 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | 2339 | struct xfrm_user_sec_ctx *uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_KERNEL); |
2339 | 2340 | ||
2340 | if (!uctx) | 2341 | if (!uctx) |
2341 | return -ENOMEM; | 2342 | return -ENOMEM; |
2342 | 2343 | ||
2343 | err = security_xfrm_policy_alloc(&pol_ctx, uctx); | 2344 | err = security_xfrm_policy_alloc(&pol_ctx, uctx, GFP_KERNEL); |
2344 | kfree(uctx); | 2345 | kfree(uctx); |
2345 | if (err) | 2346 | if (err) |
2346 | return err; | 2347 | return err; |
@@ -3239,8 +3240,8 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
3239 | } | 3240 | } |
3240 | if ((*dir = verify_sec_ctx_len(p))) | 3241 | if ((*dir = verify_sec_ctx_len(p))) |
3241 | goto out; | 3242 | goto out; |
3242 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx); | 3243 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_ATOMIC); |
3243 | *dir = security_xfrm_policy_alloc(&xp->security, uctx); | 3244 | *dir = security_xfrm_policy_alloc(&xp->security, uctx, GFP_ATOMIC); |
3244 | kfree(uctx); | 3245 | kfree(uctx); |
3245 | 3246 | ||
3246 | if (*dir) | 3247 | if (*dir) |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index c274179d60a2..2f7ddc3a59b4 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1221,7 +1221,7 @@ static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs | |||
1221 | return 0; | 1221 | return 0; |
1222 | 1222 | ||
1223 | uctx = nla_data(rt); | 1223 | uctx = nla_data(rt); |
1224 | return security_xfrm_policy_alloc(&pol->security, uctx); | 1224 | return security_xfrm_policy_alloc(&pol->security, uctx, GFP_KERNEL); |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 1227 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, |
@@ -1626,7 +1626,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1626 | if (rt) { | 1626 | if (rt) { |
1627 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1627 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1628 | 1628 | ||
1629 | err = security_xfrm_policy_alloc(&ctx, uctx); | 1629 | err = security_xfrm_policy_alloc(&ctx, uctx, GFP_KERNEL); |
1630 | if (err) | 1630 | if (err) |
1631 | return err; | 1631 | return err; |
1632 | } | 1632 | } |
@@ -1928,7 +1928,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1928 | if (rt) { | 1928 | if (rt) { |
1929 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1929 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1930 | 1930 | ||
1931 | err = security_xfrm_policy_alloc(&ctx, uctx); | 1931 | err = security_xfrm_policy_alloc(&ctx, uctx, GFP_KERNEL); |
1932 | if (err) | 1932 | if (err) |
1933 | return err; | 1933 | return err; |
1934 | } | 1934 | } |