• Alexei Starovoitov's avatar
    bpf: Fix fexit trampoline. · e21aa341
    Alexei Starovoitov authored
    The fexit/fmod_ret programs can be attached to kernel functions that can sleep.
    The synchronize_rcu_tasks() will not wait for such tasks to complete.
    In such case the trampoline image will be freed and when the task
    wakes up the return IP will point to freed memory causing the crash.
    Solve this by adding percpu_ref_get/put for the duration of trampoline
    and separate trampoline vs its image life times.
    The "half page" optimization has to be removed, since
    first_half->second_half->first_half transition cannot be guaranteed to
    complete in deterministic time. Every trampoline update becomes a new image.
    The image with fmod_ret or fexit progs will be freed via percpu_ref_kill and
    call_rcu_tasks. Together they will wait for the original function and
    trampoline asm to complete. The trampoline is patched from nop to jmp to skip
    fexit progs. They are freed independently from the trampoline. The image with
    fentry progs only will be freed via call_rcu_tasks_trace+call_rcu_tasks which
    will wait for both sleepable and non-sleepable progs to complete.
    
    Fixes: fec56f58 ("bpf: Introduce BPF trampoline")
    Reported-by: default avatarAndrii Nakryiko <andrii@kernel.org>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    Acked-by: Paul E. McKenney <paulmck@kernel.org>  # for RCU
    Link: https://lore.kernel.org/bpf/20210316210007.38949-1-alexei.starovoitov@gmail.com
    e21aa341
bpf_struct_ops.c 16 KB