* [PATCH bpf-next v3 1/2] bpf: Allow terminal gotox instructions
@ 2026-09-01 17:01 Siddharth Chintamaneni
2026-09-01 17:01 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test " Siddharth Chintamaneni
0 siblings, 1 reply; 5+ messages in thread
From: Siddharth Chintamaneni @ 2026-09-01 17:01 UTC (permalink / raw)
To: bpf
Cc: Siddharth Chintamaneni, Anton Protopopov, Alexei Starovoitov,
Daniel Borkmann, John Fastabend, Andrii Nakryiko,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau,
Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis,
Ihor Solodrai, Puranjay Mohan, rlmenge, hargar, apais
check_subprogs() treats gotox as a direct jump and validates its reserved
zero offset. When gotox is the final instruction, this produces a
synthetic successor one instruction past the end of the subprogram and
rejects an otherwise valid program.
Skip direct-offset validation for gotox and accept it as a
non-fallthrough terminal instruction. Its actual targets remain validated
from the instruction-array jump table during CFG construction.
Fixes: 493d9e0d6083 ("bpf, x86: add support for indirect jumps")
Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com>
Reviewed-by: Anton Protopopov <a.s.protopopov@gmail.com>
---
kernel/bpf/verifier.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 8f585ceb2cd5..483473df7746 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -3088,6 +3088,8 @@ static int check_subprogs(struct bpf_verifier_env *env)
subprog[cur_subprog].exit_idx = i;
goto next;
}
+ if (insn_is_gotox(&insn[i]))
+ goto next;
off = i + bpf_jmp_offset(&insn[i]) + 1;
if (off < subprog_start || off >= subprog_end) {
verbose(env, "jump out of range from insn %d to %d\n", i, off);
@@ -3107,7 +3109,8 @@ static int check_subprogs(struct bpf_verifier_env *env)
*/
if (code != (BPF_JMP | BPF_EXIT) &&
code != (BPF_JMP32 | BPF_JA) &&
- code != (BPF_JMP | BPF_JA)) {
+ code != (BPF_JMP | BPF_JA) &&
+ !insn_is_gotox(&insn[i])) {
verbose(env, "last insn is not an exit or jmp\n");
bpf_diag_program_structure(
env, i, "subprogram can fall through",
base-commit: d761934c9483ecde93fe99d8705282f716dfee50
--
2.43.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH bpf-next v3 2/2] selftests/bpf: Test terminal gotox instructions 2026-09-01 17:01 [PATCH bpf-next v3 1/2] bpf: Allow terminal gotox instructions Siddharth Chintamaneni @ 2026-09-01 17:01 ` Siddharth Chintamaneni 2026-09-01 17:55 ` Anton Protopopov 0 siblings, 1 reply; 5+ messages in thread From: Siddharth Chintamaneni @ 2026-09-01 17:01 UTC (permalink / raw) To: bpf Cc: Siddharth Chintamaneni, Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Anton Protopopov, Puranjay Mohan, rlmenge, hargar, apais Add tests that place gotox at the end of the main program and a subprogram, with each jump-table target preceding the gotox instruction. This tests gotox as a valid non-fallthrough terminal instruction. Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com> --- .../selftests/bpf/progs/verifier_gotox.c | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tools/testing/selftests/bpf/progs/verifier_gotox.c b/tools/testing/selftests/bpf/progs/verifier_gotox.c index 5b18c9a27717..cfb5b648891f 100644 --- a/tools/testing/selftests/bpf/progs/verifier_gotox.c +++ b/tools/testing/selftests/bpf/progs/verifier_gotox.c @@ -47,6 +47,48 @@ DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_src_reg, BPF_REG_1, 0, 0, __fa DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_off, BPF_REG_0, 1, 0, __failure __msg("BPF_JA|BPF_X uses reserved fields")) DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_imm, BPF_REG_0, 0, 1, __failure __msg("BPF_JA|BPF_X uses reserved fields")) +#define DEFINE_TERMINAL_GOTOX_PROG(NAME, BASE) \ + __naked void NAME(void) \ + { \ + asm volatile (" \ + .pushsection .jumptables,\"\",@progbits; \ +jt0_%=: \ + .quad ret0_%= - " BASE "; \ + .size jt0_%=, 8; \ + .global jt0_%=; \ + .popsection; \ + \ + r0 = jt0_%= ll; \ + r0 = *(u64 *)(r0 + 0); \ + goto end_%=; \ +ret0_%=: \ + r0 = 0; \ + exit; \ +end_%=: \ + .8byte %[gotox_r0]; \ +" : \ + : __imm_insn(gotox_r0, BPF_RAW_INSN(BPF_JMP | BPF_JA | BPF_X, \ + BPF_REG_0, 0, 0, 0)) \ + : __clobber_all); \ + } + +SEC("socket") +__success __retval(0) +DEFINE_TERMINAL_GOTOX_PROG(jump_table_terminal_gotox, "socket") + +static __noinline __used +DEFINE_TERMINAL_GOTOX_PROG(terminal_gotox_subprog, ".text") + +SEC("socket") +__success __retval(0) +__naked void jump_table_terminal_gotox_subprog(void) +{ + asm volatile (" \ + call terminal_gotox_subprog; \ + exit; \ +" ::: __clobber_all); +} + /* * Gotox is forbidden when there is no jump table loaded * which points to the sub-function where the gotox is used -- 2.43.0 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH bpf-next v3 2/2] selftests/bpf: Test terminal gotox instructions 2026-09-01 17:01 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test " Siddharth Chintamaneni @ 2026-09-01 17:55 ` Anton Protopopov 2026-09-01 17:55 ` Siddharth Chintamaneni 0 siblings, 1 reply; 5+ messages in thread From: Anton Protopopov @ 2026-09-01 17:55 UTC (permalink / raw) To: Siddharth Chintamaneni Cc: bpf, Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Puranjay Mohan, rlmenge, hargar, apais On 26/09/01 05:01PM, Siddharth Chintamaneni wrote: > Add tests that place gotox at the end of the main program and a > subprogram, with each jump-table target preceding the gotox instruction. > This tests gotox as a valid non-fallthrough terminal instruction. > > Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com> > --- > .../selftests/bpf/progs/verifier_gotox.c | 42 +++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/tools/testing/selftests/bpf/progs/verifier_gotox.c b/tools/testing/selftests/bpf/progs/verifier_gotox.c > index 5b18c9a27717..cfb5b648891f 100644 > --- a/tools/testing/selftests/bpf/progs/verifier_gotox.c > +++ b/tools/testing/selftests/bpf/progs/verifier_gotox.c > @@ -47,6 +47,48 @@ DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_src_reg, BPF_REG_1, 0, 0, __fa > DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_off, BPF_REG_0, 1, 0, __failure __msg("BPF_JA|BPF_X uses reserved fields")) > DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_imm, BPF_REG_0, 0, 1, __failure __msg("BPF_JA|BPF_X uses reserved fields")) > > +#define DEFINE_TERMINAL_GOTOX_PROG(NAME, BASE) \ > + __naked void NAME(void) \ > + { \ > + asm volatile (" \ > + .pushsection .jumptables,\"\",@progbits; \ > +jt0_%=: \ > + .quad ret0_%= - " BASE "; \ > + .size jt0_%=, 8; \ > + .global jt0_%=; \ > + .popsection; \ > + \ > + r0 = jt0_%= ll; \ > + r0 = *(u64 *)(r0 + 0); \ > + goto end_%=; \ > +ret0_%=: \ > + r0 = 0; \ > + exit; \ > +end_%=: \ > + .8byte %[gotox_r0]; \ > +" : \ > + : __imm_insn(gotox_r0, BPF_RAW_INSN(BPF_JMP | BPF_JA | BPF_X, \ > + BPF_REG_0, 0, 0, 0)) \ > + : __clobber_all); \ > + } > + > +SEC("socket") > +__success __retval(0) > +DEFINE_TERMINAL_GOTOX_PROG(jump_table_terminal_gotox, "socket") > + > +static __noinline __used > +DEFINE_TERMINAL_GOTOX_PROG(terminal_gotox_subprog, ".text") > + > +SEC("socket") > +__success __retval(0) > +__naked void jump_table_terminal_gotox_subprog(void) > +{ > + asm volatile (" \ > + call terminal_gotox_subprog; \ I wonder if robot will reply the same as for v2. The suggestion was to do call terminal_gotox_subprog1 call terminal_gotox_subprog2 such that subprog1 is not the last piece of loaded prog... > + exit; \ > +" ::: __clobber_all); > +} > + > /* > * Gotox is forbidden when there is no jump table loaded > * which points to the sub-function where the gotox is used > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH bpf-next v3 2/2] selftests/bpf: Test terminal gotox instructions 2026-09-01 17:55 ` Anton Protopopov @ 2026-09-01 17:55 ` Siddharth Chintamaneni 2026-09-02 15:45 ` Daniel Borkmann 0 siblings, 1 reply; 5+ messages in thread From: Siddharth Chintamaneni @ 2026-09-01 17:55 UTC (permalink / raw) To: Anton Protopopov Cc: bpf, Alexei Starovoitov, Daniel Borkmann, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Puranjay Mohan, rlmenge, hargar, apais On Tue, 1 Sept 2026 at 10:45, Anton Protopopov <a.s.protopopov@gmail.com> wrote: > > On 26/09/01 05:01PM, Siddharth Chintamaneni wrote: > > Add tests that place gotox at the end of the main program and a > > subprogram, with each jump-table target preceding the gotox instruction. > > This tests gotox as a valid non-fallthrough terminal instruction. > > > > Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com> > > --- > > .../selftests/bpf/progs/verifier_gotox.c | 42 +++++++++++++++++++ > > 1 file changed, 42 insertions(+) > > > > diff --git a/tools/testing/selftests/bpf/progs/verifier_gotox.c b/tools/testing/selftests/bpf/progs/verifier_gotox.c > > index 5b18c9a27717..cfb5b648891f 100644 > > --- a/tools/testing/selftests/bpf/progs/verifier_gotox.c > > +++ b/tools/testing/selftests/bpf/progs/verifier_gotox.c > > @@ -47,6 +47,48 @@ DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_src_reg, BPF_REG_1, 0, 0, __fa > > DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_off, BPF_REG_0, 1, 0, __failure __msg("BPF_JA|BPF_X uses reserved fields")) > > DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_imm, BPF_REG_0, 0, 1, __failure __msg("BPF_JA|BPF_X uses reserved fields")) > > > > +#define DEFINE_TERMINAL_GOTOX_PROG(NAME, BASE) \ > > + __naked void NAME(void) \ > > + { \ > > + asm volatile (" \ > > + .pushsection .jumptables,\"\",@progbits; \ > > +jt0_%=: \ > > + .quad ret0_%= - " BASE "; \ > > + .size jt0_%=, 8; \ > > + .global jt0_%=; \ > > + .popsection; \ > > + \ > > + r0 = jt0_%= ll; \ > > + r0 = *(u64 *)(r0 + 0); \ > > + goto end_%=; \ > > +ret0_%=: \ > > + r0 = 0; \ > > + exit; \ > > +end_%=: \ > > + .8byte %[gotox_r0]; \ > > +" : \ > > + : __imm_insn(gotox_r0, BPF_RAW_INSN(BPF_JMP | BPF_JA | BPF_X, \ > > + BPF_REG_0, 0, 0, 0)) \ > > + : __clobber_all); \ > > + } > > + > > +SEC("socket") > > +__success __retval(0) > > +DEFINE_TERMINAL_GOTOX_PROG(jump_table_terminal_gotox, "socket") > > + > > +static __noinline __used > > +DEFINE_TERMINAL_GOTOX_PROG(terminal_gotox_subprog, ".text") > > + > > +SEC("socket") > > +__success __retval(0) > > +__naked void jump_table_terminal_gotox_subprog(void) > > +{ > > + asm volatile (" \ > > + call terminal_gotox_subprog; \ > > I wonder if robot will reply the same as for v2. > > The suggestion was to do > > call terminal_gotox_subprog1 > call terminal_gotox_subprog2 > > such that subprog1 is not the last piece of loaded prog... > I missed this part! Can I reply the diff to this thread? or does it require a new revision? > > + exit; \ > > +" ::: __clobber_all); > > +} > > + > > /* > > * Gotox is forbidden when there is no jump table loaded > > * which points to the sub-function where the gotox is used > > -- > > 2.43.0 > > ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH bpf-next v3 2/2] selftests/bpf: Test terminal gotox instructions 2026-09-01 17:55 ` Siddharth Chintamaneni @ 2026-09-02 15:45 ` Daniel Borkmann 0 siblings, 0 replies; 5+ messages in thread From: Daniel Borkmann @ 2026-09-02 15:45 UTC (permalink / raw) To: Siddharth Chintamaneni, Anton Protopopov Cc: bpf, Alexei Starovoitov, John Fastabend, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa, Emil Tsalapatis, Ihor Solodrai, Puranjay Mohan, rlmenge, hargar, apais On 9/1/26 7:55 PM, Siddharth Chintamaneni wrote: > On Tue, 1 Sept 2026 at 10:45, Anton Protopopov <a.s.protopopov@gmail.com> wrote: >> On 26/09/01 05:01PM, Siddharth Chintamaneni wrote: >>> Add tests that place gotox at the end of the main program and a >>> subprogram, with each jump-table target preceding the gotox instruction. >>> This tests gotox as a valid non-fallthrough terminal instruction. >>> >>> Signed-off-by: Siddharth Chintamaneni <sidchintamaneni@gmail.com> >>> --- >>> .../selftests/bpf/progs/verifier_gotox.c | 42 +++++++++++++++++++ >>> 1 file changed, 42 insertions(+) >>> >>> diff --git a/tools/testing/selftests/bpf/progs/verifier_gotox.c b/tools/testing/selftests/bpf/progs/verifier_gotox.c >>> index 5b18c9a27717..cfb5b648891f 100644 >>> --- a/tools/testing/selftests/bpf/progs/verifier_gotox.c >>> +++ b/tools/testing/selftests/bpf/progs/verifier_gotox.c >>> @@ -47,6 +47,48 @@ DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_src_reg, BPF_REG_1, 0, 0, __fa >>> DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_off, BPF_REG_0, 1, 0, __failure __msg("BPF_JA|BPF_X uses reserved fields")) >>> DEFINE_SIMPLE_JUMP_TABLE_PROG(reserved_field_non_zero_imm, BPF_REG_0, 0, 1, __failure __msg("BPF_JA|BPF_X uses reserved fields")) >>> >>> +#define DEFINE_TERMINAL_GOTOX_PROG(NAME, BASE) \ >>> + __naked void NAME(void) \ >>> + { \ >>> + asm volatile (" \ >>> + .pushsection .jumptables,\"\",@progbits; \ >>> +jt0_%=: \ >>> + .quad ret0_%= - " BASE "; \ >>> + .size jt0_%=, 8; \ >>> + .global jt0_%=; \ >>> + .popsection; \ >>> + \ >>> + r0 = jt0_%= ll; \ >>> + r0 = *(u64 *)(r0 + 0); \ >>> + goto end_%=; \ >>> +ret0_%=: \ >>> + r0 = 0; \ >>> + exit; \ >>> +end_%=: \ >>> + .8byte %[gotox_r0]; \ >>> +" : \ >>> + : __imm_insn(gotox_r0, BPF_RAW_INSN(BPF_JMP | BPF_JA | BPF_X, \ >>> + BPF_REG_0, 0, 0, 0)) \ >>> + : __clobber_all); \ >>> + } >>> + >>> +SEC("socket") >>> +__success __retval(0) >>> +DEFINE_TERMINAL_GOTOX_PROG(jump_table_terminal_gotox, "socket") >>> + >>> +static __noinline __used >>> +DEFINE_TERMINAL_GOTOX_PROG(terminal_gotox_subprog, ".text") >>> + >>> +SEC("socket") >>> +__success __retval(0) >>> +__naked void jump_table_terminal_gotox_subprog(void) >>> +{ >>> + asm volatile (" \ >>> + call terminal_gotox_subprog; \ >> >> I wonder if robot will reply the same as for v2. >> >> The suggestion was to do >> >> call terminal_gotox_subprog1 >> call terminal_gotox_subprog2 >> >> such that subprog1 is not the last piece of loaded prog... > > I missed this part! Can I reply the diff to this thread? or does it > require a new revision? Please send a v4 given this needs to go through BPF CI. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-09-02 16:06 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-01 17:01 [PATCH bpf-next v3 1/2] bpf: Allow terminal gotox instructions Siddharth Chintamaneni 2026-09-01 17:01 ` [PATCH bpf-next v3 2/2] selftests/bpf: Test " Siddharth Chintamaneni 2026-09-01 17:55 ` Anton Protopopov 2026-09-01 17:55 ` Siddharth Chintamaneni 2026-09-02 15:45 ` Daniel Borkmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox