diff options
| -rw-r--r-- | arch/arm64/net/bpf_jit_comp.c | 2 | ||||
| -rw-r--r-- | arch/x86/net/bpf_jit_comp.c | 2 | ||||
| -rw-r--r-- | include/linux/filter.h | 4 |
3 files changed, 6 insertions, 2 deletions
diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index b3efe0668e86..326e9e1dea0a 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -1273,7 +1273,7 @@ static long bpf_unwind_fixup(u64 lr) e = search_bpf_extables(ptrauth_strip_kernel_insn_pac(lr) - 1); /* * The verifier made sure that unwind_goto follows a call in a prog. When - * the kernel called an async or an exception callback, it's exit. + * the kernel called an async callback, it's exit. */ return e ? e->fixup : 0; } diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c index d3ab36281144..6a2fe3d0039d 100644 --- a/arch/x86/net/bpf_jit_comp.c +++ b/arch/x86/net/bpf_jit_comp.c @@ -2552,7 +2552,7 @@ static u64 bpf_unwind_target(u64 ret_addr) /* * The verifier made sure that unwind_goto follows a call in a prog. When - * the kernel called an async or an exception callback, it's exit. + * the kernel called an async callback, it's exit. */ return e ? ret_addr + e->fixup : ret_addr; } diff --git a/include/linux/filter.h b/include/linux/filter.h index fccd8db33647..e0218e677a1d 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -267,9 +267,13 @@ static inline bool bpf_is_unwind_exit(const struct bpf_insn *insn) /* * The caller of the main prog doesn't tell unwind_exit from exit. An extension * is different: its caller is the caller of the subprog that it replaced. + * An exception callback returns from the frame of the main prog. After freplace + * or a tail call it returns to a prog that wasn't verified with the callback. */ static inline bool bpf_prog_can_unwind(const struct bpf_prog *prog) { + if (prog->aux->exception_cb) + return false; return bpf_is_subprog(prog) || prog->type == BPF_PROG_TYPE_EXT; } |
