linux-arch.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: linux-arch <linux-arch@vger.kernel.org>
Subject: Unaligned user pointer issues..
Date: Sun, 6 Oct 2019 20:25:05 -0700	[thread overview]
Message-ID: <CAHk-=wiGqnJc6obUGSAsP8YCFEb_ZhD2Zfz-aWxdS_E_R_1xVw@mail.gmail.com> (raw)

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

             reply	other threads:[~2019-10-07  3:25 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-07  3:25 Linus Torvalds [this message]
2019-10-07  7:47 ` Unaligned user pointer issues Michael Cree

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAHk-=wiGqnJc6obUGSAsP8YCFEb_ZhD2Zfz-aWxdS_E_R_1xVw@mail.gmail.com' \
    --to=torvalds@linux-foundation.org \
    --cc=linux-arch@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).