Re: [PATCHv4 3/8] mm: Pass down mm_struct to untagged_addr()

From: Alexander Potapenko
Date: Thu Jul 07 2022 - 04:57:37 EST


On Thu, Jul 7, 2022 at 1:14 AM Kirill A. Shutemov
<kirill.shutemov@xxxxxxxxxxxxxxx> wrote:
>
> On Tue, Jul 05, 2022 at 05:42:21PM +0200, Alexander Potapenko wrote:
> > Kirill,
> >
> >
> > > diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c
> > > index feeb935a2299..abc096a68f05 100644
> > > --- a/lib/strnlen_user.c
> > > +++ b/lib/strnlen_user.c
> > > @@ -97,7 +97,7 @@ long strnlen_user(const char __user *str, long count)
> > > return 0;
> > >
> > > max_addr = TASK_SIZE_MAX;
> > > - src_addr = (unsigned long)untagged_addr(str);
> > > + src_addr = (unsigned long)untagged_addr(current->mm, str);
> >
> > In a downstream kernel with LAM disabled I'm seeing current->mm being
> > NULL at this point, because strnlen_user() is being called by
> > kdevtmpfs.
> > IIUC current->mm is only guaranteed to be non-NULL in the userspace
> > process context, whereas untagged_addr() may get called in random
> > places.
> >
> > Am I missing something?
>
> Hm. Could you show a traceback?
>
> As strnlen_user() intended to be used on an user string I expected it to
> be called from a process context. I guess I'm wrong, but I don't yet
> understand why.

Oh, I see now. The old implementation of devtmpfsd()
(https://elixir.bootlin.com/linux/v5.4/source/drivers/base/devtmpfs.c#L397)
uses ksys_mount(), which assumes that the strings must be copied from
the userspace, whereas they are actually constants in kernel .rodata

Wonder if the validity of mm->current for userspace accesses is
actually enforced anyhow in newer kernels.

> --
> Kirill A. Shutemov



--
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Liana Sebastian
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg