summaryrefslogtreecommitdiff
path: root/net/xfrm
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-09 13:31:47 -0700
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 16:55:02 -0700
commit050f009e16f908932070313c1745d09dc69fd62b (patch)
tree2176b8034065bf2e8b401865efcfaab912bb1997 /net/xfrm
parent68325d3b12ad5bce650c2883bb878257f197efff (diff)
downloadlinux-3.10-050f009e16f908932070313c1745d09dc69fd62b.tar.gz
linux-3.10-050f009e16f908932070313c1745d09dc69fd62b.tar.bz2
linux-3.10-050f009e16f908932070313c1745d09dc69fd62b.zip
[IPSEC]: Lock state when copying non-atomic fields to user-space
This patch adds locking so that when we're copying non-atomic fields such as life-time or coaddr to user-space we don't get a partial result. For af_key I've changed every instance of pfkey_xfrm_state2msg apart from expiration notification to include the keys and life-times. This is in-line with XFRM behaviour. The actual cases affected are: * pfkey_getspi: No change as we don't have any keys to copy. * key_notify_sa: + ADD/UPD: This wouldn't work otherwise. + DEL: It can't hurt. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_user.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2cbbe5e93a7..5238f6a8dfa 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -507,8 +507,16 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
struct xfrm_usersa_info *p,
struct sk_buff *skb)
{
+ spin_lock_bh(&x->lock);
copy_to_user_state(x, p);
+ if (x->coaddr)
+ NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
+
+ if (x->lastused)
+ NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
+ spin_unlock_bh(&x->lock);
+
if (x->aalg)
NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg);
if (x->ealg)
@@ -522,12 +530,6 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
if (x->security && copy_sec_ctx(x->security, skb) < 0)
goto nla_put_failure;
- if (x->coaddr)
- NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr);
-
- if (x->lastused)
- NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused);
-
return 0;
nla_put_failure: