Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: mana: fix use-after-free in mana_hwc_destroy_channel() by reordering teardown

A potential race condition exists in mana_hwc_destroy_channel() where
hwc->caller_ctx is freed before the HWC's Completion Queue (CQ) and
Event Queue (EQ) are destroyed. This allows an in-flight CQ interrupt
handler to dereference freed memory, leading to a use-after-free or
NULL pointer dereference in mana_hwc_handle_resp().

mana_smc_teardown_hwc() signals the hardware to stop but does not
synchronize against IRQ handlers already executing on other CPUs. The
IRQ synchronization only happens in mana_hwc_destroy_cq() via
mana_gd_destroy_eq() -> mana_gd_deregister_irq(). Since this runs
after kfree(hwc->caller_ctx), a concurrent mana_hwc_rx_event_handler()
can dereference freed caller_ctx (and rxq->msg_buf) in
mana_hwc_handle_resp().

Fix this by reordering teardown to reverse-of-creation order: destroy
the TX/RX work queues and CQ/EQ before freeing hwc->caller_ctx. This
ensures all in-flight interrupt handlers complete before the memory they
access is freed.

Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network Adapter (MANA)")
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: Dipayaan Roy <dipayanroy@linux.microsoft.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/abHA3AjNtqa1nx9k@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Dipayaan Roy and committed by
Jakub Kicinski
fa103fc8 6cfc3bc0

+3 -3
+3 -3
drivers/net/ethernet/microsoft/mana/hw_channel.c
··· 814 814 gc->max_num_cqs = 0; 815 815 } 816 816 817 - kfree(hwc->caller_ctx); 818 - hwc->caller_ctx = NULL; 819 - 820 817 if (hwc->txq) 821 818 mana_hwc_destroy_wq(hwc, hwc->txq); 822 819 ··· 822 825 823 826 if (hwc->cq) 824 827 mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq); 828 + 829 + kfree(hwc->caller_ctx); 830 + hwc->caller_ctx = NULL; 825 831 826 832 mana_gd_free_res_map(&hwc->inflight_msg_res); 827 833