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 05/12] bpf: Support by-value struct and __int128 kfunc arguments
Date: Mon, 7 Sep 2026 21:23:34 -0700 [thread overview]
Message-ID: <8e59b431-3124-46a4-b6d6-1e1ae59f08c4@linux.dev> (raw)
In-Reply-To: <b596aa791c607e639b08d2e6bd6a4a3a9ed28e39bade2364e4b77a2e01678cdc@mail.kernel.org>
On 9/3/26 11:24 PM, bot+bpf-ci@kernel.org wrote:
>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>> index 17e576c7b757..030fb37c22ef 100644
>> --- a/kernel/bpf/verifier.c
>> +++ b/kernel/bpf/verifier.c
> [ ... ]
>
>> @@ -12792,29 +12904,34 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_call_arg_me
>> const struct btf *btf = meta->btf;
>> const struct btf_param *args;
>> struct btf_record *rec;
>> - u32 i, nargs;
>> + u32 i, k, nargs, proto_slots, slots_used, nslots = 0;
>> int ret;
>>
>> args = (const struct btf_param *)(meta->func_proto + 1);
>> nargs = btf_type_vlen(meta->func_proto);
>> + proto_slots = kfunc_proto_slots(btf, meta->func_proto);
>>
>> - ret = check_outgoing_stack_args(env, caller, nargs, func_name, btf, args);
>> + ret = check_outgoing_stack_args(env, caller, proto_slots, func_name, btf,
>> + proto_slots == nargs ? args : NULL);
>> if (ret)
>> return ret;
>>
>> /* Check that BTF function arguments match actual types that the
>> * verifier sees.
>> */
>> - for (i = 0; i < nargs; i++) {
>> - struct bpf_reg_state *reg = get_func_arg_reg(caller, regs, i);
>> + for (i = 0, slots_used = 0; i < nargs; i++, slots_used += nslots) {
>> + struct bpf_reg_state *reg = get_func_arg_reg(caller, regs, slots_used);
>> const struct btf_type *t, *ref_t, *resolve_ret;
>> enum bpf_arg_type arg_type = ARG_DONTCARE;
>> - argno_t argno = argno_from_arg(i + 1);
>> + argno_t argno = argno_from_arg(slots_used + 1);
>> int regno = reg_from_argno(argno);
>> bool btf_id_fixed_off_ok = true;
>> u32 ref_id = args[i].type, type_size;
>> int kf_arg_type = meta->fn->arg_type[i];
>>
>> + t = btf_type_skip_modifiers(btf, args[i].type, NULL);
>> + nslots = kfunc_arg_slots(t);
>> +
> This converts the argument walk to slot-based indexing, where 'reg' and
> 'argno' now come from 'slots_used' rather than 'i'. Before this patch
> every parameter took exactly one slot, so parameter index and slot
> index were the same number. After this patch they diverge whenever a
> parameter takes two slots.
>
> The KF_ARG_MEM_SIZE case, ~500 lines further down in check_kfunc_args(),
> was not converted. It still resolves the buffer register by parameter
> index:
>
> kernel/bpf/verifier.c:check_kfunc_args() {
> ...
> case KF_ARG_MEM_SIZE:
> {
> struct bpf_reg_state *buff_reg = get_func_arg_reg(caller, regs, i - 1);
> struct bpf_reg_state *size_reg = reg;
> argno_t buff_argno = argno_from_arg(i);
> ...
> }
>
> For a kfunc such as
>
> void bpf_x(__int128 v, void *p, u32 p__sz);
>
> v occupies slots 0-1 (R1, R2), p slot 2 (R3), p__sz slot 3 (R4). At
> i == 2, slots_used == 3, so 'reg' and 'argno' correctly select R4, but
> buff_reg = get_func_arg_reg(caller, regs, i - 1) selects R2 (the upper
> eightbyte of v) instead of R3, the pointer the length actually
> describes. The same applies to a 16-byte by-value struct parameter,
> exactly the shape this patch exists to enable.
>
> The consequence is a validation hole, not just a bad diagnostic. R2 is
> a SCALAR_VALUE, so when the program passes a __int128 (or struct) whose
> upper eightbyte is zero -- the common case for any value that fits in
> 64 bits -- bpf_register_is_null(buff_reg) is true and the case breaks
> out early:
>
> if (bpf_register_is_null(buff_reg))
> break;
>
> check_mem_size_reg() is then never called, so neither p nor p__sz is
> checked. The pointer's own iteration does not cover it either:
> get_kfunc_arg_type() classifies a pointer followed by a __sz parameter
> as plain KF_ARG_PTR_TO_MEM without MEM_FIXED_SIZE, and that switch arm
> only validates size when MEM_FIXED_SIZE is set. The program therefore
> loads and the kfunc runs with an unbounded length against p. When the
> upper eightbyte is non-zero the failure inverts into a spurious
> rejection, since check_mem_size_reg() is handed a scalar as the memory
> pointer. buff_argno = argno_from_arg(i) is wrong in the same way and
> feeds the wrong register into the diagnostics and into
> mark_stack_arg_precision()/mark_chain_precision() via
> check_mem_size_reg().
Yes, I missed this one. Will fix.
>
> At this commit gen_kfunc_arg_proto() gates every nslots > 1 argument on
> bpf_jit_supports_kfunc_arg_slot(), whose __weak default in
> kernel/bpf/core.c returns false, so multi-slot kfunc arguments are
> still refused. Within the stated range
> db649eef61418e5d0289d88bcdd663e510756589..9ad88f2069ccb8b9d464230a3d04082baaffe4e0,
> commit 2924cde3ca70 ("bpf, x86: Place kfunc arguments per the SysV
> calling convention") and commit e958bc6f838b ("bpf, arm64: Place kfunc
> arguments per AAPCS64") enable the path, and no commit in that range
> touches kernel/bpf/verifier.c again apart from db9461ba111c adding
> btf_type_align16().
>
> Both uses should be derived from the slot walk, e.g.
> get_func_arg_reg(caller, regs, slots_used - 1) and
> argno_from_arg(slots_used).
>
> ---
>
> commit db649eef61418e5d0289d88bcdd663e510756589
> Author: Yonghong Song <yonghong.song@linux.dev>
>
>> bpf: Support by-value struct and __int128 kfunc arguments
>>
>> A kfunc taking a struct or union by value is rejected today, and one
>> taking an __int128 is accepted but mis-counted:
>>
>> Unrecognized R2 type STRUCT
>>
>> Give the kfunc argument walk the same slot count a BPF-to-BPF call now
>> uses: one argument register per eightbyte, so a 16-byte value takes two.
>> The outgoing stack argument count at the call site follows the slots for
>> the same reason. Similar to BPF-to-BPF aggregate handling, a kfunc
>> aggregate argument only supports tbe composed of scalars.
>>
>> Signed-off-by: Yonghong Song <yonghong.song@linux.dev>
> This looks like a bug fix for kfunc argument handling introduced in
> commit 1690dcf27c73 ("bpf: Classify scalar kfunc arguments from BTF"),
> which added get_kfunc_arg_type() that only handled scalar and pointer
> types, causing struct/union types to be rejected with 'Unrecognized R2
> type STRUCT' and __int128 arguments to be mis-counted. Should this
> include:
>
> Fixes: 1690dcf27c73 ("bpf: Classify scalar kfunc arguments from BTF")
>
>
> ---
> 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/33840714551
next prev parent reply other threads:[~2026-09-08 4:23 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-04 5:09 [PATCH bpf-next 00/12] bpf: Support by-value struct and __int128 arguments Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 01/12] selftests/bpf: Add a test for an __int128 by-value argument Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 02/12] bpf: Index global function arguments by argument slot Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 03/12] bpf: Support by-value struct arguments up to 16 bytes Yonghong Song
2026-09-04 5:23 ` sashiko-bot
2026-09-08 4:17 ` Yonghong Song
2026-09-04 6:09 ` bot+bpf-ci
2026-09-08 4:19 ` Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 04/12] bpf: Support __int128 as a by-value function argument Yonghong Song
2026-09-04 5:32 ` sashiko-bot
2026-09-08 4:20 ` Yonghong Song
2026-09-04 6:09 ` bot+bpf-ci
2026-09-08 4:21 ` Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 05/12] bpf: Support by-value struct and __int128 kfunc arguments Yonghong Song
2026-09-04 6:18 ` sashiko-bot
2026-09-08 4:22 ` Yonghong Song
2026-09-04 6:24 ` bot+bpf-ci
2026-09-08 4:23 ` Yonghong Song [this message]
2026-09-04 5:10 ` [PATCH bpf-next 06/12] bpf: Add a JIT helper for the outgoing stack of kfunc calls Yonghong Song
2026-09-04 5:25 ` sashiko-bot
2026-09-08 4:26 ` Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 07/12] bpf, x86: Place kfunc arguments per the SysV calling convention Yonghong Song
2026-09-04 5:36 ` sashiko-bot
2026-09-08 4:27 ` Yonghong Song
2026-09-04 23:58 ` Alexei Starovoitov
2026-09-06 20:15 ` Yonghong Song
2026-09-08 4:33 ` Alexei Starovoitov
2026-09-08 5:02 ` Yonghong Song
2026-09-08 5:10 ` Yonghong Song
2026-09-08 15:24 ` Alexei Starovoitov
2026-09-08 18:43 ` Yonghong Song
2026-09-09 1:59 ` Alexei Starovoitov
2026-09-04 5:10 ` [PATCH bpf-next 08/12] bpf: Record a 16-byte argument alignment in the function model Yonghong Song
2026-09-04 6:09 ` bot+bpf-ci
2026-09-08 4:28 ` Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 09/12] bpf, arm64: Place kfunc arguments per AAPCS64 Yonghong Song
2026-09-04 6:09 ` bot+bpf-ci
2026-09-04 5:10 ` [PATCH bpf-next 10/12] selftests/bpf: Add C tests for by-value arguments up to 16 bytes Yonghong Song
2026-09-04 5:19 ` sashiko-bot
2026-09-08 4:33 ` Yonghong Song
2026-09-04 6:09 ` bot+bpf-ci
2026-09-08 4:34 ` Yonghong Song
2026-09-04 5:10 ` [PATCH bpf-next 11/12] selftests/bpf: Add inline-asm tests for by-value arguments Yonghong Song
2026-09-04 6:09 ` bot+bpf-ci
2026-09-08 4:35 ` Yonghong Song
2026-09-04 5:11 ` [PATCH bpf-next 12/12] selftests/bpf: Add tests for by-value kfunc arguments 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=8e59b431-3124-46a4-b6d6-1e1ae59f08c4@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