summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/net/bpf_jit_comp.c2
-rw-r--r--arch/x86/net/bpf_jit_comp.c2
-rw-r--r--include/linux/filter.h4
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;
}