All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Olsa <olsajiri@gmail.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>,
	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: Re: [RFC bpf-next 0/9] bpf: Add support to allocate user page
Date: Thu, 22 Oct 2026 12:01:37 +0200	[thread overview]
Message-ID: <atnfAUWzdsoWQKe8@krava> (raw)
In-Reply-To: <DMAUMG9WL4X6.12UEJJMJSW54Z@gmail.com>

On Wed, Oct 21, 2026 at 09:53:47PM +0000, Alexei Starovoitov wrote:
> On Wed, Oct 21, 2026 at 12:57 PM Jiri Olsa <jolsa@kernel.org> wrote:
> > hi,
> > we have few use cases where having the ability to allocate normal
> > or executable user space memory would help (like to replace function
> > in live process or change environment variables)
> 
> I think it's better to do what debuggers do:
> vm_mmap() with the final prot and
> access_process_vm(FOLL_FORCE | FOLL_WRITE), like PTRACE_POKETEXT,
> to fill it. It faults the pages in, writes into r-x private mapping
> and copy_to_user_page() takes care of icache.
> Then no need for bpf_user_page_exec(), do_mprotect_pkey_locked(),
> the marker, READ_IMPLIES_EXEC special case, get_user_pages(), etc.
> No mm changes.

great, much better, will use it in next version, thanks

> 
> Like:
> 
> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index 648abe1..ca1d88d 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 <linux/mman.h>
> 
>  #include "../../lib/kstrtox.h"
> 
> @@ -3834,6 +3835,60 @@ __bpf_kfunc int bpf_copy_from_user_task_str(void *dst, u32 dst__sz,
>  	return ret;
>  }
> 
> +/**
> + * bpf_copy_to_user_task() - Copy data to a task's address space
> + * @unsafe_ptr__ign: Destination address in the task's address space
> + * @src:             Source address, in kernel space
> + * @src__sz:         Number of bytes to copy
> + * @tsk:             The task whose address space will be used
> + * @flags:           Reserved for future use; must be zero
> + *
> + * Faults in the destination and writes the way ptrace(PTRACE_POKETEXT) does:
> + * a private mapping doesn't have to be writable.
> + *
> + * Return: 0 on success, -EINVAL if @flags is non-zero, or -EFAULT if the copy
> + * fails or is partial.
> + */
> +__bpf_kfunc int bpf_copy_to_user_task(void __user *unsafe_ptr__ign, const void *src,
> +				      u32 src__sz, struct task_struct *tsk, u64 flags)
> +{
> +	int ret;
> +
> +	if (unlikely(flags))
> +		return -EINVAL;
> +
> +	if (unlikely(!src__sz))
> +		return 0;
> +
> +	ret = access_process_vm(tsk, (unsigned long)unsafe_ptr__ign, (void *)src,
> +				src__sz, FOLL_FORCE | FOLL_WRITE);
> +	return ret == src__sz ? 0 : -EFAULT;
> +}
> +
> +/**
> + * bpf_user_mmap() - Map private anonymous memory into the current process
> + * @len:  Length of the mapping
> + * @prot: PROT_* flags of mmap(2)
> + *
> + * Return: The address of the mapping on success, or a negative error code.
> + */
> +__bpf_kfunc long bpf_user_mmap(unsigned long len, unsigned long prot)
> +{
> +	return vm_mmap(NULL, 0, len, prot, MAP_PRIVATE | MAP_ANONYMOUS, 0);
> +}
> +
> +/**
> + * bpf_user_munmap() - Unmap a range of addresses of the current process
> + * @addr: Start of the range
> + * @len:  Length of the range
> + *
> + * Return: 0 on success, or a negative error code.
> + */
> +__bpf_kfunc int bpf_user_munmap(unsigned long addr, unsigned long len)
> +{
> +	return vm_munmap(addr, len);
> +}
> +
>  /* Keep unsigned long in prototype so that kfunc is usable when emitted to
>   * vmlinux.h in BPF programs directly, but note that while in BPF prog, the
>   * unsigned long always points to 8-byte region on stack, the kernel may only
> @@ -5139,6 +5194,25 @@ 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_copy_to_user_task, KF_SLEEPABLE | KF_PERFMON)
> +BTF_ID_FLAGS(func, bpf_user_mmap, KF_SLEEPABLE | KF_PERFMON)
> +BTF_ID_FLAGS(func, bpf_user_munmap, KF_SLEEPABLE | KF_PERFMON)
> +BTF_KFUNCS_END(user_mem_btf_ids)
> +
> +static int user_mem_kfunc_filter(const struct bpf_prog *prog, u32 kfunc_id)
> +{
> +	if (!btf_id_set8_contains(&user_mem_btf_ids, kfunc_id))
> +		return 0;
> +	return security_locked_down(LOCKDOWN_BPF_WRITE_USER);

ah right.. all of those kfuncs should be behing write_user lockdown

> +}
> +
> +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 +5340,8 @@ static int __init kfunc_init(void)
>  	};
> 
>  	ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_TRACING, &generic_kfunc_set);
> +	/* Sleepable kprobe prog can only be attached to uprobe */
> +	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);
> 
> But I'm not at all sure that it's a good idea
> to inject code into a process.

well FWIW it's still guarded with the LOCKDOWN_BPF_WRITE_USER same as
bpf_probe_write_user helper

at the moment we have fragile way of live patching a userspace process,
this would give us a more direct and reliable way for that

thanks,
jirka


  reply	other threads:[~2026-10-22 10:01 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
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 [this message]
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=atnfAUWzdsoWQKe8@krava \
    --to=olsajiri@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@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 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.