From: Yonghong Song <yonghong.song@linux.dev>
To: bot+bpf-ci@kernel.org, bpf@vger.kernel.org
Cc: ast@kernel.org, andrii@kernel.org, daniel@iogearbox.net,
eddyz87@gmail.com, kernel-team@fb.com, martin.lau@kernel.org,
mason@kernel.org, ihor.solodrai@linux.dev
Subject: Re: [PATCH bpf-next v12 12/25] bpf: Allow a subprog to end with a call that does not return
Date: Fri, 16 Oct 2026 22:38:38 -0700 [thread overview]
Message-ID: <4a7080f0-1b1c-4375-b25b-f5a2dd94bbd1@linux.dev> (raw)
In-Reply-To: <c0fca81fb0b00da256b581c75751323967d8e48a600694286fea6e46ba8f811a@mail.kernel.org>
On 10/16/26 8:35 PM, bot+bpf-ci@kernel.org wrote:
>> bpf: Allow a subprog to end with a call that does not return
> TL;DR: Inserting exits after final calls may shift verifier log instruction
> indices for newly accepted programs, which could make libbpf's CO-RE
> relocation lookup miss or name the wrong field. Was this intended?
>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
> [ ... ]
>
>> @@ -3317,6 +3317,54 @@ static void find_subprog_properties(struct bpf_verifier_env *env)
>> }
>> }
>>
>> +/*
>> + * Put an exit after a call that ends a subprog, so that nothing from the CFG
>> + * walk on has to know a subprog can end that way. check_subprogs() only lets
>> + * such a call be to a callee that never returns, so do_check() never reaches
>> + * the exit.
>> + */
>> +static int add_exits_after_final_calls(struct bpf_verifier_env *env)
>> +{
> [ ... ]
>
>> + patch[0] = *insn;
>> + new_prog = bpf_patch_insn_data(env, last, patch, 2);
>> + if (!new_prog)
>> + return -ENOMEM;
>> + env->prog = new_prog;
>> + /* The patch moved the call's aux data, orig_idx included, to the exit. */
>> + env->insn_aux_data[last].orig_idx = env->insn_aux_data[last + 1].orig_idx;
> [ ... ]
>
>> + }
>> + return 0;
>> +}
> [ ... ]
>
>> @@ -23661,6 +23718,24 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
>> if (ret < 0)
>> goto skip_full_check;
>>
>> + /*
>> + * After everything above has recorded insn offsets, so the patch
>> + * adjusts them, and before an offloaded program's per-insn state.
>> + */
>> + ret = add_exits_after_final_calls(env);
>> + if (ret < 0)
>> + goto skip_full_check;
>> +
> Does inserting these exits before bpf_check_cfg() and do_check() shift the
> instruction indices that the verifier log reports?
I think this is indeed an issue, esp. for verifier log reporting.
For example, the original function:
0: call foo
1: call bpf_unwind
2: call bpf_unwind_resume
After add_exits_after_final_calls, we will have
idx orig_idx
0 0 call foo
1 1 bpf_unwind
2 1 exit
3 2 call bpf_unwind_resume
4 2 exit
When verifier trying to report error message, we cannot use 'idx'
any more, we have to use orig_idx. For example, we have
verbose_linfo(env, env->insn_idx, "; ");
...
verbose(env, "%d: ", env->insn_idx);
here env->insn_idx refers to 'idx' in the above,
but they do not correspond to the original idx.
The actual one may be replacing env->insn_idx to corresponding
orig_idx.
We could have a helper to map idx->orig_idx. This should work.
Do we have a better solution for this?
>
> Until now no pass changed the instruction count before verification, so the
> indices in the log matched the instructions user space loaded. With this
> patch, every insn behind a subprog that ends with a call moves down by one
> for each exit added in front of it. The CFG walk and do_check() print
> env->insn_idx, so every message about those insns now carries an index that
> is not in the loaded program. insn_aux_data[].orig_idx exists for this kind
> of mismatch, but only a few messages use it.
>
> This has a concrete effect on libbpf. fixup_log_failed_core_relo() in
> tools/lib/bpf/libbpf.c reads the index from the log and uses it to find the
> relocation:
>
> if (sscanf(line1, "%d: (%*d) call unknown#195896080\n", &insn_idx) != 1)
> return;
> relo = find_relo_core(prog, insn_idx);
>
> find_relo_core() needs an exact relo->insn_idx match. Take a program whose
> main subprog ends with "call _Unwind_Resume" (the prog() example in the
> commit message) and that has a poisoned CO-RE relocation at index N in a
> later subprog. The kernel now logs that instruction as N+1, so libbpf
> either finds no relocation and leaves the raw "unknown#195896080" message,
> or picks up a different CO-RE relocation sitting at N+1 and names the wrong
> field.
>
> The cleanup-record messages are affected as well. "resume at insn %d is not
> in a landing pad" and "insn %u ... is in a landing pad" now print shifted
> indices, while bpf_exc_check_info() reports the user's own offsets.
>
> Only programs that this patch newly accepts are affected, since
> add_exits_after_final_calls() patches nothing otherwise. The commit message
> says the exits are put in "before the CFG walk" but does not mention the
> effect on the log indices.
>
> Was this intended? Would it make sense to report orig_idx in the do_check()
> messages, or to handle a final call without inserting instructions until
> after verification?
>
>
> ---
> 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/38997507726
next prev parent reply other threads:[~2026-10-17 5:38 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-17 2:51 [PATCH bpf-next v12 00/25] bpf: Run exception cleanup landing pads when bpf_unwind() unwinds Yonghong Song
2026-10-17 2:51 ` [PATCH bpf-next v12 01/25] bpf: Accept the compiler's exception cleanup table at program load Yonghong Song
2026-10-17 2:51 ` [PATCH bpf-next v12 02/25] bpf: Add the bpf_unwind() and bpf_unwind_resume() kfuncs Yonghong Song
2026-10-17 2:51 ` [PATCH bpf-next v12 03/25] bpf: Keep a call site's landing pad in insn_aux_data, add lookups Yonghong Song
2026-10-17 2:51 ` [PATCH bpf-next v12 04/25] bpf: Mark covered call sites and check a program can take a table Yonghong Song
2026-10-17 2:51 ` [PATCH bpf-next v12 05/25] bpf: Make exception landing pads reachable in the CFG Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 06/25] bpf: Verify an unwind through landing pads and epilogues Yonghong Song
2026-10-17 3:27 ` sashiko-bot
2026-10-17 5:20 ` Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 07/25] bpf: Refuse a callback that can unwind Yonghong Song
2026-10-17 3:19 ` sashiko-bot
2026-10-17 5:23 ` Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 08/25] bpf: Refuse a landing pad that does not resume Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 09/25] bpf: Do not use a private stack for a program that can unwind Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 10/25] bpf: Prepare JITed programs for dispatching cleanup pads Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 11/25] bpf: Keep an epilogue for each subprog an unwind can pass through Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 12/25] bpf: Allow a subprog to end with a call that does not return Yonghong Song
2026-10-17 3:35 ` bot+bpf-ci
2026-10-17 5:38 ` Yonghong Song [this message]
2026-10-17 2:52 ` [PATCH bpf-next v12 13/25] bpf: Dispatch cleanup pads by rewriting return addresses Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 14/25] bpf: Refuse a trampoline that calls a subprog that can unwind Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 15/25] bpf, x86: Dispatch exception cleanup pads at run time Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 16/25] bpf, arm64: " Yonghong Song
2026-10-17 2:52 ` [PATCH bpf-next v12 17/25] libbpf: Resolve the compiler's _Unwind_Resume to the kernel's kfunc Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 18/25] libbpf: Add cleanup_info to bpf_prog_load_opts Yonghong Song
2026-10-17 2:57 ` sashiko-bot
2026-10-17 2:53 ` [PATCH bpf-next v12 19/25] libbpf: Collect .bpf_cleanup records and pass them to the kernel Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 20/25] libbpf: Carry the exception cleanup table through the light skeleton Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 21/25] libbpf: Let the static linker carry .bpf_cleanup relocations Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 22/25] selftests/bpf: Add end-to-end and negative .bpf_cleanup exception tests Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 23/25] selftests/bpf: Add __set_global() and __ret_global() test tags Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 24/25] selftests/bpf: Cover more accepted .bpf_cleanup exception shapes Yonghong Song
2026-10-17 2:53 ` [PATCH bpf-next v12 25/25] selftests/bpf: Load an exception cleanup program from a light skeleton Yonghong Song
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4a7080f0-1b1c-4375-b25b-f5a2dd94bbd1@linux.dev \
--to=yonghong.song@linux.dev \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bot+bpf-ci@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=ihor.solodrai@linux.dev \
--cc=kernel-team@fb.com \
--cc=martin.lau@kernel.org \
--cc=mason@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox