Commit ae319ae1 authored by Hui Tang's avatar Hui Tang Committed by Yipeng Zou
Browse files

sched: Fix null pointer derefrence for sd->span

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/I7HFZV


CVE: NA

----------------------------------------

There may be NULL pointer derefrence when hotplug running and
creating taskgroup concurrently.

sched_autogroup_create_attach
  -> sched_create_group
    -> alloc_fair_sched_group
      -> init_auto_affinity
        -> init_affinity_domains
           -> cpumask_copy(xx, sched_domain_span(tmp))
              { tmp may be free due rcu lock missing }

{ hotplug will rebuild sched domain }
sched_cpu_activate
  -> build_sched_domains
    -> cpuset_cpu_active
      -> partition_sched_domains
        -> build_sched_domains
          -> cpu_attach_domain
            -> destroy_sched_domains
              -> call_rcu(&sd->rcu, destroy_sched_domains_rcu)

So sd should be protect with rcu lock in entire critical zone.

[  599.811593] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000
[  600.112821] pc : init_affinity_domains+0xf4/0x200
[  600.125918] lr : init_affinity_domains+0xd4/0x200
[  600.331355] Call trace:
[  600.338734]  init_affinity_domains+0xf4/0x200
[  600.347955]  init_auto_affinity+0x78/0xc0
[  600.356622]  alloc_fair_sched_group+0xd8/0x210
[  600.365594]  sched_create_group+0x48/0xc0
[  600.373970]  sched_autogroup_create_attach+0x54/0x190
[  600.383311]  ksys_setsid+0x110/0x130
[  600.391014]  __arm64_sys_setsid+0x18/0x24
[  600.399156]  el0_svc_common+0x118/0x170
[  600.406818]  el0_svc_handler+0x3c/0x80
[  600.414188]  el0_svc+0x8/0x640
[  600.420719] Code: b40002c0 9104e002 f9402061 a9401444 (a9001424)
[  600.430504] SMP: stopping secondary CPUs
[  600.441751] Starting crashdump kernel...

Fixes: 713cfd26 ("sched: Introduce smart grid scheduling strategy for cfs")
Signed-off-by: default avatarHui Tang <tanghui20@huawei.com>
Reviewed-by: default avatarZhang Qiao <zhangqiao22@huawei.com>
Signed-off-by: default avatarZhang Changzhong <zhangchangzhong@huawei.com>
Signed-off-by: default avatarYipeng Zou <zouyipeng@huawei.com>
parent 5c66aaaf
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -6110,7 +6110,7 @@ void free_affinity_domains(struct affinity_domain *ad)
{
	int i;

	for (i = 0; i < ad->dcount; i++) {
	for (i = 0; i < AD_LEVEL_MAX; i++) {
		kfree(ad->domains[i]);
		kfree(ad->domains_orig[i]);
		ad->domains[i] = NULL;
@@ -6149,6 +6149,12 @@ static int init_affinity_domains(struct affinity_domain *ad)
	int i = 0;
	int cpu;

	for (i = 0; i < AD_LEVEL_MAX; i++) {
		ad->domains[i] = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
		if (!ad->domains[i])
			goto err;
	}

	rcu_read_lock();
	cpu = cpumask_first_and(cpu_active_mask,
				housekeeping_cpumask(HK_FLAG_DOMAIN));
@@ -6157,21 +6163,12 @@ static int init_affinity_domains(struct affinity_domain *ad)
		dcount++;
	}

	if (!sd) {
	if (!sd || dcount > AD_LEVEL_MAX) {
		rcu_read_unlock();
		return -EINVAL;
	}
	rcu_read_unlock();

	for (i = 0; i < dcount; i++) {
		ad->domains[i] = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
		if (!ad->domains[i]) {
			ad->dcount = i;
		ret = -EINVAL;
		goto err;
	}
	}

	rcu_read_lock();
	idlest = sd_find_idlest_group(sd);
	cpu = group_find_idlest_cpu(idlest);
	i = 0;
@@ -6216,6 +6213,8 @@ int init_auto_affinity(struct task_group *tg)
	ret = init_affinity_domains(&auto_affi->ad);
	if (ret) {
		kfree(auto_affi);
		if (ret == -EINVAL)
			ret = 0;
		return ret;
	}