Linux Kernel Selftest development
 help / color / mirror / Atom feed
From: Jiri Olsa <jolsa@kernel.org>
To: 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>,
	linux-kselftest@vger.kernel.org, Shuah Khan <shuah@kernel.org>,
	John Fastabend <john.fastabend@gmail.com>
Subject: [RFC bpf-next 2/9] bpf: Add uprobe faultable user copy kfunc
Date: Wed, 21 Oct 2026 21:57:51 +0200	[thread overview]
Message-ID: <20261021195759.119421-3-jolsa@kernel.org> (raw)
In-Reply-To: <20261021195759.119421-1-jolsa@kernel.org>

The bpf_probe_write_user() helper uses a no-fault copy. Adding kfunc
that can fault in the destination pages while copying to user memory.

Restricting it to sleepable uprobes and to LOCKDOWN_BPF_WRITE_USER.

Assisted-by: Codex:GPT-6
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 kernel/bpf/helpers.c | 57 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 648abe1ba63a..4d9e9423826a 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -29,6 +29,7 @@
 #include <linux/task_work.h>
 #include <linux/irq_work.h>
 #include <linux/buildid.h>
+#include <asm/tlb.h>
 
 #include "../../lib/kstrtox.h"
 
@@ -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;
+
+	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,
+};
+
+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);
+
+	return 0;
+}
+
+static const struct btf_kfunc_id_set user_mem_kfunc_set = {
+	.owner = THIS_MODULE,
+	.set = &user_mem_btf_ids,
+	.filter = user_mem_kfunc_filter,
+};
+
 BTF_ID_LIST(generic_dtor_ids)
 BTF_ID(struct, task_struct)
 BTF_ID(func, bpf_task_release_dtor)
@@ -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);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_SCHED_CLS, &generic_kfunc_set);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_XDP, &generic_kfunc_set);
 	ret = ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &generic_kfunc_set);
-- 
2.54.0


  parent reply	other threads:[~2026-10-21 19:58 UTC|newest]

Thread overview: 19+ 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 19:57 ` Jiri Olsa [this message]
2026-10-21 20:30   ` [RFC bpf-next 2/9] bpf: Add uprobe faultable user copy kfunc 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:41   ` bot+bpf-ci
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=20261021195759.119421-3-jolsa@kernel.org \
    --to=jolsa@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=liam@infradead.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=memxor@gmail.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox