]> git.baikalelectronics.ru Git - kernel.git/commitdiff
ipv6: Fix nexthop refcnt leak when creating ipv6 route info
authorXiyu Yang <xiyuyang19@fudan.edu.cn>
Sat, 25 Jul 2020 08:02:18 +0000 (16:02 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 29 Jul 2020 00:24:08 +0000 (17:24 -0700)
ip6_route_info_create() invokes nexthop_get(), which increases the
refcount of the "nh".

When ip6_route_info_create() returns, local variable "nh" becomes
invalid, so the refcount should be decreased to keep refcount balanced.

The reference counting issue happens in one exception handling path of
ip6_route_info_create(). When nexthops can not be used with source
routing, the function forgets to decrease the refcnt increased by
nexthop_get(), causing a refcnt leak.

Fix this issue by pulling up the error source routing handling when
nexthops can not be used with source routing.

Fixes: b6b1bd779ad2 ("ipv6: Plumb support for nexthop object in a fib6_info")
Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/route.c

index f3279810d76523bcfc4ea0ce7e59f1ba6655340c..4c36bd0c7930fbb10190c60b1415430520cad56b 100644 (file)
@@ -3685,14 +3685,14 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
        rt->fib6_src.plen = cfg->fc_src_len;
 #endif
        if (nh) {
-               if (!nexthop_get(nh)) {
-                       NL_SET_ERR_MSG(extack, "Nexthop has been deleted");
-                       goto out;
-               }
                if (rt->fib6_src.plen) {
                        NL_SET_ERR_MSG(extack, "Nexthops can not be used with source routing");
                        goto out;
                }
+               if (!nexthop_get(nh)) {
+                       NL_SET_ERR_MSG(extack, "Nexthop has been deleted");
+                       goto out;
+               }
                rt->nh = nh;
                fib6_nh = nexthop_fib6_nh(rt->nh);
        } else {