[PATCH net v4 2/4] net: bonding: Fix nd_tbl NULL dereference when IPv6 is disabled

Ricardo B. Marlière posted 4 patches 1 month ago
[PATCH net v4 2/4] net: bonding: Fix nd_tbl NULL dereference when IPv6 is disabled
Posted by Ricardo B. Marlière 1 month ago
When booting with the 'ipv6.disable=1' parameter, the nd_tbl is never
initialized because inet6_init() exits before ndisc_init() is called
which initializes it. If bonding ARP/NS validation is enabled, an IPv6
NS/NA packet received on a slave can reach bond_validate_na(), which
calls bond_has_this_ip6(). That path calls ipv6_chk_addr() and can
crash in __ipv6_chk_addr_and_flags().

 BUG: kernel NULL pointer dereference, address: 00000000000005d8
 Oops: Oops: 0000 [#1] SMP NOPTI
 RIP: 0010:__ipv6_chk_addr_and_flags+0x69/0x170
 Call Trace:
  <IRQ>
  ipv6_chk_addr+0x1f/0x30
  bond_validate_na+0x12e/0x1d0 [bonding]
  ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
  bond_rcv_validate+0x1a0/0x450 [bonding]
  bond_handle_frame+0x5e/0x290 [bonding]
  ? srso_alias_return_thunk+0x5/0xfbef5
  __netif_receive_skb_core.constprop.0+0x3e8/0xe50
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? update_cfs_rq_load_avg+0x1a/0x240
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? __enqueue_entity+0x5e/0x240
  __netif_receive_skb_one_core+0x39/0xa0
  process_backlog+0x9c/0x150
  __napi_poll+0x30/0x200
  ? srso_alias_return_thunk+0x5/0xfbef5
  net_rx_action+0x338/0x3b0
  handle_softirqs+0xc9/0x2a0
  do_softirq+0x42/0x60
  </IRQ>
  <TASK>
  __local_bh_enable_ip+0x62/0x70
  __dev_queue_xmit+0x2d3/0x1000
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? packet_parse_headers+0x10a/0x1a0
  packet_sendmsg+0x10da/0x1700
  ? kick_pool+0x5f/0x140
  ? srso_alias_return_thunk+0x5/0xfbef5
  ? __queue_work+0x12d/0x4f0
  __sys_sendto+0x1f3/0x220
  __x64_sys_sendto+0x24/0x30
  do_syscall_64+0x101/0xf80
  ? exc_page_fault+0x6e/0x170
  ? srso_alias_return_thunk+0x5/0xfbef5
  entry_SYSCALL_64_after_hwframe+0x77/0x7f
  </TASK>

Fix this by checking ipv6_mod_enabled() before dispatching IPv6 packets to
bond_na_rcv(). If IPv6 is disabled, return early from bond_rcv_validate()
and avoid the path to ipv6_chk_addr().

Suggested-by: Fernando Fernandez Mancera <fmancera@suse.de>
Fixes: 4e24be018eb9 ("bonding: add new parameter ns_targets")
Signed-off-by: Ricardo B. Marlière <rbm@suse.com>
---
 drivers/net/bonding/bond_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 14ed91391fcc..33fb5f168cef 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3377,7 +3377,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond,
 	} else if (is_arp) {
 		return bond_arp_rcv(skb, bond, slave);
 #if IS_ENABLED(CONFIG_IPV6)
-	} else if (is_ipv6) {
+	} else if (is_ipv6 && likely(ipv6_mod_enabled())) {
 		return bond_na_rcv(skb, bond, slave);
 #endif
 	} else {

-- 
2.53.0

Re: [PATCH net v4 2/4] net: bonding: Fix nd_tbl NULL dereference when IPv6 is disabled
Posted by Hangbin Liu 1 month ago
On Sat, Mar 07, 2026 at 05:50:54PM -0300, Ricardo B. Marlière wrote:
> When booting with the 'ipv6.disable=1' parameter, the nd_tbl is never
> initialized because inet6_init() exits before ndisc_init() is called
> which initializes it. If bonding ARP/NS validation is enabled, an IPv6
> NS/NA packet received on a slave can reach bond_validate_na(), which
> calls bond_has_this_ip6(). That path calls ipv6_chk_addr() and can
> crash in __ipv6_chk_addr_and_flags().
> 
>  BUG: kernel NULL pointer dereference, address: 00000000000005d8
>  Oops: Oops: 0000 [#1] SMP NOPTI
>  RIP: 0010:__ipv6_chk_addr_and_flags+0x69/0x170
>  Call Trace:
>   <IRQ>
>   ipv6_chk_addr+0x1f/0x30
>   bond_validate_na+0x12e/0x1d0 [bonding]
>   ? __pfx_bond_handle_frame+0x10/0x10 [bonding]
>   bond_rcv_validate+0x1a0/0x450 [bonding]
>   bond_handle_frame+0x5e/0x290 [bonding]
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   __netif_receive_skb_core.constprop.0+0x3e8/0xe50
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   ? update_cfs_rq_load_avg+0x1a/0x240
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   ? __enqueue_entity+0x5e/0x240
>   __netif_receive_skb_one_core+0x39/0xa0
>   process_backlog+0x9c/0x150
>   __napi_poll+0x30/0x200
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   net_rx_action+0x338/0x3b0
>   handle_softirqs+0xc9/0x2a0
>   do_softirq+0x42/0x60
>   </IRQ>
>   <TASK>
>   __local_bh_enable_ip+0x62/0x70
>   __dev_queue_xmit+0x2d3/0x1000
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   ? packet_parse_headers+0x10a/0x1a0
>   packet_sendmsg+0x10da/0x1700
>   ? kick_pool+0x5f/0x140
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   ? __queue_work+0x12d/0x4f0
>   __sys_sendto+0x1f3/0x220
>   __x64_sys_sendto+0x24/0x30
>   do_syscall_64+0x101/0xf80
>   ? exc_page_fault+0x6e/0x170
>   ? srso_alias_return_thunk+0x5/0xfbef5
>   entry_SYSCALL_64_after_hwframe+0x77/0x7f
>   </TASK>
> 
> Fix this by checking ipv6_mod_enabled() before dispatching IPv6 packets to
> bond_na_rcv(). If IPv6 is disabled, return early from bond_rcv_validate()
> and avoid the path to ipv6_chk_addr().
> 
> Suggested-by: Fernando Fernandez Mancera <fmancera@suse.de>
> Fixes: 4e24be018eb9 ("bonding: add new parameter ns_targets")
> Signed-off-by: Ricardo B. Marlière <rbm@suse.com>
> ---
>  drivers/net/bonding/bond_main.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 14ed91391fcc..33fb5f168cef 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -3377,7 +3377,7 @@ int bond_rcv_validate(const struct sk_buff *skb, struct bonding *bond,
>  	} else if (is_arp) {
>  		return bond_arp_rcv(skb, bond, slave);
>  #if IS_ENABLED(CONFIG_IPV6)
> -	} else if (is_ipv6) {
> +	} else if (is_ipv6 && likely(ipv6_mod_enabled())) {
>  		return bond_na_rcv(skb, bond, slave);
>  #endif
>  	} else {
> 
> -- 
> 2.53.0
> 

Reviewed-by: Hangbin Liu <liuhangbin@gmail.com>