summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2019-09-24 10:01:28 -0400
committerDavid S. Miller <davem@davemloft.net>2019-09-26 03:34:25 -0400
commitca7a03c4175366a92cee0ccc4fec0038c3266e26 (patch)
treeaf1034612ac5d258235529d3126c045bbfe0b570
parentea8564c865299815095bebeb4b25bef474218e4c (diff)
ipv6: do not free rt if FIB_LOOKUP_NOREF is set on suppress rule
Commit 7d9e5f422150 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: 7d9e5f422150 ("ipv6: convert major tx path to use RT6_LOOKUP_F_DST_NOREF") Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Acked-by: Wei Wang <weiwan@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv6/fib6_rules.c3
-rwxr-xr-xtools/testing/selftests/net/fib_tests.sh17
2 files changed, 18 insertions, 2 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index d22b6c140f23..f9e8fe3ff0c5 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -287,7 +287,8 @@ static bool fib6_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg
287 return false; 287 return false;
288 288
289suppress_route: 289suppress_route:
290 ip6_rt_put(rt); 290 if (!(arg->flags & FIB_LOOKUP_NOREF))
291 ip6_rt_put(rt);
291 return true; 292 return true;
292} 293}
293 294
diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
index cba83a12da82..c4ba0ff4a53f 100755
--- a/tools/testing/selftests/net/fib_tests.sh
+++ b/tools/testing/selftests/net/fib_tests.sh
@@ -9,7 +9,7 @@ ret=0
9ksft_skip=4 9ksft_skip=4
10 10
11# all tests in this script. Can be overridden with -t option 11# all tests in this script. Can be overridden with -t option
12TESTS="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" 12TESTS="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"
13 13
14VERBOSE=0 14VERBOSE=0
15PAUSE_ON_FAIL=no 15PAUSE_ON_FAIL=no
@@ -616,6 +616,20 @@ fib_nexthop_test()
616 cleanup 616 cleanup
617} 617}
618 618
619fib_suppress_test()
620{
621 $IP link add dummy1 type dummy
622 $IP link set dummy1 up
623 $IP -6 route add default dev dummy1
624 $IP -6 rule add table main suppress_prefixlength 0
625 ping -f -c 1000 -W 1 1234::1 || true
626 $IP -6 rule del table main suppress_prefixlength 0
627 $IP link del dummy1
628
629 # If we got here without crashing, we're good.
630 return 0
631}
632
619################################################################################ 633################################################################################
620# Tests on route add and replace 634# Tests on route add and replace
621 635
@@ -1593,6 +1607,7 @@ do
1593 fib_carrier_test|carrier) fib_carrier_test;; 1607 fib_carrier_test|carrier) fib_carrier_test;;
1594 fib_rp_filter_test|rp_filter) fib_rp_filter_test;; 1608 fib_rp_filter_test|rp_filter) fib_rp_filter_test;;
1595 fib_nexthop_test|nexthop) fib_nexthop_test;; 1609 fib_nexthop_test|nexthop) fib_nexthop_test;;
1610 fib_suppress_test|suppress) fib_suppress_test;;
1596 ipv6_route_test|ipv6_rt) ipv6_route_test;; 1611 ipv6_route_test|ipv6_rt) ipv6_route_test;;
1597 ipv4_route_test|ipv4_rt) ipv4_route_test;; 1612 ipv4_route_test|ipv4_rt) ipv4_route_test;;
1598 ipv6_addr_metric) ipv6_addr_metric_test;; 1613 ipv6_addr_metric) ipv6_addr_metric_test;;