aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@novell.com>2006-01-11 16:46:48 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-11 22:05:03 -0500
commit5f1d189f8a87930d62c507800a8ac20b9a185e41 (patch)
treef83f756d8481dafe3b8ddba5b741ec6b5cf33e96
parent1b2f6304500930ab534a6aa3198bce0c51586206 (diff)
[PATCH] x86_64: Display meaningful part of filename during BUG()
When building in a separate objtree, file names produced by BUG() & Co. can get fairly long; printing only the first 50 characters may thus result in (almost) no useful information. The following change makes it so that rather the last 50 characters of the filename get printed. Signed-Off-By: Jan Beulich <jbeulich@novell.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/x86_64/kernel/traps.c12
-rw-r--r--arch/x86_64/lib/usercopy.c12
-rw-r--r--include/asm-x86_64/uaccess.h1
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:
340void handle_BUG(struct pt_regs *regs) 340void 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
112long strnlen_user(const char __user *s, long n) 112long __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
129long 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
132long strlen_user(const char __user *s) 136long 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
348long strncpy_from_user(char *dst, const char __user *src, long count); 348long strncpy_from_user(char *dst, const char __user *src, long count);
349long __strncpy_from_user(char *dst, const char __user *src, long count); 349long __strncpy_from_user(char *dst, const char __user *src, long count);
350long strnlen_user(const char __user *str, long n); 350long strnlen_user(const char __user *str, long n);
351long __strnlen_user(const char __user *str, long n);
351long strlen_user(const char __user *str); 352long strlen_user(const char __user *str);
352unsigned long clear_user(void __user *mem, unsigned long len); 353unsigned long clear_user(void __user *mem, unsigned long len);
353unsigned long __clear_user(void __user *mem, unsigned long len); 354unsigned long __clear_user(void __user *mem, unsigned long len);