]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
[PATCH] Do not hold state lock while checking size
authorkaber@trash.net <kaber@trash.net>
Thu, 7 Apr 2005 18:31:38 +0000 (11:31 -0700)
committerGreg KH <gregkh@suse.de>
Thu, 12 May 2005 17:00:19 +0000 (10:00 -0700)
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>
net/ipv4/xfrm4_output.c
net/ipv6/xfrm6_output.c

index 3c70b08f908c0af1f04e84286cca32899f2a68ce..88fd283e20be16e10e71023bf93c31e992321189 100644 (file)
@@ -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);
index b06b11c960bbcac0b25cf809c386f89233e16f2d..172dd8f10190e9a11a1af6eb8e85d108a752542d 100644 (file)
@@ -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);