diff options
author | Helge Deller <deller@gmx.de> | 2010-02-01 14:56:33 -0500 |
---|---|---|
committer | Kyle McMartin <kyle@redhat.com> | 2010-03-06 17:54:09 -0500 |
commit | 888c31fc83ddc7fcd9947cb67c5718b4e3dd5e1b (patch) | |
tree | 15ef949561b6c8b319bb686eadec20c98148dfa3 /arch/parisc/include | |
parent | a3bee03e718c9251456676b71a723a34c999e891 (diff) |
parisc: add strict copy size checks (v2)
Add CONFIG_DEBUG_STRICT_USER_COPY_CHECKS, copied from the x86
implementation. Tested with 32 and 64bit kernel.
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Kyle McMartin <kyle@mcmartin.ca>
Diffstat (limited to 'arch/parisc/include')
-rw-r--r-- | arch/parisc/include/asm/uaccess.h | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/arch/parisc/include/asm/uaccess.h b/arch/parisc/include/asm/uaccess.h index 7cf799d70b4c..ff4cf9dab8d2 100644 --- a/arch/parisc/include/asm/uaccess.h +++ b/arch/parisc/include/asm/uaccess.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <asm/page.h> | 7 | #include <asm/page.h> |
8 | #include <asm/system.h> | 8 | #include <asm/system.h> |
9 | #include <asm/cache.h> | 9 | #include <asm/cache.h> |
10 | #include <asm/errno.h> | ||
10 | #include <asm-generic/uaccess-unaligned.h> | 11 | #include <asm-generic/uaccess-unaligned.h> |
11 | 12 | ||
12 | #define VERIFY_READ 0 | 13 | #define VERIFY_READ 0 |
@@ -234,13 +235,35 @@ extern long lstrnlen_user(const char __user *,long); | |||
234 | 235 | ||
235 | unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len); | 236 | unsigned long copy_to_user(void __user *dst, const void *src, unsigned long len); |
236 | #define __copy_to_user copy_to_user | 237 | #define __copy_to_user copy_to_user |
237 | unsigned long copy_from_user(void *dst, const void __user *src, unsigned long len); | 238 | unsigned long __copy_from_user(void *dst, const void __user *src, unsigned long len); |
238 | #define __copy_from_user copy_from_user | ||
239 | unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len); | 239 | unsigned long copy_in_user(void __user *dst, const void __user *src, unsigned long len); |
240 | #define __copy_in_user copy_in_user | 240 | #define __copy_in_user copy_in_user |
241 | #define __copy_to_user_inatomic __copy_to_user | 241 | #define __copy_to_user_inatomic __copy_to_user |
242 | #define __copy_from_user_inatomic __copy_from_user | 242 | #define __copy_from_user_inatomic __copy_from_user |
243 | 243 | ||
244 | extern void copy_from_user_overflow(void) | ||
245 | #ifdef CONFIG_DEBUG_STRICT_USER_COPY_CHECKS | ||
246 | __compiletime_error("copy_from_user() buffer size is not provably correct") | ||
247 | #else | ||
248 | __compiletime_warning("copy_from_user() buffer size is not provably correct") | ||
249 | #endif | ||
250 | ; | ||
251 | |||
252 | static inline unsigned long __must_check copy_from_user(void *to, | ||
253 | const void __user *from, | ||
254 | unsigned long n) | ||
255 | { | ||
256 | int sz = __compiletime_object_size(to); | ||
257 | int ret = -EFAULT; | ||
258 | |||
259 | if (likely(sz == -1 || !__builtin_constant_p(n) || sz >= n)) | ||
260 | ret = __copy_from_user(to, from, n); | ||
261 | else | ||
262 | copy_from_user_overflow(); | ||
263 | |||
264 | return ret; | ||
265 | } | ||
266 | |||
244 | struct pt_regs; | 267 | struct pt_regs; |
245 | int fixup_exception(struct pt_regs *regs); | 268 | int fixup_exception(struct pt_regs *regs); |
246 | 269 | ||