diff options
author | archie <archie@FreeBSD.org> | 1999-06-06 02:41:55 +0000 |
---|---|---|
committer | archie <archie@FreeBSD.org> | 1999-06-06 02:41:55 +0000 |
commit | f40f015be9fdde8af432707fbebe0acf7610c6f1 (patch) | |
tree | e7d6ee8d79b820feb59d8046c0fb53fc95aecf2b | |
parent | b4fbb76a1315606ed5232890a285663987ef1808 (diff) | |
download | FreeBSD-src-f40f015be9fdde8af432707fbebe0acf7610c6f1.zip FreeBSD-src-f40f015be9fdde8af432707fbebe0acf7610c6f1.tar.gz |
The function ksprintn(), which is used to convert numbers to ASCII, is not
reentrant because it returns a static buffer. This results in a race condition
when/if an interrupt handler calls log(), printf() etc. Fix this.
-rw-r--r-- | sys/kern/subr_prf.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c index c1937b7..4666a25 100644 --- a/sys/kern/subr_prf.c +++ b/sys/kern/subr_prf.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 - * $Id: subr_prf.c,v 1.51 1998/12/03 04:45:56 archie Exp $ + * $Id: subr_prf.c,v 1.52 1999/06/01 18:20:29 jlemon Exp $ */ #include <sys/param.h> @@ -60,6 +60,9 @@ #define TOTTY 0x02 #define TOLOG 0x04 +/* Max number conversion buffer length: a long in base 8, plus NUL byte */ +#define MAXNBUF (sizeof(long) * NBBY / 3 + 2) + struct tty *constty; /* pointer to console "window" tty */ struct putchar_arg { @@ -76,7 +79,7 @@ static void (*v_putc)(int) = cnputc; /* routine to putc on virtual console */ static void logpri __P((int level)); static void msglogchar(int c, void *dummyarg); static void putchar __P((int ch, void *arg)); -static char *ksprintn __P((u_long num, int base, int *len)); +static char *ksprintn __P((char *nbuf, u_long num, int base, int *len)); static void snprintf_func __P((int ch, void *arg)); static int consintr = 1; /* Ok to handle console interrupts? */ @@ -215,9 +218,10 @@ logpri(level) int level; { register char *p; + char nbuf[MAXNBUF]; msglogchar('<', NULL); - for (p = ksprintn((u_long)level, 10, NULL); *p;) + for (p = ksprintn(nbuf, (u_long)level, 10, NULL); *p;) msglogchar(*p--, NULL); msglogchar('>', NULL); } @@ -384,17 +388,18 @@ snprintf_func(int ch, void *arg) /* * Put a number (base <= 16) in a buffer in reverse order; return an * optional length and a pointer to the NULL terminated (preceded?) - * buffer. + * buffer. The buffer pointed to by "buf" must have length >= MAXNBUF. */ static char * -ksprintn(ul, base, lenp) +ksprintn(buf, ul, base, lenp) + char *buf; register u_long ul; register int base, *lenp; { /* A long in base 8, plus NULL. */ - static char buf[sizeof(long) * NBBY / 3 + 2]; register char *p; p = buf; + *p = '\0'; do { *++p = hex2ascii(ul % base); } while (ul /= base); @@ -433,6 +438,7 @@ int kvprintf(char const *fmt, void (*func)(int, void*), void *arg, int radix, va_list ap) { #define PCHAR(c) {int cc=(c); if (func) (*func)(cc,arg); else *d++ = cc; retval++; } + char nbuf[MAXNBUF]; char *p, *q, *d; u_char *up; int ch, n; @@ -511,7 +517,7 @@ reswitch: switch (ch = (u_char)*fmt++) { case 'b': ul = va_arg(ap, int); p = va_arg(ap, char *); - for (q = ksprintn(ul, *p++, NULL); *q;) + for (q = ksprintn(nbuf, ul, *p++, NULL); *q;) PCHAR(*q--); if (!ul) @@ -610,7 +616,7 @@ number: if (sign && (long)ul < 0L) { neg = 1; ul = -(long)ul; } - p = ksprintn(ul, base, &tmp); + p = ksprintn(nbuf, ul, base, &tmp); if (sharpflag && ul != 0) { if (base == 8) tmp++; |