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>, Chris Mason <mason@kernel.org>,
Xu Yunxiang <xyx2021@mail.ustc.edu.cn>,
Amery Hung <ameryhung@gmail.com>,
Christian Brauner <brauner@kernel.org>,
bpf@vger.kernel.org, Justin Suess <utilityemal77@gmail.com>
Subject: [PATCH bpf-next v3 1/5] bpf: Don't apply the trusted field lists to an RCU-protected parent
Date: Fri, 23 Oct 2026 17:20:37 -0400 [thread overview]
Message-ID: <20261023212041.884996-2-utilityemal77@gmail.com> (raw)
In-Reply-To: <20261023212041.884996-1-utilityemal77@gmail.com>
Walking a field in the __safe_trusted or __safe_trusted_or_null set
yields PTR_TRUSTED whenever the parent is trusted or RCU-protected. For
an RCU-protected parent that is wrong: RCU only keeps the parent's
memory valid, and the resulting pointer survives bpf_rcu_read_unlock()
as fully trusted. mm->exe_file read under bpf_rcu_read_lock() is
MEM_RCU, and file->f_inode walked out of it escapes the RCU critical
section as a trusted inode that can be dereferenced without PROBE_MEM
and passed to kfuncs expecting trusted arguments after the grace period.
Substituting MEM_RCU for PTR_TRUSTED on an RCU parent is not a fix
either. A field of an RCU-protected object is only safe to read under
RCU if the object it points to is itself RCU-freed: inode is, but
mm_struct is not, as __mmdrop() does kmem_cache_free() without a grace
period, so an RCU-protected vma would hand out vma->vm_mm as an RCU
pointer that can be freed under the reader.
Apply the trusted lists only to a trusted parent, so a field of an
RCU-protected parent falls through to the RCU lists and is otherwise
untrusted. Add file->f_inode to the __safe_rcu_or_null list: inode is
RCU-freed, and struct file is SLAB_TYPESAFE_BY_RCU, so a file read
under RCU may have been freed and reused, in which case init_file() has
zeroed f_inode. The field may be NULL and programs have to check it.
exe_file->f_inode is now rcu_ptr_or_null_inode, bounded by the critical
section like every other RCU pointer.
Fixes: 6fcd486b3a0a ("bpf: Refactor RCU enforcement in the verifier.")
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Justin Suess <utilityemal77@gmail.com>
---
kernel/bpf/verifier.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 5601d2056218..4a32875d7077 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6517,6 +6517,11 @@ BTF_TYPE_SAFE_RCU_OR_NULL(struct request_sock) {
struct sock *sk;
};
+/* struct file is SLAB_TYPESAFE_BY_RCU. A reused file has f_inode == NULL. */
+BTF_TYPE_SAFE_RCU_OR_NULL(struct file) {
+ struct inode *f_inode;
+};
+
/* full trusted: these fields are trusted even outside of RCU CS and never NULL */
BTF_TYPE_SAFE_TRUSTED(struct bpf_iter_meta) {
struct seq_file *seq;
@@ -6593,6 +6598,7 @@ static bool type_is_rcu_or_null(struct bpf_verifier_env *env,
BTF_TYPE_EMIT(BTF_TYPE_SAFE_RCU_OR_NULL(struct mm_struct));
BTF_TYPE_EMIT(BTF_TYPE_SAFE_RCU_OR_NULL(struct sk_buff));
BTF_TYPE_EMIT(BTF_TYPE_SAFE_RCU_OR_NULL(struct request_sock));
+ BTF_TYPE_EMIT(BTF_TYPE_SAFE_RCU_OR_NULL(struct file));
return btf_nested_type_is_trusted(&env->log, reg, field_name, btf_id, "__safe_rcu_or_null");
}
@@ -6798,10 +6804,14 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
*
* A regular RCU-protected pointer with __rcu tag can also be deemed
* trusted if we are in an RCU CS. Such pointer can be NULL.
+ *
+ * If the parent is not trusted, the field can't regain trusted status.
*/
- if (type_is_trusted(env, reg, field_name, btf_id)) {
+ bool trusted = is_trusted_reg(env, reg);
+
+ if (trusted && type_is_trusted(env, reg, field_name, btf_id)) {
flag |= PTR_TRUSTED;
- } else if (type_is_trusted_or_null(env, reg, field_name, btf_id)) {
+ } else if (trusted && type_is_trusted_or_null(env, reg, field_name, btf_id)) {
flag |= PTR_TRUSTED | PTR_MAYBE_NULL;
} else if (in_rcu_cs(env) && !type_may_be_null(reg->type)) {
if (type_is_rcu(env, reg, field_name, btf_id)) {
--
2.55.0
next prev parent reply other threads:[~2026-10-23 21:21 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Justin Suess [this message]
2026-10-23 21:58 ` [PATCH bpf-next v3 1/5] bpf: Don't apply the trusted field lists to an RCU-protected parent 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
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=20261023212041.884996-2-utilityemal77@gmail.com \
--to=utilityemal77@gmail.com \
--cc=ameryhung@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brauner@kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=mason@kernel.org \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=xyx2021@mail.ustc.edu.cn \
/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.