Re: Unaligned user pointer issues..

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.



[Index of Archives]     [Linux Kernel]     [Kernel Newbies]     [x86 Platform Driver]     [Netdev]     [Linux Wireless]     [Netfilter]     [Bugtraq]     [Linux Filesystems]     [Yosemite Discussion]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]

  Powered by Linux