Clean up x86 unsafe_get/put_user() type handling
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 21 May 2017 22:25:46 +0000 (15:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 21 May 2017 22:25:46 +0000 (15:25 -0700)
Al noticed that unsafe_put_user() had type problems, and fixed them in
commit a7cc722fff0b ("fix unsafe_put_user()"), which made me look more
at those functions.

It turns out that unsafe_get_user() had a type issue too: it limited the
largest size of the type it could handle to "unsigned long".  Which is
fine with the current users, but doesn't match our existing normal
get_user() semantics, which can also handle "u64" even when that does
not fit in a long.

While at it, also clean up the type cast in unsafe_put_user().  We
actually want to just make it an assignment to the expected type of the
pointer, because we actually do want warnings from types that don't
convert silently.  And it makes the code more readable by not having
that one very long and complex line.

[ This patch might become stable material if we ever end up back-porting
  any new users of the unsafe uaccess code, but as things stand now this
  doesn't matter for any current existing uses. ]

Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/x86/include/asm/uaccess.h

index d9668c3beb5b4943de4f9610454890ceaa5b1e39..fc1eb64fdfffdee1887660f454af2d7b13a7ad8e 100644 (file)
@@ -703,14 +703,15 @@ extern struct movsl_mask {
 #define unsafe_put_user(x, ptr, err_label)                                     \
 do {                                                                           \
        int __pu_err;                                                           \
-       __put_user_size((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);             \
+       __typeof__(*(ptr)) __pu_val = (x);                                      \
+       __put_user_size(__pu_val, (ptr), sizeof(*(ptr)), __pu_err, -EFAULT);    \
        if (unlikely(__pu_err)) goto err_label;                                 \
 } while (0)
 
 #define unsafe_get_user(x, ptr, err_label)                                     \
 do {                                                                           \
        int __gu_err;                                                           \
-       unsigned long __gu_val;                                                 \
+       __inttype(*(ptr)) __gu_val;                                             \
        __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT);    \
        (x) = (__force __typeof__(*(ptr)))__gu_val;                             \
        if (unlikely(__gu_err)) goto err_label;                                 \