hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IB3N2A
----------------------------------------
KASAN detected a double-free bug in the smart grid.
This issue arises from the uninitialized use of p->grid_qos within the task {fork,free} processes.
The sequence of events leading to the double-free is as follows:
CPU0 CPU1 fork (in some error process) goto bad_fork_free call_rcu(__delayed_free_task) __delayed_free_task sched_grid_qos_free realse_task delayed_put_task_struct __put_task_struct sched_grid_qos_free(double free)
When copy_process returns with an error, grid_qos is double-freed.
To address this, grid_qos is initialized to NULL in dup_task_struct, and a NULL check is added for p->grid_qos before freeing.
Bug report details: ================================================================== BUG: KASAN: double-free or invalid-free in sched_grid_qos_free+0x3c/0x90
CPU: 343 PID: 0 Comm: swapper/343 Kdump: loaded Tainted: G B E Call trace: dump_backtrace+0x0/0x3e0 show_stack+0x1c/0x28 dump_stack+0x13c/0x190 print_address_description.constprop.0+0x28/0x1f0 kasan_report_invalid_free+0x44/0x6c __kasan_slab_free+0x158/0x180 kasan_slab_free+0x10/0x20 kfree+0xe0/0x6e0 sched_grid_qos_free+0x3c/0x90 free_task+0xc4/0x164 __put_task_struct+0x264/0x31c delayed_put_task_struct+0x94/0x180 rcu_do_batch+0x2ec/0x9f0 rcu_core+0x34c/0x530 rcu_core_si+0x14/0x30 __do_softirq+0x284/0x900 irq_exit+0x2d4/0x35c __handle_domain_irq+0x108/0x1f0 gic_handle_irq+0x74/0x620 el1_irq+0xbc/0x140 arch_cpu_idle+0x14/0x3c default_idle_call+0x80/0x320 cpuidle_idle_call+0x244/0x2b0 do_idle+0x138/0x260 cpu_startup_entry+0x2c/0x70 secondary_start_kernel+0x35c/0x4e4
Allocated by task 44027: kasan_save_stack+0x24/0x50 __kasan_kmalloc.constprop.0+0xa0/0xcc kasan_kmalloc+0xc/0x14 kmem_cache_alloc_trace+0xdc/0x5d0 sched_grid_qos_fork+0x50/0x20c copy_process+0x8fc/0x3f60 kernel_clone+0x12c/0x660 __se_sys_clone+0xc0/0x110 __arm64_sys_clone+0xa8/0x110 invoke_syscall+0x70/0x274 el0_svc_common.constprop.0+0x1fc/0x2dc do_el0_svc+0xe8/0x140 el0_svc+0x1c/0x2c el0_sync_handler+0xb0/0xb4 el0_sync+0x168/0x180
Freed by task 1748: kasan_save_stack+0x24/0x50 kasan_set_track+0x24/0x34 kasan_set_free_info+0x24/0x4c __kasan_slab_free+0xf8/0x180 kasan_slab_free+0x10/0x20 kfree+0xe0/0x6e0 sched_grid_qos_free+0x3c/0x90 free_task+0xc4/0x164 __delayed_free_task+0x18/0x3c rcu_do_batch+0x2ec/0x9f0 rcu_core+0x34c/0x530 rcu_core_si+0x14/0x30 __do_softirq+0x284/0x900
Fixes: 700bfc4068cf ("sched: smart grid: init sched_grid_qos structure on QOS purpose") Signed-off-by: Yipeng Zou zouyipeng@huawei.com --- kernel/fork.c | 4 ++++ kernel/sched/grid/qos.c | 3 +++ 2 files changed, 7 insertions(+)
diff --git a/kernel/fork.c b/kernel/fork.c index dcf1f9c655d8..9b1ea79deaa5 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -953,6 +953,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig, int node) tsk->prefer_cpus = NULL; #endif
+#ifdef CONFIG_QOS_SCHED_SMART_GRID + tsk->grid_qos = NULL; +#endif + #ifdef CONFIG_SCHED_TASK_RELATIONSHIP tsk->rship = NULL; #endif diff --git a/kernel/sched/grid/qos.c b/kernel/sched/grid/qos.c index 7ee3687347ce..60b1ff843bbb 100644 --- a/kernel/sched/grid/qos.c +++ b/kernel/sched/grid/qos.c @@ -70,6 +70,9 @@ int sched_grid_qos_fork(struct task_struct *p, struct task_struct *orig)
void sched_grid_qos_free(struct task_struct *p) { + if (!p->grid_qos) + return; + kfree(p->grid_qos); p->grid_qos = NULL; }