mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-10-31 14:23:49 +01:00
ipv6: avoid divide by zero in rt6_multipath_rebalance
rt6_multipath_rebalance() calculates the total eligible nexthop weight
in one pass and programs upper bounds in a second pass. Since
RTM_NEWROUTE is RTNL-free, a concurrent
ignore_routes_with_linkdown update can make the first pass return zero
while the second sees an eligible nexthop, causing
rt6_upper_bound_set() to divide by zero.
UBSAN: division-overflow in net/ipv6/route.c:4845:17
Oops: divide error: 0000 [#1] SMP KASAN NOPTI
rt6_upper_bound_set() net/ipv6/route.c:4845
rt6_multipath_rebalance()
fib6_add_rt2node()
ip6_route_multipath_add()
inet6_rtm_newroute()
Skip upper-bound calculation when the first pass reports a zero total.
This respects the lock-free performance considerations here and solves
insecure scenarios.
Fixes: bd11ff421d ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.")
Reported-by: [email protected]
Reported-by: Xiang Mei (Microsoft) <[email protected]>
Reported-by: Cen Zhang (Microsoft) <[email protected]>
Signed-off-by: Cen Zhang (Microsoft) <[email protected]>
Reviewed-by: Ido Schimmel <[email protected]>
Link: https://patch.msgid.link/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
This commit is contained in:
1 parent
07e98a4d5e
commit
d2c26c2911
1 file changed
+1
-1
+1
-1
@@ -4852,7 +4852,7 @@ static void rt6_upper_bound_set(struct fib6_info *rt, int *weight, int total)
|
||||
{
|
||||
int upper_bound = -1;
|
||||
|
||||
if (!rt6_is_dead(rt)) {
|
||||
if (total && !rt6_is_dead(rt)) {
|
||||
*weight += rt->fib6_nh->fib_nh_weight;
|
||||
upper_bound = DIV_ROUND_CLOSEST_ULL((u64) (*weight) << 31,
|
||||
total) - 1;
|
||||
|
||||
Reference in new issue
Block a user