Roland, the following looks OK to me. OK to commit? (I'm assuming that Neal tested it, but I'll test it a bit before commit as always)
Summary: printk may cause buffer overruns Original Submission: The implementation of printk in linux/dev/kernel/printk.c assumes that the formatted string is less than sizeof (buf) - 3 (BUF being a statically allocated string of 2048 bytes). Code in Linux violates this assumption. For instance, linux/src/drivers/pci/pci.c:pci_init which prints out the pci bus topography if debugging is enabled. I looked at writing a linux_vsnprintf to replace the linux_vsprintf, however, the code is a mess and the Mach printf code is much easier to work with (kern/printf.c). Hence, I modified that. Thanks. 2004-09-08 Neal H. Walfield <[EMAIL PROTECTED]> * linux/dev/kernel/printk.c: Include <kern/assert.h>. (printk): Use vsnprintf, not linux_vsprintf to avoid buffer overruns. * kern/printf.c (struct vsnprintf_cookie): New structure. (snputc): New function. (vsnprintf): Likewise. Index: linux/dev/kernel/printk.c =================================================================== RCS file: /cvsroot/hurd/gnumach/linux/dev/kernel/Attic/printk.c,v retrieving revision 1.1 diff -u -p -r1.1 printk.c --- linux/dev/kernel/printk.c 26 Apr 1999 05:49:36 -0000 1.1 +++ linux/dev/kernel/printk.c 8 Sep 2004 10:29:05 -0000 @@ -26,6 +26,7 @@ #define MACH_INCLUDE #include <stdarg.h> #include <asm/system.h> +#include <kern/assert.h> static char buf[2048]; @@ -40,14 +41,14 @@ printk (char *fmt, ...) va_list args; int n, flags; extern void cnputc (); - extern int linux_vsprintf (char *buf, char *fmt,...); char *p, *msg, *buf_end; static int msg_level = -1; save_flags (flags); cli (); va_start (args, fmt); - n = linux_vsprintf (buf + 3, fmt, args); + n = vsnprintf (buf + 3, sizeof (buf) - 3, fmt, args); + assert (n <= sizeof (buf) - 3); buf_end = buf + 3 + n; va_end (args); for (p = buf + 3; p < buf_end; p++) Index: kern/printf.c =================================================================== RCS file: /cvsroot/hurd/gnumach/kern/Attic/printf.c,v retrieving revision 1.2 diff -u -p -r1.2 printf.c --- kern/printf.c 23 Jul 2000 00:34:12 -0000 1.2 +++ kern/printf.c 8 Sep 2004 10:29:06 -0000 @@ -579,6 +579,34 @@ sprintf(char *buf, const char *fmt, ...) return (buf - start); } +struct vsnprintf_cookie +{ + char *buf; + int index; + int max_len; +}; + +static void +snputc(char c, vm_offset_t arg) +{ + struct vsnprintf_cookie *cookie = (void *) arg; + + if (cookie->index < cookie->max_len) + cookie->buf[cookie->index ++] = c; +} + +int +vsnprintf(char *buf, int size, const char *fmt, va_list args) +{ + struct vsnprintf_cookie cookie + = { .buf = buf, .index = 0, .max_len = size }; + + _doprnt (fmt, &args, snputc, 16, (vm_offset_t)&cookie); + cookie.buf[cookie.index] = '\0'; + + return cookie.index; +} + void safe_gets(str, maxlen) char *str; _______________________________________________ Bug-hurd mailing list [EMAIL PROTECTED] http://lists.gnu.org/mailman/listinfo/bug-hurd