• Namhyung Kim's avatar
    perf/core: Fix cgroup event list management · c5de60cd
    Namhyung Kim authored
    The active cgroup events are managed in the per-cpu cgrp_cpuctx_list.
    This list is only accessed from current cpu and not protected by any
    locks.  But from the commit ef54c1a4 ("perf: Rework
    perf_event_exit_event()"), it's possible to access (actually modify)
    the list from another cpu.
    
    In the perf_remove_from_context(), it can remove an event from the
    context without an IPI when the context is not active.  This is not
    safe with cgroup events which can have some active events in the
    context even if ctx->is_active is 0 at the moment.  The target cpu
    might be in the middle of list iteration at the same time.
    
    If the event is enabled when it's about to be closed, it might call
    perf_cgroup_event_disable() and list_del() with the cgrp_cpuctx_list
    on a different cpu.
    
    This resulted in a crash due to an invalid list pointer access during
    the cgroup list traversal on the cpu which the event belongs to.
    
    Let's fallback to IPI to access the cgrp_cpuctx_list from that cpu.
    Similarly, perf_install_in_context() should use IPI for the cgroup
    events too.
    
    Fixes: ef54c1a4 ("perf: Rework perf_event_exit_event()")
    Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/20220124195808.2252071-1-namhyung@kernel.org
    c5de60cd
core.c 324 KB