Re: [PATCH net v5 3/7] net: mana: free HWC comp_buf after destroying the EQ
[email protected] Mon, 10 Aug 2026 19:01:34 +0000
| Newsgroups | org.kernel.vger.linux-hyperv |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: Pre-existing issues: - [Critical] A TOCTOU race condition between the HWC request timeout path and the response interrupt handler allows the handler to perform a `memcpy` into a deallocated stack frame. - [High] Pre-existing use-after-free risk in `mana_hwc_destroy_channel` due to WQs (`txq` and `rxq`) being destroyed before the EQ is safely fenced. - [High] If HWC channel establishment times out, hardware teardown is skipped, allowing the hardware to DMA into freed queue memory. -- --- Patch [3]: [PATCH net v5 3/7] net: mana: free HWC comp_buf after destroying the EQ --- commit 20a39692a14893099232cb3a9085ec258236f7dc Author: Long Li <[email protected]> net: mana: free HWC comp_buf after destroying the EQ mana_hwc_destroy_cq() freed hwc_cq->comp_buf and destroyed the CQ before the EQ. That was unsafe while the EQ was still registered: the EQ interrupt handler reaches comp_buf via mana_hwc_comp_event() and the CQ object (hwc->cq->gdma_cq) via mana_hwc_init_event_handler(), so a late EQE dispatched after the free could touch freed memory. > diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c > index 3f011ebbe7b3e..19896bb5ce1a4 100644 > --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c > +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c > @@ -384,14 +384,24 @@ static void mana_hwc_comp_event(void *ctx, struct gdma_queue *q_self) > > static void mana_hwc_destroy_cq(struct gdma_context *gc, struct hwc_cq *hwc_cq) > { > - kfree(hwc_cq->comp_buf); > + /* Destroy the EQ before the CQ. mana_gd_destroy_queue() on the EQ > + * deregisters its IRQ and waits out in-flight handlers, fencing all > + * EQE dispatch — both the completion path and HWC init/reconfig > + * events. Freeing the CQ first would leave the EQ live and able to > + * dispatch an event that dereferences hwc->cq->gdma_cq (e.g. > + * mana_hwc_init_event_handler()) after it has been freed. > + */ > + if (hwc_cq->gdma_eq) > + mana_gd_destroy_queue(gc, hwc_cq->gdma_eq); [Severity: High] This isn't a bug introduced by this patch, but while checking the teardown ordering, could there be a similar use-after-free risk for the WQs? In mana_hwc_destroy_channel(), the WQs are destroyed before the EQ is safely fenced by mana_hwc_destroy_cq(): drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_destroy_channel() { ... mana_hwc_destroy_wq(hwc, hwc->rxq); mana_hwc_destroy_wq(hwc, hwc->txq); mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq); ... } If an in-flight EQ interrupt handler runs during this window, it will invoke mana_hwc_comp_event(), which calls mana_hwc_rx_event_handler(). The handler blindly dereferences the freed hwc->rxq: drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_rx_event_handler() { ... if (WARN_ON_ONCE(hwc_rxq->gdma_wq->id != gdma_rxq_id)) ... } Will this cause a use-after-free if an interrupt arrives after the WQs are freed but before mana_hwc_destroy_cq() fences the EQ? [Severity: High] This is a pre-existing issue, but does skipping hardware teardown on a timeout lead to DMA into freed memory? In mana_hwc_establish_channel(), if hardware initialization times out: drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_establish_channel() { ... if (!wait_for_completion_timeout(&hwc->hwc_init_eqe_comp, 60 * HZ)) return -ETIMEDOUT; ... } The hardware channel remains active while gc->max_num_cqs remains 0. When the error path calls mana_hwc_destroy_channel(), the teardown is skipped: drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_destroy_channel() { ... if (gc->max_num_cqs > 0) mana_smc_teardown_hwc(&gc->shm_channel, false); ... } Since the hardware is still active but the queue memory is subsequently freed, can the device DMA into the freed queue memory? [Severity: Critical] This is a pre-existing issue, but could a race condition cause stack corruption if a request times out? In mana_hwc_send_request(), if wait_for_completion_timeout() times out, the function clears the msg_id and returns, destroying the stack frame containing ctx->output_buf: drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_send_request() { ... if (!wait_for_completion_timeout(&ctx->comp_event, 40 * HZ)) { ... mana_hwc_put_msg_index(hwc, msg_id); return err; } ... } Concurrently, the interrupt handler does a lockless check of the inflight map: drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_handle_resp() { ... if (!test_bit(msg_id, hwc->inflight_msg_res.map)) { ... memcpy(ctx->output_buf, resp_msg, resp_len); ... } If the handler observes the bit as set just before the timeout clears it, it will execute the memcpy(). Since the request function has already returned, doesn't this write arbitrary device-controlled data into a deallocated stack frame? > + > + /* comp_buf is reached only by mana_hwc_comp_event(), invoked from > + * the now-fenced EQ handler, so it is safe to free once the EQ and > + * CQ are gone. > + */ > if (hwc_cq->gdma_cq) > mana_gd_destroy_queue(gc, hwc_cq->gdma_cq); > > - if (hwc_cq->gdma_eq) > - mana_gd_destroy_queue(gc, hwc_cq->gdma_eq); > - > + kfree(hwc_cq->comp_buf); > kfree(hwc_cq); > } -- Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=3