On 02/22, Peter Zijlstra wrote:
> On Thu, Feb 22, 2018 at 05:37:15PM +0100, Oleg Nesterov wrote:
> > On 02/22, Prashant Bhole wrote:
> > > After debugging, found that uprobe_perf_close() is called after task has
> > > been terminated and uprobe_perf_close() tries to access task_struct of the
> > > terminated process.
> > Oh. You can't imagine how much I forgot this code ;) I will recheck, but at
> > first glance you are right. We can't rely on _free_event()->put_ctx() which
> > does put_task_struct() after event->destroy(), the exiting task does
> > put_task_struct(current) itself and sets child_ctx->task = TASK_TOMBSTONE in
> > perf_event_exit_task_context().
> > In short, nothing protects event->hw.target. But uprobe_perf_open() should
> > be
> > safe, perf_init_event() is called when the caller has the additional
> > reference.
> > I am wondering if this was wrong from the very beginning or it was broken
> > later,
> > but I won't even try to check.
> b2fe8ba674e8 ("uprobes/perf: Avoid uprobe_apply() whenever possible")
> Seems to have added that PF_EXITING test that dereferences the target
Hehe ;) no, I think we should blame another commit
("perf: Fix perf_event_exit_task() race").
I can be easily wrong, but after
added by this commit nothing protects event->hw.target.
And just in case, we can simply remove that PF_EXITING test in
this is a minor optimization. But __uprobe_perf_filter() needs a stable