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
next 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