diff options
-rw-r--r-- | arch/x86_64/kernel/traps.c | 12 | ||||
-rw-r--r-- | arch/x86_64/lib/usercopy.c | 12 | ||||
-rw-r--r-- | include/asm-x86_64/uaccess.h | 1 |
3 files changed, 18 insertions, 7 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index d345c712c6ca..2671fd46ea85 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -340,7 +340,8 @@ bad: | |||
340 | void handle_BUG(struct pt_regs *regs) | 340 | void handle_BUG(struct pt_regs *regs) |
341 | { | 341 | { |
342 | struct bug_frame f; | 342 | struct bug_frame f; |
343 | char tmp; | 343 | long len; |
344 | const char *prefix = ""; | ||
344 | 345 | ||
345 | if (user_mode(regs)) | 346 | if (user_mode(regs)) |
346 | return; | 347 | return; |
@@ -350,10 +351,15 @@ void handle_BUG(struct pt_regs *regs) | |||
350 | if (f.filename >= 0 || | 351 | if (f.filename >= 0 || |
351 | f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) | 352 | f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) |
352 | return; | 353 | return; |
353 | if (__get_user(tmp, (char *)(long)f.filename)) | 354 | len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1; |
355 | if (len < 0 || len >= PATH_MAX) | ||
354 | f.filename = (int)(long)"unmapped filename"; | 356 | f.filename = (int)(long)"unmapped filename"; |
357 | else if (len > 50) { | ||
358 | f.filename += len - 50; | ||
359 | prefix = "..."; | ||
360 | } | ||
355 | printk("----------- [cut here ] --------- [please bite here ] ---------\n"); | 361 | printk("----------- [cut here ] --------- [please bite here ] ---------\n"); |
356 | printk(KERN_ALERT "Kernel BUG at %.50s:%d\n", (char *)(long)f.filename, f.line); | 362 | printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line); |
357 | } | 363 | } |
358 | 364 | ||
359 | #ifdef CONFIG_BUG | 365 | #ifdef CONFIG_BUG |
diff --git a/arch/x86_64/lib/usercopy.c b/arch/x86_64/lib/usercopy.c index db8abba1ad81..9bc2c295818e 100644 --- a/arch/x86_64/lib/usercopy.c +++ b/arch/x86_64/lib/usercopy.c | |||
@@ -109,14 +109,11 @@ unsigned long clear_user(void __user *to, unsigned long n) | |||
109 | * Return 0 on exception, a value greater than N if too long | 109 | * Return 0 on exception, a value greater than N if too long |
110 | */ | 110 | */ |
111 | 111 | ||
112 | long strnlen_user(const char __user *s, long n) | 112 | long __strnlen_user(const char __user *s, long n) |
113 | { | 113 | { |
114 | long res = 0; | 114 | long res = 0; |
115 | char c; | 115 | char c; |
116 | 116 | ||
117 | if (!access_ok(VERIFY_READ, s, n)) | ||
118 | return 0; | ||
119 | |||
120 | while (1) { | 117 | while (1) { |
121 | if (res>n) | 118 | if (res>n) |
122 | return n+1; | 119 | return n+1; |
@@ -129,6 +126,13 @@ long strnlen_user(const char __user *s, long n) | |||
129 | } | 126 | } |
130 | } | 127 | } |
131 | 128 | ||
129 | long strnlen_user(const char __user *s, long n) | ||
130 | { | ||
131 | if (!access_ok(VERIFY_READ, s, n)) | ||
132 | return 0; | ||
133 | return __strnlen_user(s, n); | ||
134 | } | ||
135 | |||
132 | long strlen_user(const char __user *s) | 136 | long strlen_user(const char __user *s) |
133 | { | 137 | { |
134 | long res = 0; | 138 | long res = 0; |
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h index 1bb8b8a24436..2892c4b7a28b 100644 --- a/include/asm-x86_64/uaccess.h +++ b/include/asm-x86_64/uaccess.h | |||
@@ -348,6 +348,7 @@ static inline int __copy_in_user(void __user *dst, const void __user *src, unsig | |||
348 | long strncpy_from_user(char *dst, const char __user *src, long count); | 348 | long strncpy_from_user(char *dst, const char __user *src, long count); |
349 | long __strncpy_from_user(char *dst, const char __user *src, long count); | 349 | long __strncpy_from_user(char *dst, const char __user *src, long count); |
350 | long strnlen_user(const char __user *str, long n); | 350 | long strnlen_user(const char __user *str, long n); |
351 | long __strnlen_user(const char __user *str, long n); | ||
351 | long strlen_user(const char __user *str); | 352 | long strlen_user(const char __user *str); |
352 | unsigned long clear_user(void __user *mem, unsigned long len); | 353 | unsigned long clear_user(void __user *mem, unsigned long len); |
353 | unsigned long __clear_user(void __user *mem, unsigned long len); | 354 | unsigned long __clear_user(void __user *mem, unsigned long len); |