aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLachlan McIlroy <lachlan@sgi.com>2007-02-10 02:34:38 -0500
committerTim Shimmin <tes@sgi.com>2007-02-10 02:34:38 -0500
commitdc74eaad8cda9f12a885639b4f2513c99e9b483a (patch)
treeb32ac71e87436179c2f9ef94f6e9aca7e4aa7b4e
parent585e6d8856526a846b90b485abf37ec40e5da1cf (diff)
[XFS] Prevent buffer overrun in cmn_err().
The message buffer used by cmn_err() is only 256 bytes and some CXFS messages were exceeding this length. Since we were using vsprintf() and not checking for buffer overruns we were clobbering memory beyond the buffer. The size of the buffer has been increased to 1024 bytes so we can capture these larger messages and we are now using vsnprintf() to prevent overrunning the buffer size. SGI-PV: 958599 SGI-Modid: xfs-linux-melb:xfs-kern:27561a Signed-off-by: Lachlan McIlroy <lachlan@sgi.com> Signed-off-by: Geoffrey Wehrman <gwehrman@sgi.com> Signed-off-by: Tim Shimmin <tes@sgi.com>
-rw-r--r--fs/xfs/support/debug.c23
1 files changed, 13 insertions, 10 deletions
diff --git a/fs/xfs/support/debug.c b/fs/xfs/support/debug.c
index 4363512d2f90..08bbd3cb87ae 100644
--- a/fs/xfs/support/debug.c
+++ b/fs/xfs/support/debug.c
@@ -19,7 +19,7 @@
19#include "debug.h" 19#include "debug.h"
20#include "spin.h" 20#include "spin.h"
21 21
22static char message[256]; /* keep it off the stack */ 22static char message[1024]; /* keep it off the stack */
23static DEFINE_SPINLOCK(xfs_err_lock); 23static DEFINE_SPINLOCK(xfs_err_lock);
24 24
25/* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */ 25/* Translate from CE_FOO to KERN_FOO, err_level(CE_FOO) == KERN_FOO */
@@ -44,13 +44,14 @@ cmn_err(register int level, char *fmt, ...)
44 spin_lock_irqsave(&xfs_err_lock,flags); 44 spin_lock_irqsave(&xfs_err_lock,flags);
45 va_start(ap, fmt); 45 va_start(ap, fmt);
46 if (*fmt == '!') fp++; 46 if (*fmt == '!') fp++;
47 len = vsprintf(message, fp, ap); 47 len = vsnprintf(message, sizeof(message), fp, ap);
48 if (level != CE_DEBUG && message[len-1] != '\n') 48 if (len >= sizeof(message))
49 strcat(message, "\n"); 49 len = sizeof(message) - 1;
50 printk("%s%s", err_level[level], message); 50 if (message[len-1] == '\n')
51 message[len-1] = 0;
52 printk("%s%s\n", err_level[level], message);
51 va_end(ap); 53 va_end(ap);
52 spin_unlock_irqrestore(&xfs_err_lock,flags); 54 spin_unlock_irqrestore(&xfs_err_lock,flags);
53
54 BUG_ON(level == CE_PANIC); 55 BUG_ON(level == CE_PANIC);
55} 56}
56 57
@@ -64,11 +65,13 @@ icmn_err(register int level, char *fmt, va_list ap)
64 if(level > XFS_MAX_ERR_LEVEL) 65 if(level > XFS_MAX_ERR_LEVEL)
65 level = XFS_MAX_ERR_LEVEL; 66 level = XFS_MAX_ERR_LEVEL;
66 spin_lock_irqsave(&xfs_err_lock,flags); 67 spin_lock_irqsave(&xfs_err_lock,flags);
67 len = vsprintf(message, fmt, ap); 68 len = vsnprintf(message, sizeof(message), fmt, ap);
68 if (level != CE_DEBUG && message[len-1] != '\n') 69 if (len >= sizeof(message))
69 strcat(message, "\n"); 70 len = sizeof(message) - 1;
71 if (message[len-1] == '\n')
72 message[len-1] = 0;
73 printk("%s%s\n", err_level[level], message);
70 spin_unlock_irqrestore(&xfs_err_lock,flags); 74 spin_unlock_irqrestore(&xfs_err_lock,flags);
71 printk("%s%s", err_level[level], message);
72 BUG_ON(level == CE_PANIC); 75 BUG_ON(level == CE_PANIC);
73} 76}
74 77