lkml.org 
[lkml]   [2014]   [Oct]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.13 158/163] perf: fix perf bug in fork()
    Date
    3.13.11.9 -stable review patch.  If anyone has any objections, please let me know.

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

    From: Peter Zijlstra <peterz@infradead.org>

    commit 6c72e3501d0d62fc064d3680e5234f3463ec5a86 upstream.

    Oleg noticed that a cleanup by Sylvain actually uncovered a bug; by
    calling perf_event_free_task() when failing sched_fork() we will not yet
    have done the memset() on ->perf_event_ctxp[] and will therefore try and
    'free' the inherited contexts, which are still in use by the parent
    process. This is bad..

    Suggested-by: Oleg Nesterov <oleg@redhat.com>
    Reported-by: Oleg Nesterov <oleg@redhat.com>
    Reported-by: Sylvain 'ythier' Hitier <sylvain.hitier@gmail.com>
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Cc: Ingo Molnar <mingo@kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Kamal Mostafa <kamal@canonical.com>
    ---
    kernel/events/core.c | 4 +++-
    kernel/fork.c | 5 +++--
    2 files changed, 6 insertions(+), 3 deletions(-)

    diff --git a/kernel/events/core.c b/kernel/events/core.c
    index 38f0d1b..6acd7d9 100644
    --- a/kernel/events/core.c
    +++ b/kernel/events/core.c
    @@ -7808,8 +7808,10 @@ int perf_event_init_task(struct task_struct *child)

    for_each_task_context_nr(ctxn) {
    ret = perf_event_init_context(child, ctxn);
    - if (ret)
    + if (ret) {
    + perf_event_free_task(child);
    return ret;
    + }
    }

    return 0;
    diff --git a/kernel/fork.c b/kernel/fork.c
    index d0ca776..5726bf1 100644
    --- a/kernel/fork.c
    +++ b/kernel/fork.c
    @@ -1323,7 +1323,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
    goto bad_fork_cleanup_policy;
    retval = audit_alloc(p);
    if (retval)
    - goto bad_fork_cleanup_policy;
    + goto bad_fork_cleanup_perf;
    /* copy all the process information */
    retval = copy_semundo(clone_flags, p);
    if (retval)
    @@ -1522,8 +1522,9 @@ bad_fork_cleanup_semundo:
    exit_sem(p);
    bad_fork_cleanup_audit:
    audit_free(p);
    -bad_fork_cleanup_policy:
    +bad_fork_cleanup_perf:
    perf_event_free_task(p);
    +bad_fork_cleanup_policy:
    #ifdef CONFIG_NUMA
    mpol_put(p->mempolicy);
    bad_fork_cleanup_cgroup:
    --
    1.9.1


    \
     
     \ /
      Last update: 2014-10-09 23:41    [W:8.367 / U:0.024 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site