From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: sashiko-reviews@lists.linux.dev
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v2 07/11] bpf: Introduce REF_TYPE_FRAME in the verifier
Date: Fri, 9 Oct 2026 20:26:18 -0700 [thread overview]
Message-ID: <75475cb1-7f53-499a-8eb5-3b9a9dec6fd2@linux.dev> (raw)
In-Reply-To: <sashiko-outbox-166059@kernel.org>
On 2026-10-09 1:48 p.m., sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Critical] bpf: UAF due to dropped parent_id in dynptr_from_mem for frame-scoped args
> --
>
> commit 19d3a1bd15552653b24ece884c759a788c6abaf9
> Author: Ihor Solodrai <ihor.solodrai@linux.dev>
>
> bpf: Introduce REF_TYPE_FRAME in the verifier
>
> This commit introduces REF_TYPE_FRAME to track references owned by a callee
> frame. It allows a set_callee_state_fn to anchor an argument to a reference
> which is dropped when the frame is popped.
>
>> diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
>> index c51083c761cf2..54a4f440c33b3 100644
>> --- a/include/linux/bpf_verifier.h
>> +++ b/include/linux/bpf_verifier.h
>> @@ -272,15 +272,13 @@ struct bpf_stack_state {
>> };
>>
>> struct bpf_reference_state {
>> - /* Each reference object has a type. Ensure REF_TYPE_PTR is zero to
>> - * default to pointer reference on zero initialization of a state.
>> - */
>> enum ref_state_type {
>> REF_TYPE_PTR = (1 << 1),
>> REF_TYPE_IRQ = (1 << 2),
>> REF_TYPE_LOCK = (1 << 3),
>> REF_TYPE_RES_LOCK = (1 << 4),
>> REF_TYPE_RES_LOCK_IRQ = (1 << 5),
>> + REF_TYPE_FRAME = (1 << 6),
> ^^^^^^^^^^^^^^
>
> [Severity: Critical]
> Does this new reference type get ignored when the verifier checks if a register
> is referenced?
>
> In kernel/bpf/verifier.c, find_reference_state() explicitly skips any
> reference type other than REF_TYPE_PTR:
>
> kernel/bpf/verifier.c:find_reference_state() {
> ...
> for (i = 0; i < state->acquired_refs; i++) {
> if (state->refs[i].type != REF_TYPE_PTR)
> continue;
> if (state->refs[i].id == id)
> return true;
> }
> ...
> }
>
> Because find_reference_state() ignores REF_TYPE_FRAME, reg_is_referenced()
> returns false for frame-scoped arguments.
Yes, this is intentional.
>
> Could this lead to a regression if a callback passes a frame-scoped reference
> (like a PTR_TO_MAP_KEY array key or ringbuf dynptr slice) to a constructor
> like bpf_dynptr_from_mem() to create a local dynptr?
No, bpf_dynptr_from_mem() accepts only PTR_TO_MAP_VALUE.
check_helper_call() rejects other types:
case BPF_FUNC_dynptr_from_mem:
if (regs[BPF_REG_1].type != PTR_TO_MAP_VALUE) {
[...]
return -EACCES;
}
break;
>
> When check_helper_call() processes the constructor, reg_is_referenced()
> returns false, which leaves meta->ref_obj.id as 0:
>
> kernel/bpf/verifier.c:check_helper_call() {
> ...
> if (reg_is_referenced(env, reg))
> update_ref_obj(&meta->ref_obj, reg);
> ...
> }
>
> Later, mark_stack_slots_dynptr() sets the dynptr's parent_id to this 0:
>
> kernel/bpf/verifier.c:mark_stack_slots_dynptr() {
> ...
> /* Track parent's id if the parent is a referenced object */
> parent_id = ref_obj->id;
> ...
> }
>
> This strips the dynptr of its frame-scoped lifetime tie. When the callback
> exits, release_frame_references() won't invalidate the dynptr because its
> parent_id is 0.
>
> Can the caller then extract a pointer from the dynptr using bpf_dynptr_data()
> and access memory after the callback frame is destroyed?
>
> Is it possible that pointer cast functions like bpf_skc_to_tcp_sock() also
> suffer from the exact same logic flaw because they rely on
> find_reference_state(..., meta.ref_obj.id)?
No, bpf_skc_to_tcp_sock() requires ARG_PTR_TO_BTF_ID_SOCK_COMMON. Its
compatible register types, listed in btf_id_sock_common_types, exclude
the frame-scoped arguments introduced by this series.
>
next prev parent reply other threads:[~2026-10-10 3:26 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-09 20:27 [PATCH bpf-next v2 00/11] bpf: Scope callback arguments to their frame Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 01/11] bpf: Set up callee state outside of setup_func_entry() Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 02/11] bpf: Pass the owning verifier state to callback setters Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 03/11] bpf: Append complete reference states Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 04/11] bpf: Separate reference removal from descendant invalidation Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 05/11] bpf: Share map-backed callback register setup Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 06/11] bpf: Rely on callback frame initialization defaults Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 07/11] bpf: Introduce REF_TYPE_FRAME in the verifier Ihor Solodrai
2026-10-09 20:48 ` sashiko-bot
2026-10-10 3:26 ` Ihor Solodrai [this message]
2026-10-09 20:27 ` [PATCH bpf-next v2 08/11] bpf: Scope the bpf_user_ringbuf_drain() dynptr to its callback frame Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 09/11] selftests/bpf: Cover the user ringbuf callback dynptr lifetime Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 10/11] bpf: Scope the bpf_for_each_map_elem() array key to the callback frame Ihor Solodrai
2026-10-09 20:27 ` [PATCH bpf-next v2 11/11] selftests/bpf: Cover callback-frame map key lifetime Ihor Solodrai
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=75475cb1-7f53-499a-8eb5-3b9a9dec6fd2@linux.dev \
--to=ihor.solodrai@linux.dev \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.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