Re: [PATCH v10 06/12] fs, arm64: untag user pointers in copy_mount_options

From: Andrey Konovalov
Date: Tue Feb 26 2019 - 09:35:54 EST


On Sat, Feb 23, 2019 at 12:03 AM Dave Hansen <dave.hansen@xxxxxxxxx> wrote:
>
> On 2/22/19 4:53 AM, Andrey Konovalov wrote:
> > --- a/fs/namespace.c
> > +++ b/fs/namespace.c
> > @@ -2730,7 +2730,7 @@ void *copy_mount_options(const void __user * data)
> > * the remainder of the page.
> > */
> > /* copy_from_user cannot cross TASK_SIZE ! */
> > - size = TASK_SIZE - (unsigned long)data;
> > + size = TASK_SIZE - (unsigned long)untagged_addr(data);
> > if (size > PAGE_SIZE)
> > size = PAGE_SIZE;
>
> I would have thought that copy_from_user() *is* entirely capable of
> detecting and returning an error in the case that its arguments cross
> TASK_SIZE. It will fail and return an error, but that's what it's
> supposed to do.
>
> I'd question why this code needs to be doing its own checking in the
> first place. Is there something subtle going on?

The comment above exact_copy_from_user() states:

Some copy_from_user() implementations do not return the exact number of
bytes remaining to copy on a fault. But copy_mount_options() requires that.
Note that this function differs from copy_from_user() in that it will oops
on bad values of `to', rather than returning a short copy.