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

> 


  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