xfrm: Force a dst refcount before entering the xfrm type handlers
authorSteffen Klassert <steffen.klassert@secunet.com>
Tue, 15 Mar 2011 21:08:28 +0000 (21:08 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Mar 2011 00:55:01 +0000 (17:55 -0700)
Crypto requests might return asynchronous. In this case we leave
the rcu protected region, so force a refcount on the skb's
destination entry before we enter the xfrm type input/output
handlers.

This fixes a crash when a route is deleted whilst sending IPsec
data that is transformed by an asynchronous algorithm.

Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c

index 872065ca7f8c8ade85d3d5edd90682bab8a23e3b..341cd1189f8a5b7aa90093707825f7cdac3b05b2 100644 (file)
@@ -190,6 +190,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
                XFRM_SKB_CB(skb)->seq.input.low = seq;
                XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
 
+               skb_dst_force(skb);
+
                nexthdr = x->type->input(x, skb);
 
                if (nexthdr == -EINPROGRESS)
index 1aba03f449cc889098fc33710692e0c1b1518c3c..8f3f0eedc5a4672565fdd6fa105cd62730df68ba 100644 (file)
@@ -78,6 +78,8 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
 
                spin_unlock_bh(&x->lock);
 
+               skb_dst_force(skb);
+
                err = x->type->output(x, skb);
                if (err == -EINPROGRESS)
                        goto out_exit;