09 Aug, 2016

1 commit

  • When I initially added the unsafe_[get|put]_user() helpers in commit
    5b24a7a2aa20 ("Add 'unsafe' user access functions for batched
    accesses"), I made the mistake of modeling the interface on our
    traditional __[get|put]_user() functions, which return zero on success,
    or -EFAULT on failure.

    That interface is fairly easy to use, but it's actually fairly nasty for
    good code generation, since it essentially forces the caller to check
    the error value for each access.

    In particular, since the error handling is already internally
    implemented with an exception handler, and we already use "asm goto" for
    various other things, we could fairly easily make the error cases just
    jump directly to an error label instead, and avoid the need for explicit
    checking after each operation.

    So switch the interface to pass in an error label, rather than checking
    the error value in the caller. Best do it now before we start growing
    more users (the signal handling code in particular would be a good place
    to use the new interface).

    So rather than

    if (unsafe_get_user(x, ptr))
    ... handle error ..

    the interface is now

    unsafe_get_user(x, ptr, label);

    where an error during the user mode fetch will now just cause a jump to
    'label' in the caller.

    Right now the actual _implementation_ of this all still ends up being a
    "if (err) goto label", and does not take advantage of any exception
    label tricks, but for "unsafe_put_user()" in particular it should be
    fairly straightforward to convert to using the exception table model.

    Note that "unsafe_get_user()" is much harder to convert to a clever
    exception table model, because current versions of gcc do not allow the
    use of "asm goto" (for the exception) with output values (for the actual
    value to be fetched). But that is hopefully not a limitation in the
    long term.

    [ Also note that it might be a good idea to switch unsafe_get_user() to
    actually _return_ the value it fetches from user space, but this
    commit only changes the error handling semantics ]

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

21 May, 2016

1 commit

  • Exchange between user and kernel memory is coded in assembly language.
    Which means that such accesses won't be spotted by KASAN as a compiler
    instruments only C code.

    Add explicit KASAN checks to user memory access API to ensure that
    userspace writes to (or reads from) a valid kernel memory.

    Note: Unlike others strncpy_from_user() is written mostly in C and KASAN
    sees memory accesses in it. However, it makes sense to add explicit
    check for all @count bytes that *potentially* could be written to the
    kernel.

    [aryabinin@virtuozzo.com: move kasan check under the condition]
    Link: http://lkml.kernel.org/r/1462869209-21096-1-git-send-email-aryabinin@virtuozzo.com
    Link: http://lkml.kernel.org/r/1462538722-1574-4-git-send-email-aryabinin@virtuozzo.com
    Signed-off-by: Andrey Ryabinin
    Cc: Alexander Potapenko
    Cc: Dmitry Vyukov
    Cc: Ingo Molnar
    Cc: "H. Peter Anvin"
    Cc: Thomas Gleixner
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Andrey Ryabinin
     

18 Dec, 2015

1 commit

  • This converts the generic user string functions to use the batched user
    access functions.

    It makes a big difference on Skylake, which is the first x86
    microarchitecture to implement SMAP. The STAC/CLAC instructions are not
    very fast, and doing them for each access inside the loop that copies
    strings from user space (which is what the pathname handling does for
    every pathname the kernel uses, for example) is very inefficient.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

13 Feb, 2015

1 commit


27 May, 2012

1 commit

  • This changes the interfaces in to be a bit more
    complicated, but a lot more generic.

    In particular, it allows us to really do the operations efficiently on
    both little-endian and big-endian machines, pretty much regardless of
    machine details. For example, if you can rely on a fast population
    count instruction on your architecture, this will allow you to make your
    optimized file with that.

    NOTE! The "generic" version in include/asm-generic/word-at-a-time.h is
    not truly generic, it actually only works on big-endian. Why? Because
    on little-endian the generic algorithms are wasteful, since you can
    inevitably do better. The x86 implementation is an example of that.

    (The only truly non-generic part of the asm-generic implementation is
    the "find_zero()" function, and you could make a little-endian version
    of it. And if the Kbuild infrastructure allowed us to pick a particular
    header file, that would be lovely)

    The functions are as follows:

    - WORD_AT_A_TIME_CONSTANTS: specific constants that the algorithm
    uses.

    - has_zero(): take a word, and determine if it has a zero byte in it.
    It gets the word, the pointer to the constant pool, and a pointer to
    an intermediate "data" field it can set.

    This is the "quick-and-dirty" zero tester: it's what is run inside
    the hot loops.

    - "prep_zero_mask()": take the word, the data that has_zero() produced,
    and the constant pool, and generate an *exact* mask of which byte had
    the first zero. This is run directly *outside* the loop, and allows
    the "has_zero()" function to answer the "is there a zero byte"
    question without necessarily getting exactly *which* byte is the
    first one to contain a zero.

    If you do multiple byte lookups concurrently (eg "hash_name()", which
    looks for both NUL and '/' bytes), after you've done the prep_zero_mask()
    phase, the result of those can be or'ed together to get the "either
    or" case.

    - The result from "prep_zero_mask()" can then be fed into "find_zero()"
    (to find the byte offset of the first byte that was zero) or into
    "zero_bytemask()" (to find the bytemask of the bytes preceding the
    zero byte).

    The existence of zero_bytemask() is optional, and is not necessary
    for the normal string routines. But dentry name hashing needs it, so
    if you enable DENTRY_WORD_AT_A_TIME you need to expose it.

    This changes the generic strncpy_from_user() function and the dentry
    hashing functions to use these modified word-at-a-time interfaces. This
    gets us back to the optimized state of the x86 strncpy that we lost in
    the previous commit when moving over to the generic version.

    Signed-off-by: Linus Torvalds

    Linus Torvalds
     

25 May, 2012

1 commit