From: "Emil Tsalapatis" <emil@etsalapatis.com>
To: "Eduard Zingerman" <eddyz87@gmail.com>, <bpf@vger.kernel.org>
Cc: <andrii@kernel.org>, <ast@kernel.org>, <daniel@iogearbox.net>,
<martin.lau@kernel.org>, <memxor@gmail.com>, <song@kernel.org>,
<yonghong.song@linux.dev>
Subject: Re: [PATCH bpf-next v3 1/2] bpf: Allow void global functions in the verifier
Date: Tue, 24 Feb 2026 13:46:22 -0500 [thread overview]
Message-ID: <DGNEYQZUKR83.25MVGRAQ05NSU@etsalapatis.com> (raw)
In-Reply-To: <7fcfdf81aa76d816f7b5032d5b8a85302621fe64.camel@gmail.com>
On Mon Feb 23, 2026 at 7:09 PM EST, Eduard Zingerman wrote:
> On Mon, 2026-02-23 at 16:50 -0500, Emil Tsalapatis wrote:
Ack on the comments for 2/2. For here:
>
> [...]
>
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 0162f946032f..e997c3776fa7 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
>> @@ -444,6 +444,29 @@ static bool subprog_is_global(const struct bpf_verifier_env *env, int subprog)
>> return aux && aux[subprog].linkage == BTF_FUNC_GLOBAL;
>> }
>>
>> +static bool subprog_returns_void(struct bpf_verifier_env *env, int subprog)
>> +{
>> + const struct btf_type *type, *func, *func_proto;
>> + const struct btf *btf = env->prog->aux->btf;
>> + u32 btf_id;
>> +
>> + btf_id = env->prog->aux->func_info[subprog].type_id;
>> +
>> + func = btf_type_by_id(btf, btf_id);
>> + if (verifier_bug_if(!func, env, "btf_id %u not found", btf_id))
>> + return false;
>> +
>> + func_proto = btf_type_by_id(btf, func->type);
>> + if (verifier_bug_if(!func_proto, env, "btf_id %u not found", func->type))
>> + return false;
>> +
>> + type = btf_type_skip_modifiers(btf, func_proto->type, NULL);
>> + if (verifier_bug_if(!type, env, "btf_id %u not found", func_proto->type))
>> + return false;
>> +
>
> Nit: I there there are a few unnecessary 'verifier_bug_if()' checks here,
> e.g. btf.c:btf_check_all_types() guarantees that func->type and func_proto->type
> would be valid.
>
Ack, just to make sure I got it right at all the verifier_bug_if() are
unnecessary. unnecessary because the BTF is already checked. There's no way we
have an existing type with invalid fields. We also know the subprog btf
ID is valid from check_btf_func_early that happens way before
do_check_subprogs where subprog_returns_void is used.
>> + return btf_type_is_void(type);
>> +}
>> +
>> static const char *subprog_name(const struct bpf_verifier_env *env, int subprog)
>> {
>> struct bpf_func_info *info;
>
> [...]
>
>> @@ -17812,6 +17837,16 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
>>
>> /* LSM and struct_ops func-ptr's return type could be "void" */
>> if (!is_subprog || frame->in_exception_callback_fn) {
>> +
>> + /*
>> + * If the actual program is an extension, let it
>> + * return void - attaching will succeed only if the
>> + * program being replaced also returns void, and since
>> + * it has passed verification its actual type doesn't matter.
>> + */
>> + if (env->prog->type == BPF_PROG_TYPE_EXT && subprog_returns_void(env, frame->subprogno))
>> + return 0;
>> +
>> switch (prog_type) {
>> case BPF_PROG_TYPE_LSM:
>> if (prog->expected_attach_type == BPF_LSM_CGROUP)
>> @@ -17841,6 +17876,10 @@ static int check_return_code(struct bpf_verifier_env *env, int regno, const char
>> default:
>> break;
>> }
>> + } else {
>> + /* If this is a void global subprog, there is no return value. */
>> + if (subprog_is_global(env, frame->subprogno) && subprog_returns_void(env, frame->subprogno))
>> + return 0;
>
> Suppose a global subprogram is verified and it calls bpf_throw().
> check_return_code() is called from check_kfunc_call() in such case
> with R1 as a parameter. This check acts on the return type of the
> program, will it miss proper return value check for the program?
>
Due to the short-circuiting herea a void global program can bpf_throw()
with no issue. This is what we want, correct? The return type we check
in that case would always be that of the u64 cookie AFAICT.
>> }
>>
>> /* eBPF calling convention is such that R0 is used
>
> [...]
next prev parent reply other threads:[~2026-02-24 18:46 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-23 21:50 [PATCH bpf-next v3 0/2] bpf: Allow void return type for global subprogs Emil Tsalapatis
2026-02-23 21:50 ` [PATCH bpf-next v3 1/2] bpf: Allow void global functions in the verifier Emil Tsalapatis
2026-02-24 0:09 ` Eduard Zingerman
2026-02-24 18:46 ` Emil Tsalapatis [this message]
2026-02-24 19:02 ` Eduard Zingerman
2026-02-24 19:53 ` Emil Tsalapatis
2026-02-24 20:33 ` Eduard Zingerman
2026-02-25 0:55 ` Emil Tsalapatis
2026-02-23 21:50 ` [PATCH bpf-next v3 2/2] selftests: bpf: Add tests for void global subprogs Emil Tsalapatis
2026-02-24 0:24 ` Eduard Zingerman
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=DGNEYQZUKR83.25MVGRAQ05NSU@etsalapatis.com \
--to=emil@etsalapatis.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=martin.lau@kernel.org \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@linux.dev \
/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