Skip to content

Commit 07005ff

Browse files
olsajiriFishwaldo
authored andcommitted
bpf: Add extra path pointer check to d_path helper
[ Upstream commit f46fab0 ] Anastasios reported crash on stable 5.15 kernel with following BPF attached to lsm hook: SEC("lsm.s/bprm_creds_for_exec") int BPF_PROG(bprm_creds_for_exec, struct linux_binprm *bprm) { struct path *path = &bprm->executable->f_path; char p[128] = { 0 }; bpf_d_path(path, p, 128); return 0; } But bprm->executable can be NULL, so bpf_d_path call will crash: BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [Fishwaldo#1] PREEMPT SMP DEBUG_PAGEALLOC NOPTI ... RIP: 0010:d_path+0x22/0x280 ... Call Trace: <TASK> bpf_d_path+0x21/0x60 bpf_prog_db9cf176e84498d9_bprm_creds_for_exec+0x94/0x99 bpf_trampoline_6442506293_0+0x55/0x1000 bpf_lsm_bprm_creds_for_exec+0x5/0x10 security_bprm_creds_for_exec+0x29/0x40 bprm_execve+0x1c1/0x900 do_execveat_common.isra.0+0x1af/0x260 __x64_sys_execve+0x32/0x40 It's problem for all stable trees with bpf_d_path helper, which was added in 5.9. This issue is fixed in current bpf code, where we identify and mark trusted pointers, so the above code would fail even to load. For the sake of the stable trees and to workaround potentially broken verifier in the future, adding the code that reads the path object from the passed pointer and verifies it's valid in kernel space. Fixes: 6e22ab9 ("bpf: Add d_path helper") Reported-by: Anastasios Papagiannis <tasos.papagiannnis@gmail.com> Suggested-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Stanislav Fomichev <sdf@google.com> Acked-by: Yonghong Song <yhs@fb.com> Link: https://lore.kernel.org/bpf/20230606181714.532998-1-jolsa@kernel.org Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent f95cfcf commit 07005ff

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

kernel/trace/bpf_trace.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -849,13 +849,23 @@ static const struct bpf_func_proto bpf_send_signal_thread_proto = {
849849

850850
BPF_CALL_3(bpf_d_path, struct path *, path, char *, buf, u32, sz)
851851
{
852+
struct path copy;
852853
long len;
853854
char *p;
854855

855856
if (!sz)
856857
return 0;
857858

858-
p = d_path(path, buf, sz);
859+
/*
860+
* The path pointer is verified as trusted and safe to use,
861+
* but let's double check it's valid anyway to workaround
862+
* potentially broken verifier.
863+
*/
864+
len = copy_from_kernel_nofault(&copy, path, sizeof(*path));
865+
if (len < 0)
866+
return len;
867+
868+
p = d_path(&copy, buf, sz);
859869
if (IS_ERR(p)) {
860870
len = PTR_ERR(p);
861871
} else {

0 commit comments

Comments
 (0)