From: sashiko-bot@kernel.org
To: "Jiri Olsa" <jolsa@kernel.org>,
"Alexei Starovoitov" <ast@kernel.org>,
"Daniel Borkmann" <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org, "Andrii Nakryiko" <andrii@kernel.org>,
"Eduard Zingerman" <eddyz87@gmail.com>,
"Kumar Kartikeya Dwivedi" <memxor@gmail.com>,
linux-mm@kvack.org, "Andrew Morton" <akpm@linux-foundation.org>,
"Liam R. Howlett" <liam@infradead.org>,
"Lorenzo Stoakes" <ljs@kernel.org>,
"Shuah Khan" <shuah@kernel.org>,
"John Fastabend" <john.fastabend@gmail.com>
Subject: Re: [RFC bpf-next 2/9] bpf: Add uprobe faultable user copy kfunc
Date: Wed, 21 Oct 2026 20:22:24 +0000 [thread overview]
Message-ID: <sashiko-outbox-180638@kernel.org> (raw)
In-Reply-To: <20261021195759.119421-3-jolsa@kernel.org>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] bpf: missing CAP_SYS_ADMIN check in user_mem_kfunc_filter()
- [High] bpf: hardened usercopy BUG() in bpf_probe_write_user_faultable()
- [Medium] bpf: missing prog->sleepable check in user_mem_kfunc_filter()
- [Low] bpf: unused enum user_mem_kfunc_id in kernel/bpf/helpers.c
--
commit bbd6dece6abea0ce7dfa98ce448c7aae57de64d1
Author: Jiri Olsa <jolsa@kernel.org>
bpf: Add uprobe faultable user copy kfunc
This patch adds the bpf_probe_write_user_faultable() sleepable kfunc to copy
data to user memory with page faults enabled. It registers the kfunc for
BPF_PROG_TYPE_KPROBE programs and filters access with
LOCKDOWN_BPF_WRITE_USER.
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 648abe1ba63ae..4d9e9423826a9 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
[ ... ]
> @@ -3738,6 +3739,36 @@ __bpf_kfunc int bpf_copy_from_user_mm(void *dst, u32 dst__sz,
> return ret;
> }
>
> +/**
> + * bpf_probe_write_user_faultable() - Copy data to userspace with page faults
> + * enabled
> + * @unsafe_dst__ign: Destination address in the current task's address space.
> + * @src__srcptr: Source buffer in BPF-accessible memory.
> + * @src__sz: Number of bytes to copy.
> + *
> + * Copies data to userspace, allowing page faults to resolve the destination
> + * mapping. A failed copy may have written a prefix of the source buffer.
> + *
> + * Return: 0 on success, -EFAULT if the copy is incomplete, or -EPERM if the
> + * current task cannot safely access userspace.
> + */
> +__bpf_kfunc int bpf_probe_write_user_faultable(void __user *unsafe_dst__ign,
> + const void *src__srcptr,
> + u32 src__sz)
> +{
> + if (unlikely(in_interrupt() ||
> + current->flags & (PF_KTHREAD | PF_EXITING)))
> + return -EPERM;
> + if (unlikely(!nmi_uaccess_okay()))
> + return -EPERM;
> + if (unlikely(!current->mm))
> + return -EFAULT;
> + if (copy_to_user(unsafe_dst__ign, src__srcptr, src__sz))
> + return -EFAULT;
[Severity: High]
Can calling copy_to_user() directly on src__srcptr trigger a hardened
usercopy bug when a BPF program passes a trusted BTF object pointer?
In kernel/bpf/verifier.c, get_kfunc_arg_type() classifies src__srcptr paired
with src__sz as ARG_PTR_TO_MEM | MEM_RDONLY. During verification,
check_reg_type() permits mem_types, which includes:
kernel/bpf/verifier.c:
PTR_TO_BTF_ID | PTR_TRUSTED,
and check_helper_mem_access() allows BPF_READ access on scalar fields of
trusted BTF objects (such as &task->pid or task->comm from
bpf_get_current_task_btf()).
At runtime, copy_to_user() calls check_copy_size(src__srcptr, src__sz, true)
-> __check_object_size() -> __check_heap_object() in mm/slub.c:
mm/slub.c:__check_heap_object() {
...
usercopy_abort("SLUB object", s->name, to_user, offset, n);
}
When src__srcptr points to a field in a dedicated slab cache outside its
whitelisted usercopy region (for example task_struct_cachep, mm_cachep,
files_cachep, or fs_cachep), wouldn't __check_heap_object() call
usercopy_abort() and panic the kernel when CONFIG_HARDENED_USERCOPY is
enabled?
> +
> + return 0;
> +}
> +
> /**
> * bpf_copy_from_user_mm_str() - Copy a string from an address space
> * @dst: Destination address, in kernel space. This buffer must be
> @@ -5139,6 +5170,31 @@ static const struct btf_kfunc_id_set generic_kfunc_set = {
> .set = &generic_btf_ids,
> };
>
> +BTF_KFUNCS_START(user_mem_btf_ids)
> +BTF_ID_FLAGS(func, bpf_probe_write_user_faultable, KF_SLEEPABLE | KF_PERFMON)
> +BTF_KFUNCS_END(user_mem_btf_ids)
> +
> +enum user_mem_kfunc_id {
> + KF_bpf_probe_write_user_faultable,
> +};
[Severity: Low]
Is enum user_mem_kfunc_id left over from an earlier version of the patch?
Since user_mem_kfunc_filter() compares kfunc_id against
bpf_probe_write_user_faultable_btf_id[0], neither enum user_mem_kfunc_id nor
KF_bpf_probe_write_user_faultable is used anywhere in kernel/bpf/helpers.c.
> +
> +BTF_ID_LIST_SINGLE(bpf_probe_write_user_faultable_btf_id, func,
> + bpf_probe_write_user_faultable)
> +
> +static int user_mem_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
> +{
> + if (kfunc_id == bpf_probe_write_user_faultable_btf_id[0])
> + return security_locked_down(LOCKDOWN_BPF_WRITE_USER);
[Severity: Critical]
Should user_mem_kfunc_filter() also verify that the program has
CAP_SYS_ADMIN via bpf_token_capable(prog->aux->token, CAP_SYS_ADMIN)?
In user_mem_btf_ids, bpf_probe_write_user_faultable is marked with
KF_PERFMON, which in check_kfunc_call() in kernel/bpf/verifier.c only checks
env->allow_ptr_leaks (satisfied by CAP_PERFMON). Meanwhile, for the existing
bpf_probe_write_user() helper, bpf_tracing_func_proto() in
kernel/trace/bpf_trace.c enforces CAP_SYS_ADMIN in addition to lockdown:
kernel/trace/bpf_trace.c:bpf_tracing_func_proto() {
...
if (!bpf_token_capable(prog->aux->token, CAP_SYS_ADMIN))
return NULL;
switch (func_id) {
case BPF_FUNC_probe_write_user:
return security_locked_down(LOCKDOWN_BPF_WRITE_USER) < 0 ?
NULL : &bpf_probe_write_user_proto;
...
}
And include/uapi/linux/capability.h documents this boundary under CAP_BPF:
* CAP_SYS_ADMIN is required to use bpf_probe_write_user.
Without a bpf_token_capable(prog->aux->token, CAP_SYS_ADMIN) check in
user_mem_kfunc_filter(), couldn't a process or container granted only
CAP_BPF and CAP_PERFMON attach a sleepable uprobe or uprobe_multi program to
a shared library and overwrite memory in privileged processes?
> +
> + return 0;
> +}
[Severity: Medium]
Does user_mem_kfunc_filter() also need to check prog->sleepable to restrict
bpf_probe_write_user_faultable() to sleepable uprobes as described in the
commit message?
Because BPF_PROG_TYPE_KPROBE is shared by kernel kprobes and uprobes, the
uprobe-only restriction for sleepable programs is enforced at attach time by
checking prog->sleepable in __perf_event_set_bpf_prog() and
bpf_kprobe_multi_link_attach().
In check_kfunc_call() in kernel/bpf/verifier.c, KF_SLEEPABLE checks
in_sleepable_context(env) rather than prog->sleepable. When a non-sleepable
BPF_PROG_TYPE_KPROBE program (prog->sleepable == false) registers a callback
via bpf_task_work_schedule_signal(), bpf_task_work_schedule_resume(), or
bpf_wq_set_callback(), push_callback_call() marks the callback state as
sleepable via is_async_cb_sleepable():
kernel/bpf/verifier.c:is_async_cb_sleepable() {
/* bpf_wq and bpf_task_work callbacks are always sleepable. */
if (bpf_pseudo_kfunc_call(insn) && insn->off == 0 &&
(is_bpf_wq_set_callback_kfunc(insn->imm) || is_task_work_add_kfunc(insn->imm)))
return true;
return false;
}
Without checking !prog->sleepable in user_mem_kfunc_filter(), wouldn't a
non-sleepable kernel kprobe, kretprobe, or kprobe_multi program be able to
call bpf_probe_write_user_faultable() from a bpf_task_work callback?
> +
> +static const struct btf_kfunc_id_set user_mem_kfunc_set = {
> + .owner = THIS_MODULE,
> + .set = &user_mem_btf_ids,
> + .filter = user_mem_kfunc_filter,
> +};
[ ... ]
> @@ -5266,6 +5322,7 @@ static int __init kfunc_init(void)
> };
>
> ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &generic_kfunc_set);
> + ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_KPROBE, &user_mem_kfunc_set);
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261021195759.119421-1-jolsa@kernel.org?part=2
next prev parent reply other threads:[~2026-10-21 20:22 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 19:57 [RFC bpf-next 0/9] bpf: Add support to allocate user page Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 1/9] bpf: Add __srcptr kfunc argument suffix Jiri Olsa
2026-10-21 20:16 ` sashiko-bot
2026-10-21 19:57 ` [RFC bpf-next 2/9] bpf: Add uprobe faultable user copy kfunc Jiri Olsa
2026-10-21 20:22 ` sashiko-bot [this message]
2026-10-21 20:30 ` bot+bpf-ci
2026-10-21 19:57 ` [RFC bpf-next 3/9] mm: Expose locked mprotect operation Jiri Olsa
2026-10-21 20:30 ` bot+bpf-ci
2026-10-22 10:25 ` Lorenzo Stoakes (ARM)
2026-10-22 19:39 ` Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 4/9] bpf: Add kfuncs to allocate and seal user pages Jiri Olsa
2026-10-21 20:28 ` sashiko-bot
2026-10-21 20:41 ` bot+bpf-ci
2026-10-26 12:51 ` kernel test robot
2026-10-26 15:27 ` kernel test robot
2026-10-21 19:57 ` [RFC bpf-next 5/9] selftests/bpf: Add __srcptr kfunc arguments test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 6/9] selftests/bpf: Add user page allocation test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 7/9] selftests/bpf: Add uprobe user page exec test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 8/9] selftests/bpf: Add faultable user page writes test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 9/9] selftests/bpf: Add user page failures test Jiri Olsa
2026-10-21 20:30 ` bot+bpf-ci
2026-10-21 21:53 ` [RFC bpf-next 0/9] bpf: Add support to allocate user page Alexei Starovoitov
2026-10-22 10:01 ` Jiri Olsa
2026-10-22 10:27 ` Lorenzo Stoakes (ARM)
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=sashiko-outbox-180638@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=liam@infradead.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=memxor@gmail.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shuah@kernel.org \
/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.