Re: [PATCH v3] mmc: mmc_test: Fix __counted_by handling after kzalloc_flex() conversion

Ulf Hansson <[email protected]>
Newsgroups org.kernel.vger.linux-hardening,org.kernel.vger.linux-kernel,org.kernel.vger.linux-mmc,org.kernel.vger.linux-renesas-soc
Message-ID <CAPx+jO-fhBf+8T9oc6CvsAfJu1Jxp0iE=rregHJ=HmLRCvTFzg@mail.gmail.com>
On Tue, Jun 2, 2026 at 10:13 PM Prabhakar <[email protected]> wrote:
>
> From: Lad Prabhakar <[email protected]>
>
> Fix logic issues introduced by the kzalloc_flex() conversion in
> mmc_test_alloc_mem() due to interaction with the __counted_by
> annotation on the flexible array.
>
> Bounds-checking sanitizers rely on the counter field reflecting the
> allocated array size before any array access occurs. However, use
> mem->cnt both as the allocation size and as the runtime insertion
> index, causing incorrect indexing and potentially invalid bounds
> tracking.
>
> Initialize mem->cnt to the maximum allocated number of segments
> immediately after kzalloc_flex(), then use a separate local index
> variable to track successfully allocated entries. Update mem->cnt to
> the actual number of initialized elements before returning or entering
> the cleanup path.
>
> Also rewrite mmc_test_free_mem() to use a forward for-loop, improving
> readability and ensuring only initialized entries are freed.
>
> Fixes: c3126dccfd7b ("mmc: mmc_test: use kzalloc_flex")
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Geert Uytterhoeven <[email protected]>

Applied for fixes, thanks!

Kind regards
Uffe


> ---
> v2->v3:
> - Switched back to v1 version of the patch.
> - Addressed review comments from Geert.
> - Add RB tag from Geert which was received on v1.
>
> v1->v2:
> - Started with cnt = 0 and incremented before assignment to ensure
>   accurate tracking of initialized entries in mmc_test_alloc_mem().
> - In mmc_test_free_mem(), replaced the while loop with a forward for-loop to
>   safely iterate over initialized entries without risking underflow.
> - Updated commit message to clarify the issue and the fix.
>
> v2: https://lore.kernel.org/all/[email protected]/
> v1: https://lore.kernel.org/all/[email protected]/
> ---
>  drivers/mmc/core/mmc_test.c | 18 +++++++++++-------
>  1 file changed, 11 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mmc/core/mmc_test.c b/drivers/mmc/core/mmc_test.c
> index ab38e4c45a8d..4dc16649e61d 100644
> --- a/drivers/mmc/core/mmc_test.c
> +++ b/drivers/mmc/core/mmc_test.c
> @@ -318,9 +318,9 @@ static void mmc_test_free_mem(struct mmc_test_mem *mem)
>  {
>         if (!mem)
>                 return;
> -       while (mem->cnt--)
> -               __free_pages(mem->arr[mem->cnt].page,
> -                            mem->arr[mem->cnt].order);
> +       for (unsigned int i = 0; i < mem->cnt; i++)
> +               __free_pages(mem->arr[i].page,
> +                            mem->arr[i].order);
>         kfree(mem);
>  }
>
> @@ -341,6 +341,7 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
>         unsigned long page_cnt = 0;
>         unsigned long limit = nr_free_buffer_pages() >> 4;
>         struct mmc_test_mem *mem;
> +       unsigned int idx = 0;
>
>         if (max_page_cnt > limit)
>                 max_page_cnt = limit;
> @@ -375,23 +376,26 @@ static struct mmc_test_mem *mmc_test_alloc_mem(unsigned long min_sz,
>                                 goto out_free;
>                         break;
>                 }
> -               mem->arr[mem->cnt].page = page;
> -               mem->arr[mem->cnt].order = order;
> -               mem->cnt += 1;
> +               mem->arr[idx].page = page;
> +               mem->arr[idx].order = order;
> +               idx += 1;
>                 if (max_page_cnt <= (1UL << order))
>                         break;
>                 max_page_cnt -= 1UL << order;
>                 page_cnt += 1UL << order;
> -               if (mem->cnt >= max_segs) {
> +               if (idx >= mem->cnt) {
>                         if (page_cnt < min_page_cnt)
>                                 goto out_free;
>                         break;
>                 }
>         }
>
> +       mem->cnt = idx;
> +
>         return mem;
>
>  out_free:
> +       mem->cnt = idx;
>         mmc_test_free_mem(mem);
>         return NULL;
>  }
> --
> 2.54.0
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.