From: sashiko-bot@kernel.org
To: "Long Li" <longli@microsoft.com>
Cc: linux-hyperv@vger.kernel.org
Subject: Re: [PATCH net-next v2 3/7] net: mana: free HWC comp_buf after destroying the EQ
Date: Wed, 22 Jul 2026 23:46:15 +0000 [thread overview]
Message-ID: <20260722234616.4E24B1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260721234339.1476932-4-longli@microsoft.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
Pre-existing issues:
- [High] Use-After-Free of WQs during HWC channel destruction because WQs are destroyed before the EQ and CQ.
- [High] Immediate reuse of `msg_id` after a timeout leads to cross-request stack corruption.
- [High] Pending `mana_serv_work` items on the global workqueue are not canceled during device removal, causing a Use-After-Free.
- [High] Missing bounds check on untrusted `inline_oob_size_div4` allows out-of-bounds memory read.
- [High] Missing length check on `tx_oob_data_size` allows spoofed completions via stale DMA buffer data.
- [Medium] Destroying the CQ before the EQ triggers a `WARN_ON_ONCE(!cq)` splat if an EQ interrupt fires during the race window.
--
--- Patch [3]: [PATCH net-next v2 3/7] net: mana: free HWC comp_buf after destroying the EQ ---
commit 6326f43efebe30510f1377a79fcf8a92f5abb2b7
Author: Long Li <longli@microsoft.com>
net: mana: free HWC comp_buf after destroying the EQ
This commit changes mana_hwc_destroy_cq() to free hwc_cq->comp_buf after
destroying the CQ and EQ. This prevents a use-after-free where a late EQ
interrupt handler could touch comp_buf while the EQ was still registered.
> diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> index 3f011ebbe7b3e..2239fdeda57cb 100644
> --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
[ ... ]
> @@ -384,14 +384,20 @@ 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);
> -
> if (hwc_cq->gdma_cq)
> mana_gd_destroy_queue(gc, hwc_cq->gdma_cq);
[Severity: Medium]
This isn't a bug introduced by this patch, but destroying the CQ before the
EQ appears to leave a race window for EQ interrupts. If a hardware interrupt
fires for the EQ, could mana_gd_process_eqe() read a completion event, look
up the CQ ID in the table, find NULL, and trigger the WARN_ON_ONCE(!cq) splat?
>
> + /* comp_buf is reached only by mana_hwc_comp_event(), which the
[ ... ]
> if (hwc_cq->gdma_eq)
> mana_gd_destroy_queue(gc, hwc_cq->gdma_eq);
>
> + kfree(hwc_cq->comp_buf);
> kfree(hwc_cq);
> }
I also noticed some pre-existing issues in related code:
> drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_destroy_channel()
>
> if (hwc->txq)
> mana_hwc_destroy_wq(hwc, hwc->txq);
>
> if (hwc->rxq)
> mana_hwc_destroy_wq(hwc, hwc->rxq);
>
> if (hwc->cq)
> mana_hwc_destroy_cq(hwc->gdma_dev->gdma_context, hwc->cq);
[Severity: High]
This is a pre-existing issue, but WQs are destroyed and freed here before
the CQ/EQ. Since the EQ and CQ are not yet destroyed and their interrupts
are still active, could an in-flight EQ interrupt process a late completion,
call mana_hwc_rx_event_handler(), and dereference hwc->rxq which points to
freed memory?
> drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_send_request()
>
> if (!wait_for_completion_timeout(&ctx->comp_event,
> (msecs_to_jiffies(hwc->hwc_timeout)))) {
[ ... ]
> err = -ETIMEDOUT;
> goto out;
> }
> out:
> mana_hwc_put_msg_index(hwc, msg_id);
[Severity: High]
This is a pre-existing issue, but does the timeout path prematurely release
the msg_id without cancelling the request in hardware? If a second thread
allocates the same msg_id and the hardware sends a late response for the
first request, could mana_hwc_handle_resp() copy the response data into
the second thread's stack buffer?
> drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_rx_event_handler()
>
> sge = (struct gdma_sge *)(wqe + 8 + dma_oob->inline_oob_size_div4 * 4);
>
> /* Select the RX work request for virtual address and for reposting. */
> rq_base_addr = hwc_rxq->msg_buf->mem_info.dma_handle;
> rx_req_idx = (sge->address - rq_base_addr) / hwc->max_resp_msg_size;
[Severity: High]
This is a pre-existing issue, but is there a missing bounds check on the
untrusted inline_oob_size_div4 before it is used to calculate the sge pointer?
If a malicious hypervisor supplies an arbitrarily large value, could this
lead to an out-of-bounds memory read when sge->address is dereferenced?
> drivers/net/ethernet/microsoft/mana/hw_channel.c:mana_hwc_rx_event_handler()
>
> resp = (struct gdma_resp_hdr *)rx_req->buf_va;
>
> /* Read msg_id once from DMA buffer to prevent TOCTOU:
> * DMA memory is shared/unencrypted in CVMs - host can
> * modify it between reads.
> */
> msg_id = READ_ONCE(resp->response.hwc_msg_id);
> if (msg_id >= hwc->num_inflight_msg) {
[ ... ]
> mana_hwc_handle_resp(hwc, rx_oob->tx_oob_data_size, rx_req, msg_id);
[Severity: High]
This is a pre-existing issue, but does this code read msg_id from the DMA
buffer before verifying that the response size (rx_oob->tx_oob_data_size)
is large enough to contain it? If the hardware sends a small completion,
could the buffer retain stale data containing an old msg_id, causing
mana_hwc_handle_resp() to route the response to an active, unrelated request?
> drivers/net/ethernet/microsoft/mana/gdma_main.c:mana_schedule_serv_work()
>
> INIT_WORK(&mns_wk->serv_work, mana_serv_func);
> schedule_work(&mns_wk->serv_work);
[Severity: High]
This is a pre-existing issue, but the work item is queued on the global
workqueue here. During device unbind, mana_gd_remove() frees the gc
structure via vfree(gc) but does not track or cancel pending work items.
When the delayed work item executes, could mana_serv_func() retrieve the
stale gc pointer via pci_get_drvdata(pdev) and dereference it?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260721234339.1476932-1-longli@microsoft.com?part=3
next prev parent reply other threads:[~2026-07-22 23:46 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-21 23:43 [PATCH net-next v2 0/7] net: mana: harden the HWC and add dynamic queue depth Long Li
2026-07-21 23:43 ` [PATCH net-next v2 1/7] net: mana: RCU-protect gc->cq_table lookups against concurrent CQ destroy Long Li
2026-07-22 23:46 ` sashiko-bot
2026-07-21 23:43 ` [PATCH net-next v2 2/7] net: mana: fix HWC RQ/SQ buffer size swap Long Li
2026-07-22 23:46 ` sashiko-bot
2026-07-21 23:43 ` [PATCH net-next v2 3/7] net: mana: free HWC comp_buf after destroying the EQ Long Li
2026-07-22 23:46 ` sashiko-bot [this message]
2026-07-21 23:43 ` [PATCH net-next v2 4/7] net: mana: validate hardware-supplied values in the HWC RX path Long Li
2026-07-22 23:46 ` sashiko-bot
2026-07-21 23:43 ` [PATCH net-next v2 5/7] net: mana: fix HWC teardown safety with setup_active flag and destroy ordering Long Li
2026-07-22 23:46 ` sashiko-bot
2026-07-21 23:43 ` [PATCH net-next v2 6/7] net: mana: support concurrent HWC requests with proper synchronization Long Li
2026-07-21 23:43 ` [PATCH net-next v2 7/7] net: mana: add dynamic HWC queue depth with reinit path Long Li
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=20260722234616.4E24B1F000E9@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.