Re: [PATCH] xfrm: serialize state GC with device state flush
Steffen Klassert <[email protected]>
| Newsgroups | org.kernel.vger.linux-kernel,org.kernel.vger.netdev,org.kernel.vger.stable |
|---|---|
| Message-ID | <[email protected]> |
On Thu, Jul 30, 2026 at 06:35:43PM +0800, Chengfeng Ye wrote:
> The deferred-device pass in xfrm_dev_state_flush() finds states under
> xfrm_state_dev_gc_lock, but drops the lock before calling
> xfrm_dev_state_free() because the driver callback may sleep. The device
> GC list does not hold an xfrm_state reference, so the state GC worker can
> destroy the same state concurrently.
>
> The race can proceed as follows:
>
> CPU 0 CPU 1
> find x on the device GC list
> drop xfrm_state_dev_gc_lock
> read x->xso.dev
> xfrm_state_gc_destroy(x)
> xfrm_dev_state_free(x)
> xfrm_state_free(x)
> continue xfrm_dev_state_free(x)
>
> Both paths can invoke the driver callback and drop the device reference.
> CPU 0 can also access the xfrm_state after CPU 1 has freed it.
>
> KASAN reported:
>
> BUG: KASAN: slab-use-after-free in xfrm_dev_state_free+0x24c/0x2a0
> Read of size 8 at addr ffff88810bbaa960 by task poc/102
>
> Call Trace:
> xfrm_dev_state_free+0x24c/0x2a0
> xfrm_dev_state_flush+0x353/0x400
> xfrm_dev_event+0x26d/0x3a0
> notifier_call_chain+0xc0/0x280
> __dev_notify_flags+0x169/0x250
> netif_change_flags+0xe7/0x160
> dev_change_flags+0x96/0x220
> devinet_ioctl+0x7f4/0x1880
>
> Allocated by task 87:
> xfrm_state_alloc+0x1e/0x5c0
> xfrm_add_sa+0xe7f/0x5820
> xfrm_user_rcv_msg+0x4f3/0x940
>
> Freed by task 57:
> kmem_cache_free+0xcb/0x3d0
> xfrm_state_gc_task+0x4a8/0x650
> process_one_work+0x63a/0x1070
>
> Serialize xfrm_state destruction against the deferred-device pass with a
> mutex. Keep xfrm_state_dev_gc_lock limited to list operations and retain
> the existing callback and device-reference release ordering.
>
> Fixes: 07b87f9eea0c ("xfrm: Fix unregister netdevice hang on hardware offload.")
> Cc: [email protected]
> Signed-off-by: Chengfeng Ye <[email protected]>
Applied to the ipsec tree, thanks!