All of lore.kernel.org
 help / color / mirror / Atom feed
* Unaligned user pointer issues..
@ 2019-10-07  3:25 Linus Torvalds
  2019-10-07  7:47 ` Michael Cree
  0 siblings, 1 reply; 2+ messages in thread
From: Linus Torvalds @ 2019-10-07  3:25 UTC (permalink / raw)
  To: linux-arch

So Guenther Roeck reported that my fancy readdir() user access
optimization broke alpha and sparc64 boot for him.

(It really improves things on x86 - I swear! The cost of telling the
CPU over and over again to "please allow user space accesses" is
horrendously high, so doing the whole "user_access_begin()/end() just
_once_ per dirent is a big deal).

It turns out that it's broken on at least alpha because it does that
filename copy to user space by hand, and the "linux_filldir64"
structure is set up so that the name part is basically never aligned.
So when it does the word copies, it does them as unaligned
"put_user()" invocations.

I'll fix it, never fear, since it's clearly a horrible performance
pessimization on architectures that don't deal unaligned accesses
well.

However, at least on alpha, it's not just that unaligned user accesses
were slow, they didn't actually _work_.

And that's a problem.

Because they are easy to trigger from user space even without any new
readdir code.

This trivial program causes a kernel oops on alpha:

  #define _GNU_SOURCE
  #include <unistd.h>
  #include <sys/mman.h>

  int main(int argc, char **argv)
  {
        void *mymap;
        uid_t *bad_ptr = (void *) 0x01;

        /* Create unpopulated memory area */
        mymap = mmap(NULL, 16384,
                PROT_READ | PROT_WRITE,
                MAP_PRIVATE | MAP_ANONYMOUS,
                -1, 0);

        /* Unaligned uidpointer in that memory area */
        bad_ptr = mymap+1;

        /* Make the kernel do put_user() on it */
        return getresuid(bad_ptr, bad_ptr+1, bad_ptr+2);
  }

because getresuid() does "put_user()" on that unaligned pointer, and
it looks like something goes badly sideways when it first takes the
unaligned trap, and then the unaligned trap handler gets an exception
on the emulation code.

I'm not sure what the alpha bug is (I looked at the code just long
enough to see that it _tries_ to do the exception handling), but the
fact that apparently I broke at least sparc64 too makes me suspect
that other architectures have this issue too.

So hey, can I ask architecture maintainers to try the above trivial
program and see how it works (or doesn't)?

On alpha, when Guenther tried my silly test-program, he reported:

  # ./mmtest
  Unable to handle kernel paging request at virtual address 0000000000000004
  mmtest(75): Oops -1
  pc = [<0000000000000004>]  ra = [<fffffc0000311584>]  ps = 0000    Not tainted
  pc is at 0x4
  ra is at entSys+0xa4/0xc0
  v0 = fffffffffffffff2  t0 = 0000000000000000  t1 = 0000000000000000
  ...

which is not what is supposed to happen ;)

            Linus

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Unaligned user pointer issues..
  2019-10-07  3:25 Unaligned user pointer issues Linus Torvalds
@ 2019-10-07  7:47 ` Michael Cree
  0 siblings, 0 replies; 2+ messages in thread
From: Michael Cree @ 2019-10-07  7:47 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-arch, linux-alpha

On Sun, Oct 06, 2019 at 08:25:05PM -0700, Linus Torvalds wrote:
> So Guenther Roeck reported that my fancy readdir() user access
> optimization broke alpha and sparc64 boot for him.
> 
> (It really improves things on x86 - I swear! The cost of telling the
> CPU over and over again to "please allow user space accesses" is
> horrendously high, so doing the whole "user_access_begin()/end() just
> _once_ per dirent is a big deal).
> 
> It turns out that it's broken on at least alpha because it does that
> filename copy to user space by hand, and the "linux_filldir64"
> structure is set up so that the name part is basically never aligned.
> So when it does the word copies, it does them as unaligned
> "put_user()" invocations.
> 
> I'll fix it, never fear, since it's clearly a horrible performance
> pessimization on architectures that don't deal unaligned accesses
> well.
> 
> However, at least on alpha, it's not just that unaligned user accesses
> were slow, they didn't actually _work_.
> 
> And that's a problem.
> 
> Because they are easy to trigger from user space even without any new
> readdir code.
> 
> This trivial program causes a kernel oops on alpha:
> 
>   #define _GNU_SOURCE
>   #include <unistd.h>
>   #include <sys/mman.h>
> 
>   int main(int argc, char **argv)
>   {
>         void *mymap;
>         uid_t *bad_ptr = (void *) 0x01;
> 
>         /* Create unpopulated memory area */
>         mymap = mmap(NULL, 16384,
>                 PROT_READ | PROT_WRITE,
>                 MAP_PRIVATE | MAP_ANONYMOUS,
>                 -1, 0);
> 
>         /* Unaligned uidpointer in that memory area */
>         bad_ptr = mymap+1;
> 
>         /* Make the kernel do put_user() on it */
>         return getresuid(bad_ptr, bad_ptr+1, bad_ptr+2);
>   }
> 
> because getresuid() does "put_user()" on that unaligned pointer, and
> it looks like something goes badly sideways when it first takes the
> unaligned trap, and then the unaligned trap handler gets an exception
> on the emulation code.
> 
> I'm not sure what the alpha bug is (I looked at the code just long
> enough to see that it _tries_ to do the exception handling), but the
> fact that apparently I broke at least sparc64 too makes me suspect
> that other architectures have this issue too.
> 
> So hey, can I ask architecture maintainers to try the above trivial
> program and see how it works (or doesn't)?
> 
> On alpha, when Guenther tried my silly test-program, he reported:
> 
>   # ./mmtest
>   Unable to handle kernel paging request at virtual address 0000000000000004
>   mmtest(75): Oops -1
>   pc = [<0000000000000004>]  ra = [<fffffc0000311584>]  ps = 0000    Not tainted
>   pc is at 0x4
>   ra is at entSys+0xa4/0xc0
>   v0 = fffffffffffffff2  t0 = 0000000000000000  t1 = 0000000000000000
>   ...
> 
> which is not what is supposed to happen ;)

Testing the above on an XP1000 running 5.4.0-rc2 built for Alpha
DP264 reveals no problems.  No Oops reported.  Unaligned access
count goes up by three in /proc/cpuinfo as expected.  But
interestingly the kernel unaligned access count is quite high
(14000 or so) on this kernel after boot whereas with the 5.2.y
kernel I was recently running it was zero.

Cheers,
Michael.

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-10-07  8:05 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-07  3:25 Unaligned user pointer issues Linus Torvalds
2019-10-07  7:47 ` Michael Cree

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.