diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-10-09 16:31:47 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-10-10 19:55:02 -0400 |
commit | 050f009e16f908932070313c1745d09dc69fd62b (patch) | |
tree | 2176b8034065bf2e8b401865efcfaab912bb1997 /net/xfrm | |
parent | 68325d3b12ad5bce650c2883bb878257f197efff (diff) |
[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.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 2cbbe5e93a7b..5238f6a8dfad 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, | |||
507 | struct xfrm_usersa_info *p, | 507 | struct xfrm_usersa_info *p, |
508 | struct sk_buff *skb) | 508 | struct sk_buff *skb) |
509 | { | 509 | { |
510 | spin_lock_bh(&x->lock); | ||
510 | copy_to_user_state(x, p); | 511 | copy_to_user_state(x, p); |
511 | 512 | ||
513 | if (x->coaddr) | ||
514 | NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr); | ||
515 | |||
516 | if (x->lastused) | ||
517 | NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused); | ||
518 | spin_unlock_bh(&x->lock); | ||
519 | |||
512 | if (x->aalg) | 520 | if (x->aalg) |
513 | NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg); | 521 | NLA_PUT(skb, XFRMA_ALG_AUTH, alg_len(x->aalg), x->aalg); |
514 | if (x->ealg) | 522 | if (x->ealg) |
@@ -522,12 +530,6 @@ static int copy_to_user_state_extra(struct xfrm_state *x, | |||
522 | if (x->security && copy_sec_ctx(x->security, skb) < 0) | 530 | if (x->security && copy_sec_ctx(x->security, skb) < 0) |
523 | goto nla_put_failure; | 531 | goto nla_put_failure; |
524 | 532 | ||
525 | if (x->coaddr) | ||
526 | NLA_PUT(skb, XFRMA_COADDR, sizeof(*x->coaddr), x->coaddr); | ||
527 | |||
528 | if (x->lastused) | ||
529 | NLA_PUT_U64(skb, XFRMA_LASTUSED, x->lastused); | ||
530 | |||
531 | return 0; | 533 | return 0; |
532 | 534 | ||
533 | nla_put_failure: | 535 | nla_put_failure: |