diff --git a/include/net/route.h b/include/net/route.h index 08e689f23365e4609694b7d3462686f591f4f6cc..cb0a76d9dde17bc77d1b1db853b32d69bfa5f5c5 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -190,7 +190,9 @@ static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src, rcu_read_lock(); err = ip_route_input_noref(skb, dst, src, tos, devin); if (!err) - skb_dst_force(skb); + skb_dst_force_safe(skb); + if (!skb_dst(skb)) + err = -EINVAL; rcu_read_unlock(); return err; diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d986d80258d29facae23839e702d6fa49983ca55..903a12c601ac349a6cdee5a3bfb8a7c309d6f1cb 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2234,10 +2234,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res, rth = rcu_dereference(*prth); rt_cache: - if (rt_cache_valid(rth)) { - dst_hold(&rth->dst); + if (rt_cache_valid(rth) && dst_hold_safe(&rth->dst)) return rth; - } } add: