* [PATCH bpf] bpf, lsm: Mark backing_file_alloc/free LSM hooks as untrusted
@ 2026-11-11 20:35 Sergei Nizovtsev
0 siblings, 0 replies; only message in thread
From: Sergei Nizovtsev @ 2026-11-11 20:35 UTC (permalink / raw)
To: bpf
Cc: linux-security-module, Sergei Nizovtsev, stable, KP Singh,
Matt Bobrowski, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Serge Hallyn, Amir Goldstein,
Paul Moore, Christian Brauner, linux-kernel
The backing_file_alloc and backing_file_free LSM hooks get the backing
file as "struct file *backing_file", but its f_path is not populated
while they run:
- security_backing_file_alloc() is called from init_backing_file() in
alloc_empty_backing_file(), before vfs_open() sets f_path, so
backing_file->f_path.dentry is NULL;
- security_backing_file_free() can run for a backing file whose open
failed and whose f_path was already cleared.
Neither hook is listed in untrusted_lsm_hooks, so bpf_lsm_is_trusted()
lets BPF LSM programs use the argument as a trusted pointer. A program
attached to lsm/backing_file_alloc can pass &backing_file->f_path to the
trusted-args kfunc bpf_path_d_path(), and d_path() dereferences the NULL
dentry on the first open of a file on overlayfs:
extern int bpf_path_d_path(const struct path *path, char *buf,
size_t sz) __ksym;
char buf[256];
SEC("lsm/backing_file_alloc")
int BPF_PROG(poc, struct file *backing_file,
const struct file *user_file)
{
bpf_path_d_path(&backing_file->f_path, buf, sizeof(buf));
return 0;
}
# bpftool prog load poc.bpf.o /sys/fs/bpf/poc autoattach
# cat <any file on an overlayfs mount>
Oops: general protection fault, probably for non-canonical address 0xdffffc000000000c: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000060-0x0000000000000067]
RIP: 0010:d_path+0xb4/0x810
Call Trace:
bpf_path_d_path+0x26/0x70
bpf_prog_f8f2e241d4ff7217_poc+0x33/0x37
bpf_trampoline_6442521065+0x61/0xf9
security_backing_file_alloc+0x78/0xe0
alloc_empty_backing_file+0xf0/0x170
backing_file_open+0xfd/0x290
ovl_open_realfile+0x1ed/0x270
ovl_open+0x1a9/0x2f0
do_dentry_open+0x404/0x1280
vfs_open_consume+0xba/0x4b0
path_openat+0xc4f/0x1f60
Add both hooks to untrusted_lsm_hooks, next to file_alloc_security and
file_free_security, which are listed there for the same reason. The
program above is then rejected at load time with "R1 must be referenced
or trusted".
Fixes: 6af36aeb147a ("lsm: add backing_file LSM hooks")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5-2
Signed-off-by: Sergei Nizovtsev <snizovtsev@cloudlinux.com>
---
Tested on bpf.git master (475a0cfd02f1) under virtme-ng with KASAN: the
reproducer oopses without the patch and fails to load with it. Only the
backing_file_alloc case was reproduced; backing_file_free is from code
reading.
kernel/bpf/bpf_lsm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c
index f58dce888ff4a..f39a3766f2245 100644
--- a/kernel/bpf/bpf_lsm.c
+++ b/kernel/bpf/bpf_lsm.c
@@ -411,6 +411,8 @@ BTF_ID(func, bpf_lsm_bpf_map_free)
BTF_ID(func, bpf_lsm_bpf_prog_free)
BTF_ID(func, bpf_lsm_file_alloc_security)
BTF_ID(func, bpf_lsm_file_free_security)
+BTF_ID(func, bpf_lsm_backing_file_alloc)
+BTF_ID(func, bpf_lsm_backing_file_free)
#ifdef CONFIG_SECURITY_NETWORK
BTF_ID(func, bpf_lsm_sk_alloc_security)
BTF_ID(func, bpf_lsm_sk_free_security)
--
2.56.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-11-11 20:36 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-11 20:35 [PATCH bpf] bpf, lsm: Mark backing_file_alloc/free LSM hooks as untrusted Sergei Nizovtsev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®