mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
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.
This commit is contained in:
parent
f5a99677a3
commit
ad4f8dbd23
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=47773
@ -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++;
|
||||
|
Loading…
Reference in New Issue
Block a user