Skip to content

Commit 21ec927

Browse files
mrprekuba-moo
authored andcommitted
net: ipv6: fix panic when IPv4 route references loopback IPv6 nexthop
When a standalone IPv6 nexthop object is created with a loopback device (e.g., "ip -6 nexthop add id 100 dev lo"), fib6_nh_init() misclassifies it as a reject route. This is because nexthop objects have no destination prefix (fc_dst=::), causing fib6_is_reject() to match any loopback nexthop. The reject path skips fib_nh_common_init(), leaving nhc_pcpu_rth_output unallocated. If an IPv4 route later references this nexthop, __mkroute_output() dereferences NULL nhc_pcpu_rth_output and panics. Simplify the check in fib6_nh_init() to only match explicit reject routes (RTF_REJECT) instead of using fib6_is_reject(). The loopback promotion heuristic in fib6_is_reject() is handled separately by ip6_route_info_create_nh(). After this change, the three cases behave as follows: 1. Explicit reject route ("ip -6 route add unreachable 2001:db8::/64"): RTF_REJECT is set, enters reject path, skips fib_nh_common_init(). No behavior change. 2. Implicit loopback reject route ("ip -6 route add 2001:db8::/32 dev lo"): RTF_REJECT is not set, takes normal path, fib_nh_common_init() is called. ip6_route_info_create_nh() still promotes it to reject afterward. nhc_pcpu_rth_output is allocated but unused, which is harmless. 3. Standalone nexthop object ("ip -6 nexthop add id 100 dev lo"): RTF_REJECT is not set, takes normal path, fib_nh_common_init() is called. nhc_pcpu_rth_output is properly allocated, fixing the crash when IPv4 routes reference this nexthop. Suggested-by: Ido Schimmel <[email protected]> Fixes: 493ced1 ("ipv4: Allow routes to use nexthop objects") Reported-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/T/ Signed-off-by: Jiayuan Chen <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Reviewed-by: David Ahern <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent 168ff39 commit 21ec927

1 file changed

Lines changed: 3 additions & 5 deletions

File tree

net/ipv6/route.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3583,7 +3583,6 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
35833583
netdevice_tracker *dev_tracker = &fib6_nh->fib_nh_dev_tracker;
35843584
struct net_device *dev = NULL;
35853585
struct inet6_dev *idev = NULL;
3586-
int addr_type;
35873586
int err;
35883587

35893588
fib6_nh->fib_nh_family = AF_INET6;
@@ -3625,11 +3624,10 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
36253624

36263625
fib6_nh->fib_nh_weight = 1;
36273626

3628-
/* We cannot add true routes via loopback here,
3629-
* they would result in kernel looping; promote them to reject routes
3627+
/* Reset the nexthop device to the loopback device in case of reject
3628+
* routes.
36303629
*/
3631-
addr_type = ipv6_addr_type(&cfg->fc_dst);
3632-
if (fib6_is_reject(cfg->fc_flags, dev, addr_type)) {
3630+
if (cfg->fc_flags & RTF_REJECT) {
36333631
/* hold loopback dev/idev if we haven't done so. */
36343632
if (dev != net->loopback_dev) {
36353633
if (dev) {

0 commit comments

Comments
 (0)