BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next v3 0/5] bpf: bound trusted fields and derived returns to their parent's lifetime
@ 2026-10-23 21:20 Justin Suess
  2026-10-23 21:20 ` [PATCH bpf-next v3 1/5] bpf: Don't apply the trusted field lists to an RCU-protected parent Justin Suess
                   ` (4 more replies)
  0 siblings, 5 replies; 8+ messages in thread
From: Justin Suess @ 2026-10-23 21:20 UTC (permalink / raw)
  To: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
	Eduard Zingerman, Kumar Kartikeya Dwivedi
  Cc: Song Liu, Chris Mason, Xu Yunxiang, Amery Hung, Christian Brauner,
	bpf, Justin Suess

Howdy folks,

Fixes to the lifetime of trusted pointers derived from other pointers:
fields walked out of an RCU-protected parent, and returns a kfunc
borrows from one of its arguments.

A field in the __safe_trusted or __safe_trusted_or_null sets becomes
PTR_TRUSTED regardless of how its parent is kept alive, 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".
For an RCU-protected parent that bound was never enforced: mm->exe_file
read under bpf_rcu_read_lock() is MEM_RCU, yet it hands 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. Patch 1 stops applying the trusted lists to a parent that is
not itself trusted, and moves file->f_inode to the __safe_rcu_or_null
list, since inode is RCU-freed and a SLAB_TYPESAFE_BY_RCU file read
under RCU may have been reused with a NULL f_inode. Patch 2 adds the
tests.

A kfunc that returns a pointer it borrows from an argument, without
taking a reference of its own, has the same gap one level up: the
verifier types the return as trusted for the whole program.
bpf_real_data_inode(file) hands out an inode the file keeps alive, and
it stays usable after bpf_put_file(). Patch 3 adds a __derives_ret
argument annotation: the return inherits whatever keeps that argument
alive, its reference or its parent_id, and a return derived from an
RCU-protected argument of a KF_RCU kfunc is MEM_RCU. Patch 4 annotates
bpf_real_data_inode(), patch 5 adds the tests.

The referenced-parent case, a trusted field walked out of an acquired
object staying trusted after the reference is released, was patch 3 of
v2. It is dropped here along with the iterator patches: Xu Yunxiang's
series [1] carries the same field-load rule and binds iterator
elements to the iterator as well, so this series only keeps what it
does not cover. Patch 3 introduces reg_lifetime_id() in the same shape
as [1] so the two merge cleanly in either order.

With both series in, a trusted pointer is valid exactly as long as
whatever pins the pointer it was derived from: the program (hook
arguments), a reference (released by a kfunc), or an RCU critical
section.

Changes in v3:
- Rework patch 1 as Alexei suggested: gate the trusted lists on
  is_trusted_reg() instead of substituting MEM_RCU for PTR_TRUSTED,
  which would have handed out non-RCU-freed objects such as
  vma->vm_mm as RCU pointers; add file->f_inode to __safe_rcu_or_null.
  Not for stable.
- Add the __derives_ret annotation, the bpf_real_data_inode()
  annotation and their tests (patches 3-5), as Kumar suggested.
- Drop the referenced-parent field binding and the iterator patches in
  favor of [1].
- Rebase onto bpf-next b116ac608754.
- v2: https://lore.kernel.org/bpf/20261020145059.2146170-1-utilityemal77@gmail.com/

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/

[1] https://lore.kernel.org/bpf/20261021210754.3270023-1-xyx2021@mail.ustc.edu.cn/

Justin

Justin Suess (5):
  bpf: Don't apply the trusted field lists to an RCU-protected parent
  selftests/bpf: Test f_inode of an RCU-protected file
  bpf: Add a __derives_ret kfunc argument annotation
  bpf: Bind the inode bpf_real_data_inode() returns to the file
  selftests/bpf: Test __derives_ret return invalidation on argument
    release

 Documentation/bpf/kfuncs.rst                  | 31 ++++++++
 fs/bpf_fs_kfuncs.c                            |  9 ++-
 include/linux/bpf_verifier.h                  |  6 ++
 kernel/bpf/btf.c                              | 35 ++++++++-
 kernel/bpf/verifier.c                         | 48 +++++++++++-
 .../testing/selftests/bpf/bpf_experimental.h  |  9 +++
 .../selftests/bpf/prog_tests/verifier.c       |  2 +
 .../bpf/progs/verifier_derives_ret.c          | 50 +++++++++++++
 .../selftests/bpf/progs/verifier_vfs_accept.c | 44 +++++++++++
 .../selftests/bpf/progs/verifier_vfs_reject.c | 73 +++++++++++++++++++
 .../selftests/bpf/test_kmods/bpf_testmod.c    |  4 +-
 .../bpf/test_kmods/bpf_testmod_kfunc.h        |  2 +-
 12 files changed, 302 insertions(+), 11 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/verifier_derives_ret.c


base-commit: b116ac6087541d3d98031e786adbe9c733cd6df3
-- 
2.55.0


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

end of thread, other threads:[~2026-10-23 21:58 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-23 21:20 [PATCH bpf-next v3 0/5] bpf: bound trusted fields and derived returns to their parent's lifetime Justin Suess
2026-10-23 21:20 ` [PATCH bpf-next v3 1/5] bpf: Don't apply the trusted field lists to an RCU-protected parent Justin Suess
2026-10-23 21:58   ` sashiko-bot
2026-10-23 21:20 ` [PATCH bpf-next v3 2/5] selftests/bpf: Test f_inode of an RCU-protected file Justin Suess
2026-10-23 21:20 ` [PATCH bpf-next v3 3/5] bpf: Add a __derives_ret kfunc argument annotation Justin Suess
2026-10-23 21:52   ` sashiko-bot
2026-10-23 21:20 ` [PATCH bpf-next v3 4/5] bpf: Bind the inode bpf_real_data_inode() returns to the file Justin Suess
2026-10-23 21:20 ` [PATCH bpf-next v3 5/5] selftests/bpf: Test __derives_ret return invalidation on argument release Justin Suess

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