From 92ef2364e62254d5a36d30ffc7f447ac5358b06e Mon Sep 17 00:00:00 2001 From: "kaber@trash.net" Date: Thu, 7 Apr 2005 11:31:38 -0700 Subject: [PATCH] [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 --- net/ipv4/xfrm4_output.c | 12 ++++++------ 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 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); -- 2.47.2