BPF List
 help / color / mirror / Atom feed
From: Justin Suess <utilityemal77@gmail.com>
To: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Eduard Zingerman <eddyz87@gmail.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>
Cc: Song Liu <song@kernel.org>, Puranjay Mohan <puranjay@kernel.org>,
	bpf@vger.kernel.org, Justin Suess <utilityemal77@gmail.com>
Subject: [PATCH bpf-next v2 0/6] bpf: bound trusted fields to their parent's lifetime
Date: Tue, 20 Oct 2026 10:50:53 -0400	[thread overview]
Message-ID: <20261020145059.2146170-1-utilityemal77@gmail.com> (raw)

Howdy folks,

Fixes to the lifetime of trusted pointers derived from other pointers:
fields walked out of a parent, and elements produced by an iterator.

A field in the __safe_trusted or __safe_trusted_or_null sets becomes
PTR_TRUSTED regardless of how its parent is kept alive: nothing ties
the resulting pointer to its parent's lifetime, even though kfuncs.rst
defines the annotations as marking a field "guaranteed to be valid
(trusted or rcu ...) as long as its parent pointer is valid". The
documented bound was never enforced. There are two separate cases,
RCU-protected parents and referenced parents.

First, an RCU-protected parent, e.g. mm->exe_file read under
bpf_rcu_read_lock(), is MEM_RCU. It can hand out file->f_inode as
fully trusted, and the inode pointer survives bpf_rcu_read_unlock().
It remains dereferenceable without PROBE_MEM and passable to kfuncs
expecting trusted arguments after the grace period.

Second, a referenced parent has the same lifetime problem with release
kfuncs. A trusted field walked out of an acquired object stays usable
even after the reference to its parent is dropped. An in-tree example:
the file acquired from bpf_get_task_exe_file() is released at
bpf_put_file(), but an f_inode taken out of it stays trusted after the
object may be freed.

Fix both by making the walked field inherit its parent's bound.
Patch 1 substitutes MEM_RCU for PTR_TRUSTED when the parent is
MEM_RCU, so the field is invalidated with the critical section like
every other RCU pointer. Patch 3 sets the walked field's parent_id to
the parent's reference. Programs that relied on either escape will no
longer load, but the behavior they relied on was essentially a
use-after-free being papered over with deferred free mechanisms and
refcounts held outside BPF.

Third, the same gap exists for open-coded iterators. The element
returned by bpf_iter_<type>_next() is kept alive by the iterator, yet
the verifier marks it plain PTR_TRUSTED with nothing tying it to the
iterator's reference. bpf_iter_task_vma_next() returns a snapshot
from the iterator's own allocation, with the vma's vm_file reference
held only until the next step or destroy, and the kmem_cache and
dmabuf iterators hand out objects whose reference the iterator drops
the same way. A saved element, or a trusted field walked out of it,
stays usable after bpf_iter_<type>_destroy() freed it. Patch 5
binds trusted elements to the iterator's reference, as already done
for the PTR_TO_MEM elements of bpf_iter_num_next(). Elements of
RCU-protected iterators (task, css, scx_dsq) keep MEM_RCU and stay
bounded by the critical section; they point at RCU-managed objects, and
in-tree programs legitimately return them past the iterator's
destruction (__COMPAT_scx_bpf_dsq_peek()).

With the three bounds in place, a trusted field is valid exactly as
long as whatever pins its parent: the program (hook arguments), a
reference (released by a kfunc or an iterator destroy), or an RCU
critical section.

Patches 2, 4 and 6 add reject and accept selftests for each.

Changes in v2:
- Trusted fields of an RCU parent are PTR_MAYBE_NULL as well as
  MEM_RCU: the parent may be a SLAB_TYPESAFE_BY_RCU object reused
  under the reader, as Sashiko pointed out for file->f_inode
  (patches 1, 2).
- Bind trusted iterator elements to the iterator (patches 5, 6).
- Cc stable on the three fixes.
- v1: https://lore.kernel.org/bpf/20261014173039.3666415-1-utilityemal77@gmail.com/

Justin

Justin Suess (6):
  bpf: Carry MEM_RCU for trusted fields with MEM_RCU parents
  selftests/bpf: Test MEM_RCU carry-over for trusted fields
  bpf: Bind trusted fields to their parent's reference
  selftests/bpf: Test trusted-field invalidation on parent release
  bpf: Bind iterator elements to their iterator
  selftests/bpf: Test iterator element invalidation on destroy

 Documentation/bpf/bpf_iterators.rst           |  6 +-
 kernel/bpf/verifier.c                         | 24 ++++++-
 .../selftests/bpf/progs/iters_task_failure.c  | 68 ++++++++++++++++++
 .../selftests/bpf/progs/verifier_vfs_accept.c | 41 +++++++++++
 .../selftests/bpf/progs/verifier_vfs_reject.c | 70 +++++++++++++++++++
 5 files changed, 206 insertions(+), 3 deletions(-)


base-commit: 763187dbbf83764a57d5811168ef9de7b9a60e2d
-- 
2.55.0


             reply	other threads:[~2026-10-20 14:56 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 14:50 Justin Suess [this message]
2026-10-20 14:50 ` [PATCH bpf-next v2 1/6] bpf: Carry MEM_RCU for trusted fields with MEM_RCU parents Justin Suess
2026-10-20 14:50 ` [PATCH bpf-next v2 2/6] selftests/bpf: Test MEM_RCU carry-over for trusted fields Justin Suess
2026-10-20 14:50 ` [PATCH bpf-next v2 3/6] bpf: Bind trusted fields to their parent's reference Justin Suess
2026-10-20 14:50 ` [PATCH bpf-next v2 4/6] selftests/bpf: Test trusted-field invalidation on parent release Justin Suess
2026-10-20 14:50 ` [PATCH bpf-next v2 5/6] bpf: Bind iterator elements to their iterator Justin Suess
2026-10-20 15:25   ` bot+bpf-ci
2026-10-20 15:29   ` sashiko-bot
2026-10-20 14:50 ` [PATCH bpf-next v2 6/6] selftests/bpf: Test iterator element invalidation on destroy Justin Suess

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=20261020145059.2146170-1-utilityemal77@gmail.com \
    --to=utilityemal77@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=memxor@gmail.com \
    --cc=puranjay@kernel.org \
    --cc=song@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