aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/uaccess.h
diff options
context:
space:
mode:
authorJan Beulich <JBeulich@suse.com>2013-10-21 04:44:37 -0400
committerIngo Molnar <mingo@kernel.org>2013-10-26 06:27:37 -0400
commit7a3d9b0f3abbea957b829cdfff8169872c575642 (patch)
tree905bb8d2f62b5bee5b1523ed6dff08dc81551763 /arch/x86/include/asm/uaccess.h
parent3df7b41aa5e7797f391d0a41f8b0dce1fe366a09 (diff)
x86: Unify copy_to_user() and add size checking to it
Similarly to copy_from_user(), where the range check is to protect against kernel memory corruption, copy_to_user() can benefit from such checking too: Here it protects against kernel information leaks. Signed-off-by: Jan Beulich <jbeulich@suse.com> Cc: <arjan@linux.intel.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/5265059502000078000FC4F6@nat28.tlf.novell.com Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Arjan van de Ven <arjan@linux.intel.com>
Diffstat (limited to 'arch/x86/include/asm/uaccess.h')
-rw-r--r--arch/x86/include/asm/uaccess.h30
1 files changed, 30 insertions, 0 deletions
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index c9799ed208a8..8ec57c07b125 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -544,6 +544,8 @@ extern struct movsl_mask {
544 544
545unsigned long __must_check _copy_from_user(void *to, const void __user *from, 545unsigned long __must_check _copy_from_user(void *to, const void __user *from,
546 unsigned n); 546 unsigned n);
547unsigned long __must_check _copy_to_user(void __user *to, const void *from,
548 unsigned n);
547 549
548#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS 550#ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS
549# define copy_user_diag __compiletime_error 551# define copy_user_diag __compiletime_error
@@ -553,6 +555,8 @@ unsigned long __must_check _copy_from_user(void *to, const void __user *from,
553 555
554extern void copy_user_diag("copy_from_user() buffer size is too small") 556extern void copy_user_diag("copy_from_user() buffer size is too small")
555copy_from_user_overflow(void); 557copy_from_user_overflow(void);
558extern void copy_user_diag("copy_to_user() buffer size is too small")
559copy_to_user_overflow(void) __asm__("copy_from_user_overflow");
556 560
557#undef copy_user_diag 561#undef copy_user_diag
558 562
@@ -563,6 +567,11 @@ __compiletime_warning("copy_from_user() buffer size is not provably correct")
563__copy_from_user_overflow(void) __asm__("copy_from_user_overflow"); 567__copy_from_user_overflow(void) __asm__("copy_from_user_overflow");
564#define __copy_from_user_overflow(size, count) __copy_from_user_overflow() 568#define __copy_from_user_overflow(size, count) __copy_from_user_overflow()
565 569
570extern void
571__compiletime_warning("copy_to_user() buffer size is not provably correct")
572__copy_to_user_overflow(void) __asm__("copy_from_user_overflow");
573#define __copy_to_user_overflow(size, count) __copy_to_user_overflow()
574
566#else 575#else
567 576
568static inline void 577static inline void
@@ -571,6 +580,8 @@ __copy_from_user_overflow(int size, unsigned long count)
571 WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count); 580 WARN(1, "Buffer overflow detected (%d < %lu)!\n", size, count);
572} 581}
573 582
583#define __copy_to_user_overflow __copy_from_user_overflow
584
574#endif 585#endif
575 586
576static inline unsigned long __must_check 587static inline unsigned long __must_check
@@ -608,7 +619,26 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
608 return n; 619 return n;
609} 620}
610 621
622static inline unsigned long __must_check
623copy_to_user(void __user *to, const void *from, unsigned long n)
624{
625 int sz = __compiletime_object_size(from);
626
627 might_fault();
628
629 /* See the comment in copy_from_user() above. */
630 if (likely(sz < 0 || sz >= n))
631 n = _copy_to_user(to, from, n);
632 else if(__builtin_constant_p(n))
633 copy_to_user_overflow();
634 else
635 __copy_to_user_overflow(sz, n);
636
637 return n;
638}
639
611#undef __copy_from_user_overflow 640#undef __copy_from_user_overflow
641#undef __copy_to_user_overflow
612 642
613#endif /* _ASM_X86_UACCESS_H */ 643#endif /* _ASM_X86_UACCESS_H */
614 644