On Sat, Jul 11, 2026 at 11:06:28AM -0400, Michael Bommarito wrote:
> mana_hwc_init_event_handler() in hw_channel.c stores device-advertised
> HWC_INIT_DATA_MAX_REQUEST and HWC_INIT_DATA_MAX_RESPONSE values
> without bounds checking. mana_hwc_alloc_dma_buf() later computes the
> DMA buffer size as MANA_PAGE_ALIGN(q_depth * max_msg_size) in 32-bit
> arithmetic. A malicious device returning a large max_msg_size causes
> the product to wrap, allocating a small buffer while laying out
> q_depth request slots at the unwrapped stride, placing slots outside
> the allocation.
I don't think the described data flow actually
exists in the current tree, so the security framing looks inaccurate.
Please check the comment below.
>
> Impact: a compromised hypervisor device model or malicious MANA PCI
> device can cause out-of-bounds DMA buffer writes during HWC channel
> initialization. A reproducer is available on request.
>
> Clamp both values to HW_CHANNEL_MAX_REQUEST_SIZE (4096), consistent
> with the cap already applied at the channel-create callsite.
>
> Fixes: ca9c54d2d6a5 ("net: mana: Add a driver for Microsoft Azure Network
> Adapter (MANA)")
> Cc: [email protected]
> Assisted-by: Claude:claude-opus-4-7
> Signed-off-by: Michael Bommarito <[email protected]>
> ---
> drivers/net/ethernet/microsoft/mana/hw_channel.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> index 48a9acea4ab6c..a0916b50cffce 100644
> --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> @@ -152,10 +152,14 @@ static void mana_hwc_init_event_handler(void *ctx,
> struct gdma_queue *q_self,
> break;
>
> case HWC_INIT_DATA_MAX_REQUEST:
> + if (val == 0 || val > HW_CHANNEL_MAX_REQUEST_SIZE)
> + val = HW_CHANNEL_MAX_REQUEST_SIZE;
> hwc->hwc_init_max_req_msg_size = val;
> break;
>
> case HWC_INIT_DATA_MAX_RESPONSE:
> + if (val == 0 || val > HW_CHANNEL_MAX_REQUEST_SIZE)
> + val = HW_CHANNEL_MAX_REQUEST_SIZE;
> hwc->hwc_init_max_resp_msg_size = val;
> break;
>
The clamp is applied to hwc->hwc_init_max_req_msg_size and
hwc->hwc_init_max_resp_msg_size. Tracing where those two fields are
consumed:
mana_hwc_init_event_handler()
|
mana_hwc_establish_channel() // copies them out to *max_req_msg_size
| and *max_resp_msg_size
mana_hwc_create_channel() // passes those locals only to
| mana_hwc_test_channel()
mana_hwc_test_channel() // passed as parameters but never
used them
The DMA buffers that alloc_dma_buf() sizes are created from
mana_hwc_init_queues(), which is called with the compile-time constants:
err = mana_hwc_init_queues(hwc, HW_CHANNEL_VF_BOOTSTRAP_QUEUE_DEPTH,
HW_CHANNEL_MAX_REQUEST_SIZE,
HW_CHANNEL_MAX_RESPONSE_SIZE);
Therefore, q_depth * max_msg_size cannot wrap from a device-controlled
value here.
Thanks,
Vennela
> --
> 2.53.0
>
>