public inbox for bpf@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] bpf: propagate ref_obj_id for dynptr slices of refcounted dynptrs
@ 2026-03-31 17:26 Qi Tang
  2026-03-31 17:56 ` Amery Hung
  0 siblings, 1 reply; 3+ messages in thread
From: Qi Tang @ 2026-03-31 17:26 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann
  Cc: Andrii Nakryiko, Martin KaFai Lau, John Fastabend,
	Eduard Zingerman, Song Liu, bpf, Qi Tang

bpf_dynptr_slice() and bpf_dynptr_slice_rdwr() return PTR_TO_MEM
slices that carry only dynptr_id but not ref_obj_id.  When a
refcounted dynptr (ringbuf, file) is released via submit or discard,
unmark_stack_slots_dynptr() invalidates state through
release_reference(ref_obj_id).  Because the slice has no ref_obj_id,
it survives the release and remains usable as live PTR_TO_MEM.

This allows post-release reads and writes through the stale slice.
A BPF program can reserve a ringbuf dynptr, obtain a slice, submit
the dynptr, then continue writing through the slice into the
already-submitted ringbuf entry.

Set ref_obj_id on the returned slice register when the source dynptr
is refcounted, so release_reference() properly invalidates it.

The original comment stated "packet slices are not refcounted" which
was correct for the initial packet-only use case, but
bpf_dynptr_slice is a generic kfunc also used with refcounted ringbuf
and file dynptrs.

  BPF verifier incorrectly accepts post-release slice access:
    19: (85) call bpf_ringbuf_discard_dynptr  ; dynptr released
    20: (15) if r6 == 0x0 goto pc+6  ; R6=rdonly_mem(sz=64) ← stale
    21: (71) r1 = *(u8 *)(r6 +0)     ← reads freed memory

Fixes: 66e3a13e7c2c ("bpf: Add bpf_dynptr_slice and bpf_dynptr_slice_rdwr")
Signed-off-by: Qi Tang <tpluszz77@gmail.com>
---
 kernel/bpf/verifier.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index f108c01ff6d0..937c9adf1b3d 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -14071,11 +14071,8 @@ static int check_special_kfunc(struct bpf_verifier_env *env, struct bpf_kfunc_ca
 			return -EFAULT;
 		}
 		regs[BPF_REG_0].dynptr_id = meta->initialized_dynptr.id;
-
-		/* we don't need to set BPF_REG_0's ref obj id
-		 * because packet slices are not refcounted (see
-		 * dynptr_type_refcounted)
-		 */
+		if (dynptr_type_refcounted(meta->initialized_dynptr.type))
+			regs[BPF_REG_0].ref_obj_id = meta->initialized_dynptr.ref_obj_id;
 	} else {
 		return 0;
 	}
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] bpf: propagate ref_obj_id for dynptr slices of refcounted dynptrs
  2026-03-31 17:26 [PATCH] bpf: propagate ref_obj_id for dynptr slices of refcounted dynptrs Qi Tang
@ 2026-03-31 17:56 ` Amery Hung
  2026-04-01  2:06   ` Qi Tang
  0 siblings, 1 reply; 3+ messages in thread
From: Amery Hung @ 2026-03-31 17:56 UTC (permalink / raw)
  To: Qi Tang
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, John Fastabend, Eduard Zingerman, Song Liu, bpf

On Tue, Mar 31, 2026 at 10:36 AM Qi Tang <tpluszz77@gmail.com> wrote:
>
> bpf_dynptr_slice() and bpf_dynptr_slice_rdwr() return PTR_TO_MEM
> slices that carry only dynptr_id but not ref_obj_id.  When a
> refcounted dynptr (ringbuf, file) is released via submit or discard,
> unmark_stack_slots_dynptr() invalidates state through
> release_reference(ref_obj_id).  Because the slice has no ref_obj_id,
> it survives the release and remains usable as live PTR_TO_MEM.
>
> This allows post-release reads and writes through the stale slice.
> A BPF program can reserve a ringbuf dynptr, obtain a slice, submit
> the dynptr, then continue writing through the slice into the
> already-submitted ringbuf entry.
>
> Set ref_obj_id on the returned slice register when the source dynptr
> is refcounted, so release_reference() properly invalidates it.
>
> The original comment stated "packet slices are not refcounted" which
> was correct for the initial packet-only use case, but
> bpf_dynptr_slice is a generic kfunc also used with refcounted ringbuf
> and file dynptrs.
>
>   BPF verifier incorrectly accepts post-release slice access:
>     19: (85) call bpf_ringbuf_discard_dynptr  ; dynptr released
>     20: (15) if r6 == 0x0 goto pc+6  ; R6=rdonly_mem(sz=64) ← stale
>     21: (71) r1 = *(u8 *)(r6 +0)     ← reads freed memory
>
> Fixes: 66e3a13e7c2c ("bpf: Add bpf_dynptr_slice and bpf_dynptr_slice_rdwr")
> Signed-off-by: Qi Tang <tpluszz77@gmail.com>
> ---
>  kernel/bpf/verifier.c | 7 ++-----
>  1 file changed, 2 insertions(+), 5 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index f108c01ff6d0..937c9adf1b3d 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -14071,11 +14071,8 @@ static int check_special_kfunc(struct bpf_verifier_env *env, struct bpf_kfunc_ca
>                         return -EFAULT;
>                 }
>                 regs[BPF_REG_0].dynptr_id = meta->initialized_dynptr.id;
> -
> -               /* we don't need to set BPF_REG_0's ref obj id
> -                * because packet slices are not refcounted (see
> -                * dynptr_type_refcounted)
> -                */
> +               if (dynptr_type_refcounted(meta->initialized_dynptr.type))
> +                       regs[BPF_REG_0].ref_obj_id = meta->initialized_dynptr.ref_obj_id;

Currently dynptr object relation tracking is buggy and this patch
fixes a part of it. There is another parallel effort in refactoring it
[0]

BTW. It will be good to have a selftest for this type of patch.

[0] https://lore.kernel.org/bpf/20260307064439.3247440-1-ameryhung@gmail.com/



>         } else {
>                 return 0;
>         }
> --
> 2.43.0
>
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] bpf: propagate ref_obj_id for dynptr slices of refcounted dynptrs
  2026-03-31 17:56 ` Amery Hung
@ 2026-04-01  2:06   ` Qi Tang
  0 siblings, 0 replies; 3+ messages in thread
From: Qi Tang @ 2026-04-01  2:06 UTC (permalink / raw)
  To: Amery Hung
  Cc: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Martin KaFai Lau, John Fastabend, Eduard Zingerman, Song Liu, bpf,
	Qi Tang

Thanks for the review and the pointer to Amery's series. Noted on
the selftest — will make sure to include one and run the test suite
before submitting next time.

Qi Tang

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-01  2:06 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-31 17:26 [PATCH] bpf: propagate ref_obj_id for dynptr slices of refcounted dynptrs Qi Tang
2026-03-31 17:56 ` Amery Hung
2026-04-01  2:06   ` Qi Tang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox