diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2016-08-17 16:02:32 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-09-09 19:34:32 -0400 |
commit | 2561d309dfd1555e781484af757ed0115035ddb3 (patch) | |
tree | 6d96d75a4e35e2280edc0e47af670a31b0da4660 | |
parent | 694d0d0bb2030d2e36df73e2d23d5770511dbc8d (diff) |
alpha: fix copy_from_user()
it should clear the destination even when access_ok() fails.
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/alpha/include/asm/uaccess.h | 19 |
1 files changed, 8 insertions, 11 deletions
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index c419b43c461d..466e42e96bfa 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h | |||
@@ -371,14 +371,6 @@ __copy_tofrom_user_nocheck(void *to, const void *from, long len) | |||
371 | return __cu_len; | 371 | return __cu_len; |
372 | } | 372 | } |
373 | 373 | ||
374 | extern inline long | ||
375 | __copy_tofrom_user(void *to, const void *from, long len, const void __user *validate) | ||
376 | { | ||
377 | if (__access_ok((unsigned long)validate, len, get_fs())) | ||
378 | len = __copy_tofrom_user_nocheck(to, from, len); | ||
379 | return len; | ||
380 | } | ||
381 | |||
382 | #define __copy_to_user(to, from, n) \ | 374 | #define __copy_to_user(to, from, n) \ |
383 | ({ \ | 375 | ({ \ |
384 | __chk_user_ptr(to); \ | 376 | __chk_user_ptr(to); \ |
@@ -393,17 +385,22 @@ __copy_tofrom_user(void *to, const void *from, long len, const void __user *vali | |||
393 | #define __copy_to_user_inatomic __copy_to_user | 385 | #define __copy_to_user_inatomic __copy_to_user |
394 | #define __copy_from_user_inatomic __copy_from_user | 386 | #define __copy_from_user_inatomic __copy_from_user |
395 | 387 | ||
396 | |||
397 | extern inline long | 388 | extern inline long |
398 | copy_to_user(void __user *to, const void *from, long n) | 389 | copy_to_user(void __user *to, const void *from, long n) |
399 | { | 390 | { |
400 | return __copy_tofrom_user((__force void *)to, from, n, to); | 391 | if (likely(__access_ok((unsigned long)to, n, get_fs()))) |
392 | n = __copy_tofrom_user_nocheck((__force void *)to, from, n); | ||
393 | return n; | ||
401 | } | 394 | } |
402 | 395 | ||
403 | extern inline long | 396 | extern inline long |
404 | copy_from_user(void *to, const void __user *from, long n) | 397 | copy_from_user(void *to, const void __user *from, long n) |
405 | { | 398 | { |
406 | return __copy_tofrom_user(to, (__force void *)from, n, from); | 399 | if (likely(__access_ok((unsigned long)from, n, get_fs()))) |
400 | n = __copy_tofrom_user_nocheck(to, (__force void *)from, n); | ||
401 | else | ||
402 | memset(to, 0, n); | ||
403 | return n; | ||
407 | } | 404 | } |
408 | 405 | ||
409 | extern void __do_clear_user(void); | 406 | extern void __do_clear_user(void); |