perf: Fix NULL deref in inheritance code
Liming found a NULL deref when a task has a perf context but no counters when it forks. This can occur in two cases, a race during construction where the fork hits after installing the context but before the first counter gets inserted, or more reproducably, a fork after the last counter is closed (which leaves the context around). Reported-by: Wang Liming <liming.wang@windriver.com> Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Paul Mackerras <paulus@samba.org> CC: <stable@kernel.org> LKML-Reference: <1262185684.7135.222.camel@laptop> Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
Родитель
48b5ba9cc9
Коммит
05cbaa2853
|
@ -5148,7 +5148,7 @@ int perf_event_init_task(struct task_struct *child)
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!child_ctx) {
|
if (!child_ctx) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto exit;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
__perf_event_init_context(child_ctx, child);
|
__perf_event_init_context(child_ctx, child);
|
||||||
|
@ -5164,7 +5164,7 @@ int perf_event_init_task(struct task_struct *child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inherited_all) {
|
if (child_ctx && inherited_all) {
|
||||||
/*
|
/*
|
||||||
* Mark the child context as a clone of the parent
|
* Mark the child context as a clone of the parent
|
||||||
* context, or of whatever the parent is a clone of.
|
* context, or of whatever the parent is a clone of.
|
||||||
|
@ -5184,7 +5184,6 @@ int perf_event_init_task(struct task_struct *child)
|
||||||
get_ctx(child_ctx->parent_ctx);
|
get_ctx(child_ctx->parent_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit:
|
|
||||||
mutex_unlock(&parent_ctx->mutex);
|
mutex_unlock(&parent_ctx->mutex);
|
||||||
|
|
||||||
perf_unpin_context(parent_ctx);
|
perf_unpin_context(parent_ctx);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче