> diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_gotox.c
> b/tools/testing/selftests/bpf/prog_tests/bpf_gotox.c
> index 73dc63882b7d..866b4a14ccb7 100644
> --- a/tools/testing/selftests/bpf/prog_tests/bpf_gotox.c
> +++ b/tools/testing/selftests/bpf/prog_tests/bpf_gotox.c
[ ... ]
> @@ -393,6 +417,52 @@ reject_offsets(struct bpf_insn *insns, __u32 insn_cnt,
> int off1, int off2, int o
> close(prog_fd);
> }
>
> +static void
> +check_cross_subprog_gotox_target(struct bpf_gotox *skel __always_unused)
> +{
> + struct bpf_insn insns[] = {
> + /* main subprog [0,14) */
> + BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
> + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_CALL, 0, 12),
> + BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6, 0),
> + BPF_JMP_IMM(BPF_JEQ, BPF_REG_7, 0, 4),
> + BPF_LD_IMM64_RAW(BPF_REG_2, BPF_PSEUDO_MAP_VALUE, 0),
> + BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, 0),
> + BPF_JMP_A(3),
> + BPF_LD_IMM64_RAW(BPF_REG_2, BPF_PSEUDO_MAP_VALUE, 0),
> + BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_2, 0),
> + BPF_RAW_INSN(BPF_JMP | BPF_JA | BPF_X, BPF_REG_2, 0, 0, 0),
> + BPF_MOV64_IMM(BPF_REG_0, 1),
> + BPF_EXIT_INSN(),
> +
> + /* static subprog [14,16) */
> + BPF_MOV64_IMM(BPF_REG_0, 42),
> + BPF_EXIT_INSN(),
> + };
> + int good_fd, bad_fd, prog_fd;
> +
> + good_fd = create_jt_map_with_target(12);
> + if (!ASSERT_GE(good_fd, 0, "create_good_jt_map"))
> + return;
> +
> + bad_fd = create_jt_map_with_target(14);
> + if (!ASSERT_GE(bad_fd, 0, "create_bad_jt_map")) {
> + close(good_fd);
> + return;
> + }
> +
> + insns[4].imm = bad_fd;
> + insns[8].imm = good_fd;
> +
> + prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL",
> + insns, ARRAY_SIZE(insns), NULL);
> + if (!ASSERT_EQ(prog_fd, -EACCES, "cross_subprog_gotox_prog_load"))
^^^^^^^
Does this test expect the correct error code? The kernel fix in commit
8f33cb405e13 ("bpf: Fix gotox target validation against CFG") rejects an
unmodeled gotox target with -EINVAL when the CFG jump table check fails:
kernel/bpf/verifier.c:check_indirect_jump() {
for (i = 0; i < n; i++) {
if (!is_cfg_indirect_jump_target(env, env->gotox_tmp_buf->items[i])) {
verbose(env, "gotox target %u from map id=%d is not in the CFG jump
table\n", ...);
return -EINVAL;
}
}
}
This -EINVAL propagates unchanged through do_check() -> do_check_common() ->
bpf_check() -> the BPF_PROG_LOAD syscall handler.
The existing reject_offsets() tests in this file legitimately expect -EACCES
because they fail in check_map_access (the INSN_ARRAY read path for bad size
or map-value access checks), a different code path. This new program is
structurally valid through all the loads and only fails at the gotox
instruction's CFG-jump-table check.
Should the assertion compare against -EINVAL instead of -EACCES?
> + close(prog_fd);
> +
> + close(bad_fd);
> + close(good_fd);
> +}
[ ... ]
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/27216356316