Re: [PATCH bpf-next v2 1/3] mm: Add copy_remote_mm_str()

From: Andrii Nakryiko

Date: Fri Aug 21 2026 - 15:53:44 EST


On Thu, Aug 20, 2026 at 6:18 AM Anastasios Papagiannis
<tasos.papagiannnis@xxxxxxxxx> 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.
>
> Signed-off-by: Anastasios Papagiannis <tasos.papagiannnis@xxxxxxxxx>
> ---
> include/linux/mm.h | 2 ++
> mm/memory.c | 26 +++++++++++++++++++++++++-
> mm/nommu.c | 26 +++++++++++++++++++++++++-
> 3 files changed, 52 insertions(+), 2 deletions(-)
>
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 485df9c2dbdd..eede435bf4a3 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3222,6 +3222,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
> diff --git a/mm/memory.c b/mm/memory.c
> index 6b8280cfc1db..da0010c4475d 100644
> --- a/mm/memory.c
> +++ b/mm/memory.c
> @@ -7218,6 +7218,30 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> return buf - old_buf;
> }
>
> +/**
> + * 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_vm_str(mm, addr, buf, len, gup_flags);

we should rename __copy_remote_vm_str into __copy_remote_mm_str

> +}
> +
> /**
> * copy_remote_vm_str - copy a string from another process's address space.
> * @tsk: the task of the target address space
> @@ -7247,7 +7271,7 @@ int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
> return -EFAULT;
> }
>
> - ret = __copy_remote_vm_str(mm, addr, buf, len, gup_flags);
> + ret = copy_remote_mm_str(mm, addr, buf, len, gup_flags);
>
> mmput(mm);
>
> diff --git a/mm/nommu.c b/mm/nommu.c
> index ed3934bc2de4..1fca0bb7f042 100644
> --- a/mm/nommu.c
> +++ b/mm/nommu.c
> @@ -1752,6 +1752,30 @@ static int __copy_remote_vm_str(struct mm_struct *mm, unsigned long addr,
> return ret;
> }
>
> +/**
> + * 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 (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. 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;

I'd just move this len check into __copy_remote_mm_str()


> +
> + return __copy_remote_vm_str(mm, addr, buf, len);
> +}
> +
> /**
> * copy_remote_vm_str - copy a string from another process's address space.
> * @tsk: the task of the target address space
> @@ -1781,7 +1805,7 @@ int copy_remote_vm_str(struct task_struct *tsk, unsigned long addr,
> return -EFAULT;
> }
>
> - ret = __copy_remote_vm_str(mm, addr, buf, len);
> + ret = copy_remote_mm_str(mm, addr, buf, len, gup_flags);
>
> mmput(mm);
>
> --
> 2.55.0
>