From: sashiko-bot@kernel.org
To: "Long Li" <longli@microsoft.com>
Cc: linux-hyperv@vger.kernel.org
Subject: Re: [PATCH net v5 3/7] net: mana: free HWC comp_buf after destroying the EQ
Date: Mon, 10 Aug 2026 19:01:34 +0000 [thread overview]
Message-ID: <20260810190135.62B831F00A3A@smtp.kernel.org> (raw)
In-Reply-To: <20260809190047.2086368-4-longli@microsoft.com>
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 <longli@microsoft.com>
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/20260809190047.2086368-1-longli@microsoft.com?part=3
next prev parent reply other threads:[~2026-08-10 19:01 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-09 19:00 [PATCH net v5 0/7] net: mana: HW channel reliability and hardening fixes Long Li
2026-08-09 19:00 ` [PATCH net v5 1/7] net: mana: RCU-protect gc->cq_table lookups against concurrent CQ destroy Long Li
2026-08-10 19:01 ` sashiko-bot
2026-08-09 19:00 ` [PATCH net v5 2/7] net: mana: fix HWC RQ/SQ buffer size swap Long Li
2026-08-10 19:01 ` sashiko-bot
2026-08-09 19:00 ` [PATCH net v5 3/7] net: mana: free HWC comp_buf after destroying the EQ Long Li
2026-08-10 19:01 ` sashiko-bot [this message]
2026-08-09 19:00 ` [PATCH net v5 4/7] net: mana: validate hardware-supplied values in the HWC RX path Long Li
2026-08-10 19:01 ` sashiko-bot
2026-08-09 19:00 ` [PATCH net v5 5/7] net: mana: fix HWC teardown safety with setup_active flag and destroy ordering Long Li
2026-08-09 19:00 ` [PATCH net v5 6/7] net: mana: fix stale HWC response after command timeout Long Li
2026-08-10 19:01 ` sashiko-bot
2026-08-09 19:00 ` [PATCH net v5 7/7] net: mana: keep max_num_cqs immutable once cq_table is allocated Long Li
2026-08-10 19:01 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260810190135.62B831F00A3A@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-hyperv@vger.kernel.org \
--cc=longli@microsoft.com \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox