net/iucv: Avoid explicit cpumask var allocation on stack
authorDawei Li <dawei.li@shingroup.cn>
Sun, 31 Mar 2024 05:34:40 +0000 (13:34 +0800)
committerJakub Kicinski <kuba@kernel.org>
Wed, 3 Apr 2024 01:19:09 +0000 (18:19 -0700)
For CONFIG_CPUMASK_OFFSTACK=y kernel, explicit allocation of cpumask
variable on stack is not recommended since it can cause potential stack
overflow.

Instead, kernel code should always use *cpumask_var API(s) to allocate
cpumask var in config-neutral way, leaving allocation strategy to
CONFIG_CPUMASK_OFFSTACK.

Use *cpumask_var API(s) to address it.

Signed-off-by: Dawei Li <dawei.li@shingroup.cn>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://lore.kernel.org/r/20240331053441.1276826-2-dawei.li@shingroup.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/iucv/iucv.c

index a4ab615ca3e3e1d48bfb4298f69507f5f648b112..5e37a8ceebcb88607c48ec548e53bd76633bec44 100644 (file)
@@ -520,7 +520,7 @@ static void iucv_setmask_mp(void)
  */
 static void iucv_setmask_up(void)
 {
-       cpumask_t cpumask;
+       static cpumask_t cpumask;
        int cpu;
 
        /* Disable all cpu but the first in cpu_irq_cpumask. */
@@ -628,23 +628,33 @@ static int iucv_cpu_online(unsigned int cpu)
 
 static int iucv_cpu_down_prep(unsigned int cpu)
 {
-       cpumask_t cpumask;
+       cpumask_var_t cpumask;
+       int ret = 0;
 
        if (!iucv_path_table)
                return 0;
 
-       cpumask_copy(&cpumask, &iucv_buffer_cpumask);
-       cpumask_clear_cpu(cpu, &cpumask);
-       if (cpumask_empty(&cpumask))
+       if (!alloc_cpumask_var(&cpumask, GFP_KERNEL))
+               return -ENOMEM;
+
+       cpumask_copy(cpumask, &iucv_buffer_cpumask);
+       cpumask_clear_cpu(cpu, cpumask);
+       if (cpumask_empty(cpumask)) {
                /* Can't offline last IUCV enabled cpu. */
-               return -EINVAL;
+               ret = -EINVAL;
+               goto __free_cpumask;
+       }
 
        iucv_retrieve_cpu(NULL);
        if (!cpumask_empty(&iucv_irq_cpumask))
-               return 0;
+               goto __free_cpumask;
+
        smp_call_function_single(cpumask_first(&iucv_buffer_cpumask),
                                 iucv_allow_cpu, NULL, 1);
-       return 0;
+
+__free_cpumask:
+       free_cpumask_var(cpumask);
+       return ret;
 }
 
 /**