From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
To: Anastasios Papagiannis <tasos.papagiannnis@gmail.com>
Cc: bpf@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org,
david@kernel.org, akpm@linux-foundation.org, andrii@kernel.org,
ast@kernel.org, brauner@kernel.org, daniel@iogearbox.net,
eddyz87@gmail.com, kpsingh@kernel.org, matt@bobrowski.net,
memxor@gmail.com, song@kernel.org, sun.jian.kdev@gmail.com,
utilityemal77@gmail.com, viro@zeniv.linux.org.uk
Subject: Re: [PATCH bpf-next v5 1/7] mm: Add copy_remote_mm_str()
Date: Tue, 8 Sep 2026 14:16:31 +0100 [thread overview]
Message-ID: <aqAKY6dtdxN_cUMi@gremlin> (raw)
In-Reply-To: <20260907165220.52431-2-tasos.papagiannnis@gmail.com>
On Mon, Sep 07, 2026 at 07:52:14PM +0300, Anastasios Papagiannis wrote:
> copy_remote_vm_str() gets the target address space from a struct
> task_struct. This does not work for an address space that exists but is
> not yet associated with a task_struct, such as the mm held by struct
> linux_binprm during exec.
>
> Add copy_remote_mm_str(), which operates directly on a struct mm_struct.
>
> Use a common internal interface for the MMU and NOMMU implementations
> and define both public wrappers in mm/util.c. Preserve the existing
> copy_remote_vm_str() behavior, including handling zero-length requests
> before acquiring the task's mm.
>
> Signed-off-by: Anastasios Papagiannis <tasos.papagiannnis@gmail.com>
OK actually doing it this way means we don't have to worry about
__copy_remote_mm_str() at all since we abstract it with
copy_remote_mm_str().
With David's comments addressed LGTM so:
Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> include/linux/mm.h | 2 ++
> mm/internal.h | 5 ++++
> mm/memory.c | 41 ++----------------------------
> mm/nommu.c | 41 ++----------------------------
> mm/util.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 73 insertions(+), 78 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index dd09c438fa23..d5bde1f71a97 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3326,6 +3326,8 @@ extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
> void *buf, int len, unsigned int gup_flags);
>
> #ifdef CONFIG_BPF_SYSCALL
> +extern int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr,
> + void *buf, int len, unsigned int gup_flags);
> extern int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
> void *buf, int len, unsigned int gup_flags);
> #endif
Same comments as David :>)
> diff --git a/mm/internal.h b/mm/internal.h
> index 38b1165212c9..8264a346d18a 100644
> --- a/mm/internal.h
> +++ b/mm/internal.h
> @@ -25,6 +25,11 @@
> struct folio_batch;
> struct hstate;
>
> +#ifdef CONFIG_BPF_SYSCALL
> +int __copy_remote_mm_str(struct mm_struct *mm, unsigned long addr,
> + void *buf, int len, unsigned int gup_flags);
> +#endif
> +
> struct huge_bootmem_page {
> struct list_head list;
> struct hstate *hstate;
> diff --git a/mm/memory.c b/mm/memory.c
> index 8b0c2c735d3d..fe2f5e988fb9 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -7331,8 +7331,8 @@ EXPORT_SYMBOL_GPL(access_process_vm);
> * Copy a string from another process's address space as given in mm.
> * If there is any error return -EFAULT.
> */
> -static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> - void *buf, int len, unsigned int gup_flags)
> +int __copy_remote_mm_str(struct mm_struct *mm, unsigned long addr,
> + void *buf, int len, unsigned int gup_flags)
> {
> void *old_buf = buf;
> int err = 0;
> @@ -7407,43 +7407,6 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> return err;
> return buf - old_buf;
> }
> -
> -/**
> - * copy_remote_vm_str - copy a string from another process's address space.
> - * @tsk: the task of the target address space
> - * @addr: start address to read from
> - * @buf: destination buffer
> - * @len: number of bytes to copy
> - * @gup_flags: flags modifying lookup behaviour
> - *
> - * The caller must hold a reference on @mm.
> - *
> - * Return: number of bytes copied from @addr (source) to @buf (destination);
> - * not including the trailing NUL. Always guaranteed to leave NUL-terminated
> - * buffer. On any error, return -EFAULT.
> - */
> -int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
> - void *buf, int len, unsigned int gup_flags)
> -{
> - struct mm_struct *mm;
> - int ret;
> -
> - if (unlikely(len == 0))
> - return 0;
> -
> - mm = get_task_mm(tsk);
> - if (!mm) {
> - *(char *)buf = '\0';
> - return -EFAULT;
> - }
> -
> - ret = __copy_remote_vm_str(mm, addr, buf, len, gup_flags);
> -
> - mmput(mm);
> -
> - return ret;
> -}
> -EXPORT_SYMBOL_GPL(copy_remote_vm_str);
> #endif /* CONFIG_BPF_SYSCALL */
>
> /*
> diff --git a/mm/nommu.c b/mm/nommu.c
> index 498e01ee40b0..98596e60311f 100644
> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -1746,8 +1746,8 @@ EXPORT_SYMBOL_GPL(access_process_vm);
> * Copy a string from another process's address space as given in mm.
> * If there is any error return -EFAULT.
> */
> -static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> - void *buf, int len)
> +int __copy_remote_mm_str(struct mm_struct *mm, unsigned long addr,
> + void *buf, int len, unsigned int gup_flags)
> {
> unsigned long addr_end;
> struct vm_area_struct *vma;
> @@ -1781,43 +1781,6 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> mmap_read_unlock(mm);
> return ret;
> }
> -
> -/**
> - * copy_remote_vm_str - copy a string from another process's address space.
> - * @tsk: the task of the target address space
> - * @addr: start address to read from
> - * @buf: destination buffer
> - * @len: number of bytes to copy
> - * @gup_flags: flags modifying lookup behaviour (unused)
> - *
> - * The caller must hold a reference on @mm.
> - *
> - * Return: number of bytes copied from @addr (source) to @buf (destination);
> - * not including the trailing NUL. Always guaranteed to leave NUL-terminated
> - * buffer. On any error, return -EFAULT.
> - */
> -int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
> - void *buf, int len, unsigned int gup_flags)
> -{
> - struct mm_struct *mm;
> - int ret;
> -
> - if (unlikely(len == 0))
> - return 0;
> -
> - mm = get_task_mm(tsk);
> - if (!mm) {
> - *(char *)buf = '\0';
> - return -EFAULT;
> - }
> -
> - ret = __copy_remote_vm_str(mm, addr, buf, len);
> -
> - mmput(mm);
> -
> - return ret;
> -}
> -EXPORT_SYMBOL_GPL(copy_remote_vm_str);
> #endif /* CONFIG_BPF_SYSCALL */
>
> /**
> diff --git a/mm/util.c b/mm/util.c
> index bf0513d1d3d0..2eca27b02791 100644
> --- a/mm/util.c
> +++ b/mm/util.c
> @@ -1061,6 +1061,68 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
> return res;
> }
>
> +#ifdef CONFIG_BPF_SYSCALL
> +/**
> + * copy_remote_mm_str - copy a string from a remote address space.
> + * @mm: the remote address space
> + * @addr: start address to read from
> + * @buf: destination buffer
> + * @len: number of bytes to copy
> + * @gup_flags: flags modifying lookup behaviour
> + *
> + * The caller must hold a reference on @mm.
> + *
> + * Return: number of bytes copied from @addr (source) to @buf (destination),
> + * not including the trailing NUL. If @len is zero, return 0 without accessing
> + * @buf. Otherwise, @buf is always NUL-terminated. On any error, return
> + * -EFAULT.
> + */
> +int copy_remote_mm_str(struct mm_struct *mm, unsigned long addr,
> + void *buf, int len, unsigned int gup_flags)
> +{
> + if (unlikely(len == 0))
> + return 0;
> +
> + return __copy_remote_mm_str(mm, addr, buf, len, gup_flags);
> +}
> +
> +/**
> + * copy_remote_vm_str - copy a string from another process's address space.
> + * @tsk: the task of the target address space
> + * @addr: start address to read from
> + * @buf: destination buffer
> + * @len: number of bytes to copy
> + * @gup_flags: flags modifying lookup behaviour
> + *
> + * Return: number of bytes copied from @addr (source) to @buf (destination),
> + * not including the trailing NUL. If @len is zero, return 0 without accessing
> + * @buf. Otherwise, @buf is always NUL-terminated. On any error, return
> + * -EFAULT.
> + */
> +int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
> + void *buf, int len, unsigned int gup_flags)
> +{
> + struct mm_struct *mm;
> + int ret;
> +
> + if (unlikely(len == 0))
> + return 0;
> +
> + mm = get_task_mm(tsk);
> + if (!mm) {
> + *(char *)buf = '\0';
> + return -EFAULT;
> + }
> +
> + ret = __copy_remote_mm_str(mm, addr, buf, len, gup_flags);
> +
> + mmput(mm);
> +
> + return ret;
> +}
> +EXPORT_SYMBOL_GPL(copy_remote_vm_str);
> +#endif /* CONFIG_BPF_SYSCALL */
> +
> int __weak memcmp_pages(struct page *page1, struct page *page2)
> {
> char *addr1, *addr2;
> --
> 2.55.0
>
--
Cheers, Lorenzo
next prev parent reply other threads:[~2026-09-08 13:16 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 16:52 [PATCH bpf-next v5 0/7] bpf: Add user memory access kfuncs for mm_struct Anastasios Papagiannis
2026-09-07 16:52 ` [PATCH bpf-next v5 1/7] mm: Add copy_remote_mm_str() Anastasios Papagiannis
2026-09-07 20:06 ` David Hildenbrand (Arm)
2026-09-08 13:16 ` Lorenzo Stoakes (ARM) [this message]
2026-09-07 16:52 ` [PATCH bpf-next v5 2/7] exec: Clear bprm->mm before dropping its reference Anastasios Papagiannis
2026-09-07 17:07 ` sashiko-bot
2026-09-07 16:52 ` [PATCH bpf-next v5 3/7] bpf: Add user memory access kfuncs for mm_struct Anastasios Papagiannis
2026-09-08 11:56 ` Matt Bobrowski
2026-09-07 16:52 ` [PATCH bpf-next v5 4/7] bpf: Allow reads through trusted-or-null BTF pointers Anastasios Papagiannis
2026-09-08 10:24 ` Kumar Kartikeya Dwivedi
2026-09-08 11:47 ` Anastasios Papagiannis
2026-09-08 13:19 ` Anastasios Papagiannis
2026-09-07 16:52 ` [PATCH bpf-next v5 5/7] selftests/bpf: Cover trusted-or-null BTF pointer reads Anastasios Papagiannis
2026-09-07 16:52 ` [PATCH bpf-next v5 6/7] bpf: Mark linux_binprm->mm as trusted-or-null Anastasios Papagiannis
2026-09-08 10:12 ` Matt Bobrowski
2026-09-07 16:52 ` [PATCH bpf-next v5 7/7] selftests/bpf: Test mm_struct user memory kfuncs with linux_binprm Anastasios Papagiannis
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=aqAKY6dtdxN_cUMi@gremlin \
--to=ljs@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=brauner@kernel.org \
--cc=daniel@iogearbox.net \
--cc=david@kernel.org \
--cc=eddyz87@gmail.com \
--cc=kpsingh@kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=matt@bobrowski.net \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=sun.jian.kdev@gmail.com \
--cc=tasos.papagiannnis@gmail.com \
--cc=utilityemal77@gmail.com \
--cc=viro@zeniv.linux.org.uk \
/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.