BPF List
 help / color / mirror / Atom feed
From: Chris Mason <mason@kernel.org>
To: mason@kernel.org, bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	eddyz87@gmail.com, memxor@gmail.com, brauner@kernel.org
Subject: [PATCH RFC 1/2] bpf: fix UAF via trusted BTF walk after release
Date: Wed, 16 Sep 2026 18:33:02 +0000	[thread overview]
Message-ID: <20260916183303.3504885-2-mason@kernel.org> (raw)
In-Reply-To: <20260916183303.3504885-1-mason@kernel.org>

A BPF program can keep dereferencing a trusted pointer that it loaded
from a referenced object after it has released that reference. With a
file from bpf_get_task_exe_file(), f->f_inode stays usable after
bpf_put_file(), and loads through it read freed or reused inode memory.

A pointer derived from a referenced object is only valid while the
reference is held. release_reference() enforces that by invalidating
every register whose id or parent_id matches the released id. However,
check_ptr_to_btf_access() builds the loaded register with
mark_btf_ld_reg(), which is not given the source register and zeroes
both fields. The verifier state for the f_inode case:

    file = bpf_get_task_exe_file(task)   file:  id=N, referenced
    inode = file->f_inode                inode: trusted, id=0,
                                                parent_id=0
    bpf_put_file(file)                   release_reference(N)
                                           skips inode
    inode->i_ino                         accepted, unprobed load

Reproduced by reading inode->i_ino after bpf_put_file() once the task
owning the file had exited and new fds were created.

Fix this by recording the source's reference id in the parent_id of a
trusted PTR_TO_BTF_ID load. A program that dereferences such a pointer
after the release is now rejected with "invalid mem access 'scalar'".

Assisted-by: kres
Fixes: 57539b1c0ac2 ("bpf: Enable annotating trusted nested pointers")
Signed-off-by: Chris Mason <mason@kernel.org>
---
 kernel/bpf/verifier.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6c6b8d8520cd..8b48bf796823 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -6219,9 +6219,25 @@ static int check_ptr_to_btf_access(struct bpf_verifier_env *env,
 	}
 
 	if (atype == BPF_READ && value_regno >= 0) {
+		u32 link_id = 0;
+
+		/*
+		 * A trusted pointer walked from a referenced object is only
+		 * valid while that reference is held. Remember the reference
+		 * id of the source, or the one it inherited, so that
+		 * release_reference() invalidates the loaded register too.
+		 * Read it now, reg may alias regs[value_regno].
+		 */
+		if (ret == PTR_TO_BTF_ID && (flag & PTR_TRUSTED))
+			link_id = reg_is_referenced(env, reg) ? reg->id : reg->parent_id;
+
 		ret = mark_btf_ld_reg(env, regs, value_regno, ret, reg->btf, btf_id, flag);
 		if (ret < 0)
 			return ret;
+
+		/* mark_btf_ld_reg() cleared parent_id, set it afterwards. */
+		if (link_id)
+			regs[value_regno].parent_id = link_id;
 	}
 
 	return 0;
-- 
2.54.0


  reply	other threads:[~2026-09-16 18:33 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-16 18:33 [PATCH RFC 0/2] Fix use-after-free related to binfmt-misc-bpf.c Chris Mason
2026-09-16 18:33 ` Chris Mason [this message]
2026-09-16 18:46   ` [PATCH RFC 1/2] bpf: fix UAF via trusted BTF walk after release Kumar Kartikeya Dwivedi
2026-09-16 19:19     ` Chris Mason
2026-09-16 18:33 ` [PATCH RFC 2/2] selftests/bpf: test f_inode walk around bpf_put_file() Chris Mason

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=20260916183303.3504885-2-mason@kernel.org \
    --to=mason@kernel.org \
    --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=memxor@gmail.com \
    /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