Skip to content

Commit

Permalink
padata: Allocate cpumask dependend recources in any case
Browse files Browse the repository at this point in the history
The cpumask separation work assumes the cpumask dependend recources
present regardless of valid or invalid cpumasks. With this patch
we allocate the cpumask dependend recources in any case. This fixes
two NULL pointer dereference crashes in padata_replace and in
padata_get_cpumask.

Signed-off-by: Steffen Klassert <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
klassert authored and herbertx committed Jul 26, 2010
1 parent fad3a90 commit b89661d
Showing 1 changed file with 7 additions and 17 deletions.
24 changes: 7 additions & 17 deletions kernel/padata.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ static void padata_init_pqueues(struct parallel_data *pd)
}

num_cpus = cpumask_weight(pd->cpumask.pcpu);
pd->max_seq_nr = (MAX_SEQ_NR / num_cpus) * num_cpus - 1;
pd->max_seq_nr = num_cpus ? (MAX_SEQ_NR / num_cpus) * num_cpus - 1 : 0;
}

/* Allocate and initialize the internal cpumask dependend resources. */
Expand Down Expand Up @@ -527,21 +527,19 @@ static void padata_replace(struct padata_instance *pinst,
rcu_assign_pointer(pinst->pd, pd_new);

synchronize_rcu();
if (!pd_old)
goto out;

padata_flush_queues(pd_old);
if (!cpumask_equal(pd_old->cpumask.pcpu, pd_new->cpumask.pcpu))
notification_mask |= PADATA_CPU_PARALLEL;
if (!cpumask_equal(pd_old->cpumask.cbcpu, pd_new->cpumask.cbcpu))
notification_mask |= PADATA_CPU_SERIAL;

padata_flush_queues(pd_old);
padata_free_pd(pd_old);

if (notification_mask)
blocking_notifier_call_chain(&pinst->cpumask_change_notifier,
notification_mask, pinst);

out:
pinst->flags &= ~PADATA_RESET;
}

Expand Down Expand Up @@ -673,6 +671,7 @@ int __padata_set_cpumasks(struct padata_instance *pinst,
struct parallel_data *pd = NULL;

mutex_lock(&pinst->lock);
get_online_cpus();

valid = padata_validate_cpumask(pinst, pcpumask);
if (!valid) {
Expand All @@ -681,20 +680,16 @@ int __padata_set_cpumasks(struct padata_instance *pinst,
}

valid = padata_validate_cpumask(pinst, cbcpumask);
if (!valid) {
if (!valid)
__padata_stop(pinst);
goto out_replace;
}

get_online_cpus();

out_replace:
pd = padata_alloc_pd(pinst, pcpumask, cbcpumask);
if (!pd) {
err = -ENOMEM;
goto out;
}

out_replace:
cpumask_copy(pinst->cpumask.pcpu, pcpumask);
cpumask_copy(pinst->cpumask.cbcpu, cbcpumask);

Expand All @@ -705,7 +700,6 @@ int __padata_set_cpumasks(struct padata_instance *pinst,

out:
put_online_cpus();

mutex_unlock(&pinst->lock);

return err;
Expand Down Expand Up @@ -776,11 +770,8 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
if (cpumask_test_cpu(cpu, cpu_online_mask)) {

if (!padata_validate_cpumask(pinst, pinst->cpumask.pcpu) ||
!padata_validate_cpumask(pinst, pinst->cpumask.cbcpu)) {
!padata_validate_cpumask(pinst, pinst->cpumask.cbcpu))
__padata_stop(pinst);
padata_replace(pinst, pd);
goto out;
}

pd = padata_alloc_pd(pinst, pinst->cpumask.pcpu,
pinst->cpumask.cbcpu);
Expand All @@ -790,7 +781,6 @@ static int __padata_remove_cpu(struct padata_instance *pinst, int cpu)
padata_replace(pinst, pd);
}

out:
return 0;
}

Expand Down

0 comments on commit b89661d

Please sign in to comment.