Re: [PATCH bpf-next v2 1/3] mm: Add copy_remote_mm_str()
Andrii Nakryiko <[email protected]>
| Newsgroups | org.kernel.vger.linux-fsdevel,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <CAEf4Bzb-43E7JSc5aNBEi4y1PKfQvjRi_FwTUyP7cYaQ+-JqXw@mail.gmail.com> |
On Thu, Aug 20, 2026 at 6:18 AM Anastasios Papagiannis <[email protected]> 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 <[email protected]> > --- > 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 >