Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [High] net: mana: Use-after-free of CQ objects during teardown due to missing 
RCU sync
--

commit 2740a958c23f5ddb6759715d592fec4a687478f3
Author: Long Li <[email protected]>

net: mana: prepare HWC ownership for safe reinitialization

Dynamic HWC queue sizing tears down the bootstrap queues and establishes a
second channel before publishing it. Prepare the existing HWC ownership and
teardown paths so that sequence cannot free or reuse state still reachable
by either the PF or an EQ handler.

Link: https://lore.kernel.org/r/[email protected]
Link: https://lore.kernel.org/r/[email protected]
Link: 
https://lore.kernel.org/r/[email protected]
Link: 
https://lore.kernel.org/r/[email protected]
Link: https://lore.kernel.org/r/[email protected]

> diff --git a/drivers/net/ethernet/microsoft/mana/gdma_main.c 
> b/drivers/net/ethernet/microsoft/mana/gdma_main.c
> --- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
> +++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c

[ ... ]

> @@ -765,11 +767,16 @@ static void mana_gd_process_eqe(struct gdma_queue *eq)
>       switch (type) {
>       case GDMA_EQE_COMPLETION:
>               cq_id = eqe->details[0] & 0xFFFFFF;
> -             if (WARN_ON_ONCE(cq_id >= gc->max_num_cqs))
> +             /* The IRQ handler's RCU read-side section protects the table
> +              * until HWC teardown has fenced its EQ and waited for readers.
> +              */
> +             cq_table = smp_load_acquire(&gc->cq_table);
> +             if (!cq_table || cq_id >= READ_ONCE(gc->max_num_cqs))
>                       break;
>  
> -             cq = gc->cq_table[cq_id];
> -             if (WARN_ON_ONCE(!cq || cq->type != GDMA_CQ || cq->id != cq_id))
> +             cq = READ_ONCE(cq_table[cq_id]);
> +             if (!cq || WARN_ON_ONCE(cq->type != GDMA_CQ ||
> +                                     cq->id != cq_id))
>                       break;
>  
>               if (cq->cq.callback)
>                       cq->cq.callback(cq->cq.context, cq);

[Severity: High]
Does this sequence still leave a use-after-free regression for Ethernet and
RDMA queues during teardown?

While this patch adds RCU documentation and memory barriers for the hardware
channel (HWC), it appears the teardown order issue remains for Ethernet
queues. During teardown, mana_detach() destroys CQs before EQs:

drivers/net/ethernet/microsoft/mana/mana_en.c:mana_detach() {
    ...
    mana_destroy_rxqs(apc);
    mana_destroy_txq(apc);
    mana_destroy_eq(apc);
}

When the CQ is destroyed, mana_gd_destroy_cq() unpublishes the CQ, and then
mana_gd_destroy_queue() immediately frees the queue memory via kfree()
without an RCU grace period:

drivers/net/ethernet/microsoft/mana/gdma_main.c:mana_gd_destroy_queue() {
    ...
    case GDMA_CQ:
        mana_gd_destroy_cq(gc, queue);
        break;
    ...
    mana_gd_destroy_dma_region(gc, gmi->dma_region_handle);
    mana_gd_free_memory(gmi);
    kfree(queue);
}

Because the EQ hasn't been fenced yet, an in-flight EQ interrupt could
execute mana_gd_process_eqe() concurrently. Since the RCU read-side
critical section here does not protect against kfree(), could it
dereference the freed memory when invoking cq->cq.callback() for these
queues?

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=1

Reply via email to