Date: Thu, 8 Jun 2000 21:50:48 +1000 (EST) From: Bruce Evans <bde@zeta.org.au> To: Kris Kennaway <kris@FreeBSD.ORG> Cc: current@FreeBSD.ORG Subject: Re: mktemp() patch Message-ID: <Pine.BSF.4.21.0006082054040.513-100000@besplex.bde.org> In-Reply-To: <Pine.BSF.4.21.0006071758550.11848-100000@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, 7 Jun 2000, Kris Kennaway wrote: > Instead of using only alphabetic characters, the patch uses the following > character set: > > 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz@#%^-_=+:,.~ > > which is not believed to cause any problems with shells. The PID is also I think it should use only letters and digits. For 6 X's, this gives a namespace of size 52^6 provided the namespace is not gratuitously (?) reduced using the pid. > Index: mktemp.c > =================================================================== > RCS file: /home/ncvs/src/lib/libc/stdio/mktemp.c,v > retrieving revision 1.19 > diff -u -r1.19 mktemp.c > --- mktemp.c 2000/01/27 23:06:46 1.19 > +++ mktemp.c 2000/06/08 00:57:17 > ... > @@ -120,20 +127,22 @@ > errno = EINVAL; > return (0); > } > - pid = getpid(); > - while (*trv == 'X' && pid != 0) { > - *trv-- = (pid % 10) + '0'; > - pid /= 10; > + > + /* Encode the PID (with 1 bit of randomness) into 3 base-64 chars */ > + pid = getpid() | (arc4random() & 0x00020000); > + for (n = 0; *trv == 'X' && n < 3; n++) { > + *trv-- = base64[pid & 0x3f]; > + pid >>= 6; > } Why are we still using the pid? It is highly non-random. It was originally used to ensure a separate starting point for separate processes, and because there was no truly random RNG. Now, arc4random() is hopefully random enough to give a good starting point by itself. It is a feature (a consequence of true randomness) that it may give identical starting points for separate processes. > @@ -179,15 +188,11 @@ > for (trv = start;;) { > if (*trv == '\0' || trv == suffp) ^^^^^^^ normal style > return(0); > - if (*trv == 'Z') > - *trv++ = 'a'; > + pad = strchr(padchar, *trv); > + if (pad == NULL || !*++pad) ^ style bug > + *trv++ = padchar[0]; > else { > - if (isdigit((unsigned char)*trv)) > - *trv = 'a'; > - else if (*trv == 'z') /* inc from z to A */ > - *trv = 'A'; > - else > - ++*trv; > + *trv++ = *pad; > break; > } > } This finishes bogotifying the comment before the for loop: /* tricky little algorithm for backward compatibility */ Don't forget to remove it :-). The algorithm is now a simple increment in base strlen(padchar). Perhaps it should use a random increment initially if there aren't enough X's to provide enough randomness in the starting point, or always. All cases do slow filesystem syscalls, so it might be cheap enough to randomize the whole path every time. Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0006082054040.513-100000>