Commit f1174976 authored by Yipeng Zou's avatar Yipeng Zou
Browse files

sched: smart_grid: Prevent double-free in sched_grid_qos_free

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: 1a553561 ("sched: smart grid: init sched_grid_qos structure on QOS purpose")
Signed-off-by: default avatarYipeng Zou <zouyipeng@huawei.com>
parent e0dc5e14
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1192,6 +1192,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

	setup_thread_stack(tsk, orig);
	clear_user_return_notifier(tsk);
	clear_tsk_need_resched(tsk);
+3 −0
Original line number Diff line number Diff line
@@ -71,6 +71,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;
}