* [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