diff options
author | Arjan van de Ven <arjan@infradead.org> | 2009-09-30 07:05:23 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-10-01 05:31:04 -0400 |
commit | 4a3127693001c61a21d1ce680db6340623f52e93 (patch) | |
tree | 380f5f64098926e8b3f64785580cfdac1b8b3b96 /arch | |
parent | ff60fab71bb3b4fdbf8caf57ff3739ffd0887396 (diff) |
x86: Turn the copy_from_user check into an (optional) compile time warning
A previous patch added the buffer size check to copy_from_user().
One of the things learned from analyzing the result of the previous
patch is that in general, gcc is really good at proving that the
code contains sufficient security checks to not need to do a
runtime check. But that for those cases where gcc could not prove
this, there was a relatively high percentage of real security
issues.
This patch turns the case of "gcc cannot prove" into a compile time
warning, as long as a sufficiently new gcc is in use that supports
this. The objective is that these warnings will trigger developers
checking new cases out before a security hole enters a linux kernel
release.
Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: James Morris <jmorris@namei.org>
Cc: Jan Beulich <jbeulich@novell.com>
LKML-Reference: <20090930130523.348ae6c4@infradead.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/uaccess_32.h | 12 | ||||
-rw-r--r-- | arch/x86/lib/usercopy_32.c | 6 |
2 files changed, 15 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); | ||