From: kaber@trash.net Date: Thu, 7 Apr 2005 18:31:38 +0000 (-0700) Subject: [PATCH] Do not hold state lock while checking size X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=92ef2364e62254d5a36d30ffc7f447ac5358b06e;p=thirdparty%2Fkernel%2Fstable.git [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 Signed-off-by: David S. Miller Signed-off-by: Chris Wright Signed-off-by: Greg Kroah-Hartman --- diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 3c70b08f908c0..88fd283e20be1 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 b06b11c960bbc..172dd8f10190e 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);