• Masami Hiramatsu (Google)'s avatar
    fprobe: Ensure running fprobe_exit_handler() finished before calling rethook_free() · 195b9cb5
    Masami Hiramatsu (Google) authored
    Ensure running fprobe_exit_handler() has finished before
    calling rethook_free() in the unregister_fprobe() so that caller can free
    the fprobe right after unregister_fprobe().
    
    unregister_fprobe() ensured that all running fprobe_entry/exit_handler()
    have finished by calling unregister_ftrace_function() which synchronizes
    RCU. But commit 5f810187 ("fprobe: Release rethook after the ftrace_ops
    is unregistered") changed to call rethook_free() after
    unregister_ftrace_function(). So call rethook_stop() to make rethook
    disabled before unregister_ftrace_function() and ensure it again.
    
    Here is the possible code flow that can call the exit handler after
    unregister_fprobe().
    
    ------
     CPU1                              CPU2
     call unregister_fprobe(fp)
     ...
                                       __fprobe_handler()
                                       rethook_hook() on probed function
     unregister_ftrace_function()
                                       return from probed function
                                       rethook hooks
                                       find rh->handler == fprobe_exit_handler
                                       call fprobe_exit_handler()
     rethook_free():
       set rh->handler = NULL;
     return from unreigster_fprobe;
                                       call fp->exit_handler() <- (*)
    ------
    
    (*) At this point, the exit handler is called after returning from
    unregister_fprobe().
    
    This fixes it as following;
    ------
     CPU1                              CPU2
     call unregister_fprobe()
     ...
     rethook_stop():
       set rh->handler = NULL;
                                       __fprobe_handler()
                                       rethook_hook() on probed function
     unregister_ftrace_function()
                                       return from probed function
                                       rethook hooks
                                       find rh->handler == NULL
                                       return from rethook
     rethook_free()
     return from unreigster_fprobe;
    ------
    
    Link: https://lore.kernel.org/all/168873859949.156157.13039240432299335849.stgit@devnote2/
    
    Fixes: 5f810187 ("fprobe: Release rethook after the ftrace_ops is unregistered")
    Cc: stable@vger.kernel.org
    Signed-off-by: default avatarMasami Hiramatsu (Google) <mhiramat@kernel.org>
    Reviewed-by: default avatarSteven Rostedt (Google) <rostedt@goodmis.org>
    195b9cb5
rethook.c 9.46 KB