BPF List
 help / color / mirror / Atom feed
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


  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