summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaber@trash.net <kaber@trash.net>2005-04-07 11:31:38 -0700
committerGreg KH <gregkh@suse.de>2005-05-12 10:00:19 -0700
commit92ef2364e62254d5a36d30ffc7f447ac5358b06e (patch)
tree5ae4460c36a16d1969cd2d2508a4092926bad3e7
parent82e59799aa57d2471333bf9ebbc9b4b2226b9790 (diff)
downloadlinux-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.c12
-rw-r--r--net/ipv6/xfrm6_output.c12
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);