From: sashiko-bot@kernel.org
To: "Long Li" <longli@microsoft.com>
Cc: linux-hyperv@vger.kernel.org
Subject: Re: [PATCH net v7 7/7] net: mana: keep max_num_cqs immutable once cq_table is allocated
Date: Fri, 14 Aug 2026 17:43:23 +0000 [thread overview]
Message-ID: <20260814174323.6311C1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260813174243.3044348-8-longli@microsoft.com>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] A Time-of-Check to Time-of-Use (TOCTOU) race condition in `mana_gd_publish_cq()` and `mana_gd_unpublish_cq()` allows a malicious device to cause out-of-bounds array reads and writes, bypassing the patch's protection.
- [High] The untouched `WARN_ON(err)` in `mana_hwc_establish_channel()` still allows a maliciously crafted concurrent device response to trigger a kernel panic, defeating the purpose of the patch.
- [High] Multiple other `WARN_ON_ONCE` statements evaluating device-controlled inputs remain in the code, leaving the guest vulnerable to a device-induced panic.
--
--- Patch [7]: [PATCH net v7 7/7] net: mana: keep max_num_cqs immutable once cq_table is allocated ---
commit e063157399f0ceb210a06b4543697e98b1cac7e9
Author: Long Li <longli@microsoft.com>
net: mana: keep max_num_cqs immutable once cq_table is allocated
This commit addresses an issue where an untrusted device event can update the
max_num_cqs bound after cq_table allocation, leading to out-of-bounds
accesses. It fixes this by snapshotting the bound in hwc_init_max_num_cqs and
reading it once in mana_hwc_establish_channel(). It also replaces a WARN_ON
with an error return so that a malicious device cannot panic a panic_on_warn
guest.
> diff --git a/drivers/net/ethernet/microsoft/mana/hw_channel.c b/drivers/net/ethernet/microsoft/mana/hw_channel.c
> index b1269f7da0563..d9bff4634dc35 100644
> --- a/drivers/net/ethernet/microsoft/mana/hw_channel.c
> +++ b/drivers/net/ethernet/microsoft/mana/hw_channel.c
[ ... ]
> @@ -209,7 +209,11 @@ static void mana_hwc_init_event_handler(void *ctx, struct gdma_queue *q_self,
> break;
>
> case HWC_INIT_DATA_MAX_NUM_CQS:
> - gd->gdma_context->max_num_cqs = val;
> + /* Store only; establish_channel() commits it to
> + * max_num_cqs once, so a later event cannot grow the
> + * bound past the allocation. Pairs with its READ_ONCE().
> + */
> + WRITE_ONCE(hwc->hwc_init_max_num_cqs, val);
> break;
>
[Severity: High]
This is a pre-existing issue, but does this vulnerability still exist for the
CQ ID?
In mana_hwc_init_event_handler(), the untrusted device event can concurrently
overwrite the queue ID without synchronization:
case HWC_INIT_DATA_CQID:
hwc->cq->gdma_cq->id = val;
break;
Meanwhile, mana_gd_publish_cq() reads queue->id multiple times, first to
validate the bound and then to index the array:
if (!cq_table || queue->id >= gc->max_num_cqs)
return -EINVAL;
/* Sharing a CQ between WQs is not supported. */
if (rcu_access_pointer(cq_table[queue->id]))
return -EINVAL;
...
rcu_assign_pointer(cq_table[queue->id], queue);
If the device sends a malformed CQID event that arrives after the bounds
check but before the array indexing, couldn't this force an out-of-bounds
array write of the queue pointer? The same Time-of-Check to Time-of-Use race
condition appears to exist in mana_gd_unpublish_cq().
[ ... ]
> @@ -810,17 +816,32 @@ static int mana_hwc_establish_channel(struct gdma_context *gc, u16 *q_depth,
> *max_req_msg_size = hwc->hwc_init_max_req_msg_size;
> *max_resp_msg_size = hwc->hwc_init_max_resp_msg_size;
>
> - /* Both were set in mana_hwc_init_event_handler(). */
> - if (WARN_ON(cq->id >= gc->max_num_cqs))
> + /* Snapshot the device-reported count and id once, so the same value
> + * sizes, bounds and indexes cq_table even across the sleeping
> + * vcalloc() and a concurrent init event.
> + */
> + num_cqs = READ_ONCE(hwc->hwc_init_max_num_cqs);
> + cq_id = READ_ONCE(cq->id);
> +
> + /* Both operands come from untrusted HWC bootstrap events; a missing
> + * MAX_NUM_CQS leaves num_cqs at 0. Reject rather than WARN_ON() so a
> + * malformed device response cannot panic a panic_on_warn guest.
> + */
> + if (cq_id >= num_cqs) {
> + dev_err_ratelimited(hwc->dev,
> + "HWC: bad CQ id %u >= max %u\n",
> + cq_id, num_cqs);
> return -EPROTO;
> + }
>
> - cq_table = vcalloc(gc->max_num_cqs, sizeof(*cq_table));
> + cq_table = vcalloc(num_cqs, sizeof(*cq_table));
> if (!cq_table)
> return -ENOMEM;
>
> - /* Publish the initialised table; pairs with smp_load_acquire()
> - * in mana_gd_get_cq().
> + /* Publish the bound and the initialised table together; the release
> + * pairs with smp_load_acquire() in mana_gd_get_cq().
> */
> + gc->max_num_cqs = num_cqs;
> smp_store_release(&gc->cq_table, cq_table);
>
> /* Publish the HWC CQ now that the table is in place. */
[Severity: High]
This is a pre-existing issue, but does a maliciously crafted concurrent device
response still have the ability to trigger a kernel panic here?
Just below this context in mana_hwc_establish_channel(), there is an
untouched WARN_ON():
err = mana_gd_publish_cq(gc, cq);
if (WARN_ON(err))
return err;
If a HWC_INIT_DATA_CQID event is processed after the READ_ONCE(cq->id)
snapshot earlier in this function, mana_gd_publish_cq() will correctly reject
the modified ID and return -EINVAL. However, won't that returned error
trigger this WARN_ON(), crashing a panic_on_warn guest anyway?
[Severity: High]
This is a pre-existing issue, but are there other WARN_ON_ONCE() statements
evaluating device-controlled inputs that could lead to a device-induced panic?
For example, in mana_hwc_rx_event_handler():
if (WARN_ON_ONCE(hwc_rxq->gdma_wq->id != gdma_rxq_id))
return;
In mana_hwc_tx_event_handler():
WARN_ON_ONCE(!hwc_txq || hwc_txq->gdma_wq->id != gdma_txq_id);
And in mana_gd_read_cqe():
new_bits = (cq->head / num_cqe) & GDMA_CQE_OWNER_MASK;
/* Return -1 if overflow detected. */
if (WARN_ON_ONCE(owner_bits != new_bits))
return -1;
Since these validate untrusted values from the DMA completion ring, could a
malformed response trigger these warnings and panic a guest?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260813174243.3044348-1-longli@microsoft.com?part=7
prev parent reply other threads:[~2026-08-14 17:43 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-13 17:42 [PATCH net v7 0/7] net: mana: HW channel reliability and hardening fixes Long Li
2026-08-13 17:42 ` [PATCH net v7 1/7] net: mana: reference-count CQs looked up from the EQ handler Long Li
2026-08-14 17:43 ` sashiko-bot
2026-08-13 17:42 ` [PATCH net v7 2/7] net: mana: fix HWC RQ/SQ buffer size swap Long Li
2026-08-14 17:43 ` sashiko-bot
2026-08-13 17:42 ` [PATCH net v7 3/7] net: mana: free HWC comp_buf after destroying the EQ Long Li
2026-08-14 17:43 ` sashiko-bot
2026-08-13 17:42 ` [PATCH net v7 4/7] net: mana: validate hardware-supplied values in the HWC RX path Long Li
2026-08-14 17:43 ` sashiko-bot
2026-08-13 17:42 ` [PATCH net v7 5/7] net: mana: fix HWC teardown safety with setup_active flag and destroy ordering Long Li
2026-08-14 17:43 ` sashiko-bot
2026-08-13 17:42 ` [PATCH net v7 6/7] net: mana: fix stale HWC response after command timeout Long Li
2026-08-14 17:43 ` sashiko-bot
2026-08-13 17:42 ` [PATCH net v7 7/7] net: mana: keep max_num_cqs immutable once cq_table is allocated Long Li
2026-08-14 17:43 ` sashiko-bot [this message]
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=20260814174323.6311C1F000E9@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