lib/group_cpus: fix NULL pointer dereference from group_cpus_evenly()

JIRA: https://issues.redhat.com/browse/RHEL-100485

commit df831e97739405ecbaddb85516bc7d4d1c933d6b
Author: Yu Kuai <yukuai3@huawei.com>
Date:   Thu Jun 19 21:26:55 2025 +0800

    lib/group_cpus: fix NULL pointer dereference from group_cpus_evenly()

    While testing null_blk with configfs, echo 0 > poll_queues will trigger
    following panic:

    BUG: kernel NULL pointer dereference, address: 0000000000000010
    Oops: Oops: 0000 [#1] SMP NOPTI
    CPU: 27 UID: 0 PID: 920 Comm: bash Not tainted 6.15.0-02023-gadbdb95c8696-dirty #1238 PREEMPT(undef)
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014
    RIP: 0010:__bitmap_or+0x48/0x70
    Call Trace:
     <TASK>
     __group_cpus_evenly+0x822/0x8c0
     group_cpus_evenly+0x2d9/0x490
     blk_mq_map_queues+0x1e/0x110
     null_map_queues+0xc9/0x170 [null_blk]
     blk_mq_update_queue_map+0xdb/0x160
     blk_mq_update_nr_hw_queues+0x22b/0x560
     nullb_update_nr_hw_queues+0x71/0xf0 [null_blk]
     nullb_device_poll_queues_store+0xa4/0x130 [null_blk]
     configfs_write_iter+0x109/0x1d0
     vfs_write+0x26e/0x6f0
     ksys_write+0x79/0x180
     __x64_sys_write+0x1d/0x30
     x64_sys_call+0x45c4/0x45f0
     do_syscall_64+0xa5/0x240
     entry_SYSCALL_64_after_hwframe+0x76/0x7e

    Root cause is that numgrps is set to 0, and ZERO_SIZE_PTR is returned from
    kcalloc(), and later ZERO_SIZE_PTR will be deferenced.

    Fix the problem by checking numgrps first in group_cpus_evenly(), and
    return NULL directly if numgrps is zero.

    [yukuai3@huawei.com: also fix the non-SMP version]
      Link: https://lkml.kernel.org/r/20250620010958.1265984-1-yukuai1@huaweicloud.com
    Link: https://lkml.kernel.org/r/20250619132655.3318883-1-yukuai1@huaweicloud.com
    Fixes: 6a6dcae8f486 ("blk-mq: Build default queue map via group_cpus_evenly()")
    Signed-off-by: Yu Kuai <yukuai3@huawei.com>
    Reviewed-by: Ming Lei <ming.lei@redhat.com>
    Reviewed-by: Jens Axboe <axboe@kernel.dk>
    Cc: ErKun Yang <yangerkun@huawei.com>
    Cc: John Garry <john.g.garry@oracle.com>
    Cc: Thomas Gleinxer <tglx@linutronix.de>
    Cc: "zhangyi (F)" <yi.zhang@huawei.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
This commit is contained in:
Ming Lei 2025-06-19 21:26:55 +08:00
parent 79919c379c
commit a3fd2908a6
1 changed files with 8 additions and 1 deletions

View File

@ -352,6 +352,9 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps)
int ret = -ENOMEM;
struct cpumask *masks = NULL;
if (numgrps == 0)
return NULL;
if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL))
return NULL;
@ -426,8 +429,12 @@ struct cpumask *group_cpus_evenly(unsigned int numgrps)
#else /* CONFIG_SMP */
struct cpumask *group_cpus_evenly(unsigned int numgrps)
{
struct cpumask *masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL);
struct cpumask *masks;
if (numgrps == 0)
return NULL;
masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL);
if (!masks)
return NULL;