> mm/page_owner: add open-coded page_owner iterator

TL;DR: The new page_owner kfuncs may lack KF_PERFMON, so a CAP_BPF-only
syscall program could read page_owner records and symbolized allocation stacks
that are root-only in debugfs.

> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index a284f20c97d5..85ce368315f9 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c

[ ... ]

> @@ -5177,6 +5177,12 @@ BTF_ID_FLAGS(func, bpf_iter_dmabuf_new, KF_ITER_NEW | 
> KF_SLEEPABLE)
>  BTF_ID_FLAGS(func, bpf_iter_dmabuf_next, KF_ITER_NEXT | KF_RET_NULL | 
> KF_SLEEPABLE)
>  BTF_ID_FLAGS(func, bpf_iter_dmabuf_destroy, KF_ITER_DESTROY | KF_SLEEPABLE)
>  #endif
> +#ifdef CONFIG_PAGE_OWNER
> +BTF_ID_FLAGS(func, bpf_iter_page_owner_new, KF_ITER_NEW | KF_SLEEPABLE)
> +BTF_ID_FLAGS(func, bpf_iter_page_owner_next, KF_ITER_NEXT | KF_RET_NULL | 
> KF_SLEEPABLE)
> +BTF_ID_FLAGS(func, bpf_iter_page_owner_destroy, KF_ITER_DESTROY | 
> KF_SLEEPABLE)
> +BTF_ID_FLAGS(func, bpf_page_owner_stack_snprint, KF_SLEEPABLE)
> +#endif
>  BTF_ID_FLAGS(func, __bpf_trap)
>  BTF_ID_FLAGS(func, bpf_strcmp, KF_PERFMON);
>  BTF_ID_FLAGS(func, bpf_strcasecmp, KF_PERFMON);

Should bpf_page_owner_stack_snprint(), and probably bpf_iter_page_owner_new(),
carry KF_PERFMON here?

These kfuncs are added to common_btf_ids, which is registered for
BPF_PROG_TYPE_UNSPEC, and none of them has KF_PERFMON.

BPF_PROG_TYPE_SYSCALL programs are always sleepable (check_attach_btf_id()
requires it), and they only need CAP_BPF (or a delegated BPF token) since
SYSCALL is not covered by is_perfmon_prog_type().

That means a CAP_BPF-only loader can walk all page_owner records and use
bpf_page_owner_stack_snprint() to copy symbolized allocation stack traces
into program memory.  This skips the allow_ptr_leaks gate that
check_ptr_to_btf_access() applies when the same data is read field by field.

The debugfs interface that exposes this information is root-only: page_owner
is 0600 and the page_owner_stacks/* files are 0400.

This tree already has KF_PERFMON (commit 88ce88e933e4 "bpf: Add KF_PERFMON
kfunc flag"), and comparable kfuncs use it, for example bpf_get_kmem_cache()
and bpf_probe_read_kernel_dynptr() in this same table.


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/38403671988

Reply via email to