diff options
-rw-r--r-- | arch/x86/include/asm/uaccess_32.h | 12 | ||||
-rw-r--r-- | arch/x86/lib/usercopy_32.c | 6 | ||||
-rw-r--r-- | include/linux/compiler-gcc4.h | 3 | ||||
-rw-r--r-- | include/linux/compiler.h | 4 |
4 files changed, 22 insertions, 3 deletions
diff --git a/arch/x86/include/asm/uaccess_32.h b/arch/x86/include/asm/uaccess_32.h index 582d6aef7417..952f9e793c3e 100644 --- a/arch/x86/include/asm/uaccess_32.h +++ b/arch/x86/include/asm/uaccess_32.h | |||
@@ -191,6 +191,13 @@ unsigned long __must_check _copy_from_user(void *to, | |||
191 | const void __user *from, | 191 | const void __user *from, |
192 | unsigned long n); | 192 | unsigned long n); |
193 | 193 | ||
194 | |||
195 | extern void copy_from_user_overflow(void) | ||
196 | #ifdef CONFIG_DEBUG_STACKOVERFLOW | ||
197 | __compiletime_warning("copy_from_user() buffer size is not provably correct") | ||
198 | #endif | ||
199 | ; | ||
200 | |||
194 | static inline unsigned long __must_check copy_from_user(void *to, | 201 | static inline unsigned long __must_check copy_from_user(void *to, |
195 | const void __user *from, | 202 | const void __user *from, |
196 | unsigned long n) | 203 | unsigned long n) |
@@ -200,10 +207,9 @@ static inline unsigned long __must_check copy_from_user(void *to, | |||
200 | 207 | ||
201 | if (likely(sz == -1 || sz >= n)) | 208 | if (likely(sz == -1 || sz >= n)) |
202 | ret = _copy_from_user(to, from, n); | 209 | ret = _copy_from_user(to, from, n); |
203 | #ifdef CONFIG_DEBUG_VM | ||
204 | else | 210 | else |
205 | WARN(1, "Buffer overflow detected!\n"); | 211 | copy_from_user_overflow(); |
206 | #endif | 212 | |
207 | return ret; | 213 | return ret; |
208 | } | 214 | } |
209 | 215 | ||
diff --git a/arch/x86/lib/usercopy_32.c b/arch/x86/lib/usercopy_32.c index 8498684e45b0..e218d5df85ff 100644 --- a/arch/x86/lib/usercopy_32.c +++ b/arch/x86/lib/usercopy_32.c | |||
@@ -883,3 +883,9 @@ _copy_from_user(void *to, const void __user *from, unsigned long n) | |||
883 | return n; | 883 | return n; |
884 | } | 884 | } |
885 | EXPORT_SYMBOL(_copy_from_user); | 885 | EXPORT_SYMBOL(_copy_from_user); |
886 | |||
887 | void copy_from_user_overflow(void) | ||
888 | { | ||
889 | WARN(1, "Buffer overflow detected!\n"); | ||
890 | } | ||
891 | EXPORT_SYMBOL(copy_from_user_overflow); | ||
diff --git a/include/linux/compiler-gcc4.h b/include/linux/compiler-gcc4.h index a3aef5d55dba..f1709c1f9eae 100644 --- a/include/linux/compiler-gcc4.h +++ b/include/linux/compiler-gcc4.h | |||
@@ -39,3 +39,6 @@ | |||
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) | 41 | #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) |
42 | #if __GNUC_MINOR__ >= 4 | ||
43 | #define __compiletime_warning(message) __attribute__((warning(message))) | ||
44 | #endif | ||
diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 8e54108688f9..950356311f12 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h | |||
@@ -270,6 +270,10 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); | |||
270 | #ifndef __compiletime_object_size | 270 | #ifndef __compiletime_object_size |
271 | # define __compiletime_object_size(obj) -1 | 271 | # define __compiletime_object_size(obj) -1 |
272 | #endif | 272 | #endif |
273 | #ifndef __compiletime_warning | ||
274 | # define __compiletime_warning(message) | ||
275 | #endif | ||
276 | |||
273 | /* | 277 | /* |
274 | * Prevent the compiler from merging or refetching accesses. The compiler | 278 | * Prevent the compiler from merging or refetching accesses. The compiler |
275 | * is also forbidden from reordering successive instances of ACCESS_ONCE(), | 279 | * is also forbidden from reordering successive instances of ACCESS_ONCE(), |