All of lore.kernel.org
 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>,
	stable@vger.kernel.org
Subject: [PATCH bpf-next v2 5/6] bpf: Bind iterator elements to their iterator
Date: Tue, 20 Oct 2026 10:50:58 -0400	[thread overview]
Message-ID: <20261020145059.2146170-6-utilityemal77@gmail.com> (raw)
In-Reply-To: <20261020145059.2146170-1-utilityemal77@gmail.com>

An element returned by an iterator's next() kfunc is kept alive by the
iterator alone. bpf_iter_task_vma_next() returns a snapshot that lives
in the iterator's own allocation and holds the vma's vm_file reference
only until the next step or destroy; bpf_iter_kmem_cache_next() and
bpf_iter_dmabuf_next() hand out objects whose reference the iterator
drops the same way. The verifier marks every such element PTR_TRUSTED
with nothing tying it to the iterator, so a pointer saved across
bpf_iter_<type>_destroy() stays fully trusted after the memory or the
reference behind it is gone:

	bpf_iter_task_vma_new(&it, task, 0);
	vma = bpf_iter_task_vma_next(&it);
	file = vma->vm_file;			/* __safe_trusted_or_null */
	bpf_iter_task_vma_destroy(&it);		/* frees snapshot, fput() */
	start = vma->vm_start;			/* vma, file still trusted */

Set the element's parent_id to the iterator's reference id, as is
already done for the PTR_TO_MEM elements of bpf_iter_num_next(), so
that destroying the iterator invalidates the element together with
every trusted field acquired from it. Elements of an RCU-protected
iterator keep MEM_RCU and stay bounded by the critical section instead:
they point at RCU-managed objects rather than iterator state.

Fixes: 4ac454682158 ("bpf: Introduce task_vma open-coded iterator kfuncs")
Cc: stable@vger.kernel.org
Signed-off-by: Justin Suess <utilityemal77@gmail.com>
---
 Documentation/bpf/bpf_iterators.rst |  6 +++++-
 kernel/bpf/verifier.c               | 13 +++++++++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/Documentation/bpf/bpf_iterators.rst b/Documentation/bpf/bpf_iterators.rst
index 189e3ec1c6c8..08c9c15b59ac 100644
--- a/Documentation/bpf/bpf_iterators.rst
+++ b/Documentation/bpf/bpf_iterators.rst
@@ -79,7 +79,11 @@ Constructor/next/destructor implementation contract is as follows:
     will eventually return NULL when elements are exhausted. Once NULL is
     returned, subsequent next calls *should keep returning NULL*. Next method
     is marked with KF_ITER_NEXT (and should also have KF_RET_NULL as
-    NULL-returning kfunc, of course).
+    NULL-returning kfunc, of course). An element is only guaranteed to be
+    valid until the iterator is destroyed, so the verifier invalidates it,
+    and every trusted pointer derived from it, at `bpf_iter_<type>_destroy()`.
+    Elements of an RCU-protected iterator (see KF_RCU_PROTECTED) are instead
+    valid until the end of the RCU critical section.
 
   - destructor, `bpf_iter_<type>_destroy()`, is always called once. Even if
     constructor failed or next returned nothing.  Destructor frees up any
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index c85c83a6ee63..9ce5517dc1a0 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -15504,6 +15504,19 @@ static int check_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn,
 			regs[BPF_REG_0].btf = desc_btf;
 			regs[BPF_REG_0].type = type;
 			regs[BPF_REG_0].btf_id = ptr_type_id;
+
+			/*
+			 * A trusted element is pinned by the iterator that
+			 * produced it and dies with it, like the memory
+			 * returned by bpf_iter_num_next() above. An RCU
+			 * element is bounded by the critical section instead.
+			 */
+			if (bpf_is_iter_next_kfunc(&meta) && (type & PTR_TRUSTED)) {
+				err = validate_ref_obj(env, &meta.ref_obj);
+				if (err)
+					return err;
+				regs[BPF_REG_0].parent_id = meta.ref_obj.id;
+			}
 		}
 
 		if (is_kfunc_ret_null(&meta)) {
-- 
2.55.0


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

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-20 14:50 [PATCH bpf-next v2 0/6] bpf: bound trusted fields to their parent's lifetime Justin Suess
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-21  0:37   ` Alexei Starovoitov
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-21  1:16   ` Kumar Kartikeya Dwivedi
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 ` Justin Suess [this message]
2026-10-20 15:25   ` [PATCH bpf-next v2 5/6] bpf: Bind iterator elements to their iterator bot+bpf-ci
2026-10-20 15:29   ` sashiko-bot
2026-10-21  0:57   ` Kumar Kartikeya Dwivedi
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-6-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 \
    --cc=stable@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.