Linux-HyperV List
 help / color / mirror / Atom feed
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

  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