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); |
