Re: [PATCH net v5 4/7] net: mana: validate hardware-supplied values in the HWC RX path

[email protected] Mon, 10 Aug 2026 19:01:37 +0000
Newsgroups org.kernel.vger.linux-hyperv
Message-ID <[email protected]>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

Pre-existing issues:
- [Critical] Race condition between timeout path and RX interrupt handler leading to kernel stack corruption and cross-request data corruption.
- [High] Missing length check before reading DMA response payload causes stale message IDs to incorrectly complete unrelated requests.
--

--- Patch [4]: [PATCH net v5 4/7] net: mana: validate hardware-supplied values in the HWC RX path ---
commit 74a56502856c8211c5e1df5ca5d7019fd74fb6b6
Author: Long Li <[email protected]>

net: mana: validate hardware-supplied values in the HWC RX path

This commit adds validation for lengths, indices, and sizes taken from device
DMA in the HWC RX path. It aims to protect against buggy firmware or
malicious hosts by snapshotting values and performing bounds checks. It also
drops the early return for short responses, deferring to mana_hwc_handle_resp()
to handle them.

> diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> index 19896bb5ce1a4..5db8cfe2d8443 100644
> --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> @@ -90,6 +103,18 @@ static void mana_hwc_handle_resp(struct hw_channel_context *hwc, u32 resp_len,
>  	}
>  
>  	ctx = hwc->caller_ctx + msg_id;
> +
> +	/* Reject responses larger than the RX DMA buffer — the SGE
> +	 * limits what hardware can DMA, so an oversized resp_len
> +	 * indicates a firmware bug.  Fail rather than silently
> +	 * truncating.
> +	 */
> +	if (resp_len > rx_req->buf_len) {
> +		dev_err(hwc->dev, "HWC RX: resp_len %u > buf_len %u\n",
> +			resp_len, rx_req->buf_len);
> +		resp_len = 0;
> +	}
> +
>  	err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);

[Severity: Critical]
This is a pre-existing issue, but is there a race condition between the
timeout path and the RX interrupt handler leading to kernel stack
corruption?

If a slow hardware response causes wait_for_completion_timeout() to
expire in mana_hwc_send_request(), the timeout path frees the msg_id
and returns:

mana_hwc_send_request() {
        err = wait_for_completion_timeout(...);
        if (!err) {
                err = -ETIMEDOUT;
                goto out;
        }
        ...
out:
        mana_hwc_put_msg_index(hwc, msg_id);
        return err;
}

Returning here pops the stack frame pointed to by ctx->output_buf.

If the interrupt handler is concurrently running and passes the bounds
checks, it could then execute memcpy() directly into this deallocated
stack frame:

mana_hwc_handle_resp() {
        ...
        memcpy(ctx->output_buf, resp_msg, resp_len);
        ...
}

Can this cause memory corruption, especially if the timed-out msg_id
is quickly reallocated to a new request which then gets overwritten
with the stale response?

>  	if (err)
>  		goto out;

[ ... ]

> @@ -259,28 +305,76 @@ static void mana_hwc_rx_event_handler(void *ctx, u32 gdma_rxq_id,
>  	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.
> +	/* Read msg_id once from the DMA buffer to prevent TOCTOU: DMA memory
> +	 * is shared/unencrypted in CVMs, so the host can modify it between
> +	 * reads.  A short response is not rejected here; it is handed to
> +	 * mana_hwc_handle_resp() below, whose mana_hwc_verify_resp_msg()
> +	 * fails it with -EPROTO and completes the waiting sender, so one
> +	 * malformed response cannot stall the whole channel.
>  	 */
>  	msg_id = READ_ONCE(resp->response.hwc_msg_id);

[Severity: High]
This isn't a bug introduced by this patch, but does reading the DMA
response payload without a length check cause stale message IDs to
incorrectly complete unrelated requests?

If the hardware or a malicious host provides an RX response with
tx_oob_data_size smaller than the offset required to contain the
hwc_msg_id field, it will not overwrite the hwc_msg_id field in the
persistent DMA ring buffer.

The driver then reads this stale msg_id in mana_hwc_rx_event_handler(),
which likely belongs to a previously completed request that has since
been re-allocated to a new, unrelated active request.

The driver subsequently fails this unrelated active request with -EPROTO
in mana_hwc_handle_resp():

mana_hwc_handle_resp() {
        ...
        err = mana_hwc_verify_resp_msg(ctx, resp_msg, resp_len);
        if (err)
                goto out;
        ...
out:
        ctx->error = err;
        ...
        complete(&ctx->comp_event);
}

Could a malicious host forge short DMA responses to intentionally abort
unrelated active requests?

>  	if (msg_id >= hwc->num_inflight_msg) {
>  		dev_err(hwc->dev, "HWC RX: wrong msg_id=%u\n", msg_id);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=4