dst: Clone child entry in skb_dst_pop
authorSteffen Klassert <steffen.klassert@secunet.com>
Tue, 15 Mar 2011 21:09:32 +0000 (21:09 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 28 Mar 2011 00:55:01 +0000 (17:55 -0700)
We clone the child entry in skb_dst_pop before we call
skb_dst_drop(). Otherwise we might kill the child right
before we return it to the caller.

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

index 2a46cbaef92d30dd7c890deb34a9554634eb94b5..75b95df4afe71467bb9d378f5535ab1e167772df 100644 (file)
@@ -345,7 +345,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
 
 static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
 {
-       struct dst_entry *child = skb_dst(skb)->child;
+       struct dst_entry *child = dst_clone(skb_dst(skb)->child);
 
        skb_dst_drop(skb);
        return child;
index 8f3f0eedc5a4672565fdd6fa105cd62730df68ba..47bacd8c025094e24b0200bab9a7c1d438093aa1 100644 (file)
@@ -96,7 +96,7 @@ resume:
                        err = -EHOSTUNREACH;
                        goto error_nolock;
                }
-               skb_dst_set(skb, dst_clone(dst));
+               skb_dst_set(skb, dst);
                x = dst->xfrm;
        } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));