diff options
author | Lachlan McIlroy <lachlan@sgi.com> | 2007-02-10 02:34:38 -0500 |
---|---|---|
committer | Tim Shimmin <tes@sgi.com> | 2007-02-10 02:34:38 -0500 |
commit | dc74eaad8cda9f12a885639b4f2513c99e9b483a (patch) | |
tree | b32ac71e87436179c2f9ef94f6e9aca7e4aa7b4e /fs/xfs/support/debug.c | |
parent | 585e6d8856526a846b90b485abf37ec40e5da1cf (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>
Diffstat (limited to 'fs/xfs/support/debug.c')
-rw-r--r-- | fs/xfs/support/debug.c | 23 |
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 | ||
22 | static char message[256]; /* keep it off the stack */ | 22 | static char message[1024]; /* keep it off the stack */ |
23 | static DEFINE_SPINLOCK(xfs_err_lock); | 23 | static 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 | ||