summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_prf.c
diff options
context:
space:
mode:
authorarchie <archie@FreeBSD.org>1999-06-06 02:41:55 +0000
committerarchie <archie@FreeBSD.org>1999-06-06 02:41:55 +0000
commitf40f015be9fdde8af432707fbebe0acf7610c6f1 (patch)
treee7d6ee8d79b820feb59d8046c0fb53fc95aecf2b /sys/kern/subr_prf.c
parentb4fbb76a1315606ed5232890a285663987ef1808 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'sys/kern/subr_prf.c')
-rw-r--r--sys/kern/subr_prf.c22
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++;
OpenPOWER on IntegriCloud