diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2007-12-19 01:14:25 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:59:13 -0500 |
commit | 910ef70aa301eb018255683499b8e51426c213a0 (patch) | |
tree | ccde31a2c581c1f9ddea0c482f22ce72a9293f0e /net/xfrm/xfrm_output.c | |
parent | 33b8e776056202aceaf4c90f465d0f4ee53432ac (diff) |
[IPSEC]: Do xfrm_state_check_space before encapsulation
While merging the IPsec output path I moved the encapsulation output
operation to the top of the loop so that it sits outside of the locked
section. Unfortunately in doing so it now sits in front of the space
check as well which could be a fatal error.
This patch rearranges the calls so that the space check happens as
the thing on the output path.
This patch also fixes an incorrect goto should the encapsulation output
fail.
Thanks to Kazunori MIYAZAWA for finding this bug.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm/xfrm_output.c')
-rw-r--r-- | net/xfrm/xfrm_output.c | 18 |
1 files changed, 6 insertions, 12 deletions
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 3c277a4d0e78..26fa0cb78c94 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
@@ -33,16 +33,6 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb) | |||
33 | return 0; | 33 | return 0; |
34 | } | 34 | } |
35 | 35 | ||
36 | static int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb) | ||
37 | { | ||
38 | int err = xfrm_state_check_expire(x); | ||
39 | if (err < 0) | ||
40 | goto err; | ||
41 | err = xfrm_state_check_space(x, skb); | ||
42 | err: | ||
43 | return err; | ||
44 | } | ||
45 | |||
46 | static int xfrm_output_one(struct sk_buff *skb, int err) | 36 | static int xfrm_output_one(struct sk_buff *skb, int err) |
47 | { | 37 | { |
48 | struct dst_entry *dst = skb->dst; | 38 | struct dst_entry *dst = skb->dst; |
@@ -52,12 +42,16 @@ static int xfrm_output_one(struct sk_buff *skb, int err) | |||
52 | goto resume; | 42 | goto resume; |
53 | 43 | ||
54 | do { | 44 | do { |
45 | err = xfrm_state_check_space(x, skb); | ||
46 | if (err) | ||
47 | goto error_nolock; | ||
48 | |||
55 | err = x->outer_mode->output(x, skb); | 49 | err = x->outer_mode->output(x, skb); |
56 | if (err) | 50 | if (err) |
57 | goto error; | 51 | goto error_nolock; |
58 | 52 | ||
59 | spin_lock_bh(&x->lock); | 53 | spin_lock_bh(&x->lock); |
60 | err = xfrm_state_check(x, skb); | 54 | err = xfrm_state_check_expire(x); |
61 | if (err) | 55 | if (err) |
62 | goto error; | 56 | goto error; |
63 | 57 | ||