Re: [PATCH v2] xfrm: cache the offload ifindex for netlink dumps
From: Steffen Klassert
Date: Mon Jul 06 2026 - 02:18:39 EST
On Sat, Jun 27, 2026 at 11:50:58AM +0800, Cen Zhang wrote:
> copy_to_user_state_extra() only holds a reference to the outer xfrm_state.
> That does not pin x->xso.dev. NETDEV_DOWN and NETDEV_UNREGISTER can race
> through xfrm_dev_state_flush(), xfrm_state_delete(), and
> xfrm_dev_state_free(), which clears xso->dev and drops the netdev
> reference before the GETSA dump reaches xso_to_xuo() and reads
> xso->dev->ifindex.
>
> The buggy scenario involves two paths, with each column showing the order
> within that path:
>
> XFRM_MSG_GETSA dump path: NETDEV teardown path:
> 1. xfrm_get_sa() gets xfrm_state 1. xfrm_dev_state_flush() finds x
> 2. copy_to_user_state_extra() sees 2. xfrm_state_delete() removes x
> x->xso.dev from the SAD
> 3. copy_user_offload() calls 3. xfrm_dev_state_free() clears
> xso_to_xuo() xso->dev
> 4. xso->dev->ifindex dereferences 4. netdev_put() drops the device
> a detached net_device reference
>
> Avoid following the live net_device from the dump paths. Cache the
> attached ifindex in xfrm_dev_offload when state or policy offload is bound
> to a device, and serialize that snapshot instead. This preserves the
> user-visible XFRMA_OFFLOAD_DEV value without depending on the embedded
> net_device lifetime.
>
> Validation reproduced this kernel report:
> Oops: general protection fault
>
> Call Trace:
> <TASK>
> copy_to_user_state_extra+0xb8d/0x1370 [xfrm_user]
> ? __pfx_copy_to_user_state_extra+0x10/0x10 [xfrm_user]
> ? __asan_memset+0x23/0x50
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? __alloc_skb+0x342/0x960
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? __asan_memset+0x23/0x50
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? __nlmsg_put+0x147/0x1b0
> dump_one_state+0x1c7/0x3e0 [xfrm_user]
> xfrm_state_netlink+0xcb/0x130 [xfrm_user]
> ? __pfx_xfrm_state_netlink+0x10/0x10 [xfrm_user]
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? xfrm_user_state_lookup.constprop.0+0x230/0x310 [xfrm_user]
> xfrm_get_sa+0x102/0x250 [xfrm_user]
> ? __pfx_xfrm_get_sa+0x10/0x10 [xfrm_user]
> xfrm_user_rcv_msg+0x504/0xaa0 [xfrm_user]
> ? __pfx_xfrm_user_rcv_msg+0x10/0x10 [xfrm_user]
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? stack_trace_save+0x8e/0xc0
> ? __pfx_stack_trace_save+0x10/0x10
> netlink_rcv_skb+0x11f/0x350
> ? __pfx_xfrm_user_rcv_msg+0x10/0x10 [xfrm_user]
> ? __pfx_netlink_rcv_skb+0x10/0x10
> ? __pfx_mutex_lock+0x10/0x10
> ? srso_alias_return_thunk+0x5/0xfbef5
> xfrm_netlink_rcv+0x65/0x80 [xfrm_user]
> netlink_unicast+0x600/0x870
> ? __pfx_netlink_unicast+0x10/0x10
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? __pfx_stack_trace_save+0x10/0x10
> netlink_sendmsg+0x75d/0xc10
> ? __pfx_netlink_sendmsg+0x10/0x10
> ? srso_alias_return_thunk+0x5/0xfbef5
> ____sys_sendmsg+0x77a/0x900
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? __pfx_____sys_sendmsg+0x10/0x10
> ? __pfx_copy_msghdr_from_user+0x10/0x10
> ? release_sock+0x1a/0x1d0
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? netlink_insert+0x143/0xec0
> ___sys_sendmsg+0xff/0x180
> ? __pfx____sys_sendmsg+0x10/0x10
> ? _raw_spin_lock_irqsave+0x85/0xe0
> ? do_getsockname+0xf9/0x170
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? fdget+0x53/0x3b0
> __sys_sendmsg+0x111/0x1a0
> ? __pfx___sys_sendmsg+0x10/0x10
> ? srso_alias_return_thunk+0x5/0xfbef5
> ? __sys_getsockname+0x8c/0x100
> do_syscall_64+0x102/0x5a0
> entry_SYSCALL_64_after_hwframe+0x77/0x7f
>
> Fixes: 07b87f9eea0c ("xfrm: Fix unregister netdevice hang on hardware offload.")
> Assisted-by: Codex:gpt-5.5
> Signed-off-by: Cen Zhang <zzzccc427@xxxxxxxxx>
Patch applied, thanks a lot!