Commit ca7a03c4 authored by Jason A. Donenfeld's avatar Jason A. Donenfeld Committed by David S. Miller

ipv6: do not free rt if FIB_LOOKUP_NOREF is set on suppress rule

Commit 7d9e5f42 removed references from certain dsts, but accounting
for this never translated down into the fib6 suppression code. This bug
was triggered by WireGuard users who use wg-quick(8), which uses the
"suppress-prefix" directive to ip-rule(8) for routing all of their
internet traffic without routing loops. The test case added here
causes the reference underflow by causing packets to evaluate a suppress
rule.

Fixes: 7d9e5f42 ("ipv6: convert major tx path to use RT6_LOOKUP_F_DST_NOREF")
Signed-off-by: default avatarJason A. Donenfeld <Jason@zx2c4.com>
Acked-by: default avatarWei Wang <weiwan@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ea8564c8
...@@ -287,6 +287,7 @@ static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg ...@@ -287,6 +287,7 @@ static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg
return false; return false;
suppress_route: suppress_route:
if (!(arg->flags & FIB_LOOKUP_NOREF))
ip6_rt_put(rt); ip6_rt_put(rt);
return true; return true;
} }
......
...@@ -9,7 +9,7 @@ ret=0 ...@@ -9,7 +9,7 @@ ret=0
ksft_skip=4 ksft_skip=4
# all tests in this script. Can be overridden with -t option # all tests in this script. Can be overridden with -t option
TESTS="unregister down carrier nexthop ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter" TESTS="unregister down carrier nexthop suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter"
VERBOSE=0 VERBOSE=0
PAUSE_ON_FAIL=no PAUSE_ON_FAIL=no
...@@ -616,6 +616,20 @@ fib_nexthop_test() ...@@ -616,6 +616,20 @@ fib_nexthop_test()
cleanup cleanup
} }
fib_suppress_test()
{
$IP link add dummy1 type dummy
$IP link set dummy1 up
$IP -6 route add default dev dummy1
$IP -6 rule add table main suppress_prefixlength 0
ping -f -c 1000 -W 1 1234::1 || true
$IP -6 rule del table main suppress_prefixlength 0
$IP link del dummy1
# If we got here without crashing, we're good.
return 0
}
################################################################################ ################################################################################
# Tests on route add and replace # Tests on route add and replace
...@@ -1593,6 +1607,7 @@ do ...@@ -1593,6 +1607,7 @@ do
fib_carrier_test|carrier) fib_carrier_test;; fib_carrier_test|carrier) fib_carrier_test;;
fib_rp_filter_test|rp_filter) fib_rp_filter_test;; fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
fib_nexthop_test|nexthop) fib_nexthop_test;; fib_nexthop_test|nexthop) fib_nexthop_test;;
fib_suppress_test|suppress) fib_suppress_test;;
ipv6_route_test|ipv6_rt) ipv6_route_test;; ipv6_route_test|ipv6_rt) ipv6_route_test;;
ipv4_route_test|ipv4_rt) ipv4_route_test;; ipv4_route_test|ipv4_rt) ipv4_route_test;;
ipv6_addr_metric) ipv6_addr_metric_test;; ipv6_addr_metric) ipv6_addr_metric_test;;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment