提交 70dc4628 编写于 作者: H Hui Tang 提交者: zhangchangzhong

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: NHui Tang <tanghui20@huawei.com>
Reviewed-by: NZhang Qiao <zhangqiao22@huawei.com>
Signed-off-by: NZhang Changzhong <zhangchangzhong@huawei.com>
上级 4d772181
......@@ -5582,7 +5582,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;
......@@ -5621,6 +5621,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));
......@@ -5629,21 +5635,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;
goto err;
}
ret = -EINVAL;
goto err;
}
rcu_read_lock();
idlest = sd_find_idlest_group(sd);
cpu = group_find_idlest_cpu(idlest);
i = 0;
......@@ -5688,6 +5685,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;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册