diff options
author | kaber@trash.net <kaber@trash.net> | 2005-04-07 11:31:38 -0700 |
---|---|---|
committer | Greg KH <gregkh@suse.de> | 2005-05-12 10:00:19 -0700 |
commit | 92ef2364e62254d5a36d30ffc7f447ac5358b06e (patch) | |
tree | 5ae4460c36a16d1969cd2d2508a4092926bad3e7 | |
parent | 82e59799aa57d2471333bf9ebbc9b4b2226b9790 (diff) | |
download | linux-stable-92ef2364e62254d5a36d30ffc7f447ac5358b06e.tar.gz linux-stable-92ef2364e62254d5a36d30ffc7f447ac5358b06e.tar.bz2 linux-stable-92ef2364e62254d5a36d30ffc7f447ac5358b06e.zip |
[PATCH] Do not hold state lock while checking size
This patch from Herbert Xu fixes a deadlock with IPsec.
When an ICMP frag. required is sent and the ICMP message
needs the same SA as the packet that caused it the state
will be locked twice.
[IPSEC]: Do not hold state lock while checking size.
This can elicit ICMP message output and thus result in a
deadlock.
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Chris Wright <chrisw@osdl.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | net/ipv4/xfrm4_output.c | 12 | ||||
-rw-r--r-- | net/ipv6/xfrm6_output.c | 12 |
2 files changed, 12 insertions, 12 deletions
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 3c70b08f908c..88fd283e20be 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -103,17 +103,17 @@ int xfrm4_output(struct sk_buff *skb) goto error_nolock; } - spin_lock_bh(&x->lock); - err = xfrm_state_check(x, skb); - if (err) - goto error; - if (x->props.mode) { err = xfrm4_tunnel_check_size(skb); if (err) - goto error; + goto error_nolock; } + spin_lock_bh(&x->lock); + err = xfrm_state_check(x, skb); + if (err) + goto error; + xfrm4_encap(skb); err = x->type->output(skb); diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index b06b11c960bb..172dd8f10190 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c @@ -103,17 +103,17 @@ int xfrm6_output(struct sk_buff *skb) goto error_nolock; } - spin_lock_bh(&x->lock); - err = xfrm_state_check(x, skb); - if (err) - goto error; - if (x->props.mode) { err = xfrm6_tunnel_check_size(skb); if (err) - goto error; + goto error_nolock; } + spin_lock_bh(&x->lock); + err = xfrm_state_check(x, skb); + if (err) + goto error; + xfrm6_encap(skb); err = x->type->output(skb); |