From owner-freebsd-current Thu Jun 8 4:51: 0 2000 Delivered-To: freebsd-current@freebsd.org Received: from gidora.zeta.org.au (gidora.zeta.org.au [203.26.10.25]) by hub.freebsd.org (Postfix) with SMTP id 8266937B97D for ; Thu, 8 Jun 2000 04:50:55 -0700 (PDT) (envelope-from bde@zeta.org.au) Received: (qmail 5199 invoked from network); 8 Jun 2000 11:50:51 -0000 Received: from unknown (HELO bde.zeta.org.au) (203.2.228.102) by gidora.zeta.org.au with SMTP; 8 Jun 2000 11:50:51 -0000 Date: Thu, 8 Jun 2000 21:50:48 +1000 (EST) From: Bruce Evans X-Sender: bde@besplex.bde.org To: Kris Kennaway Cc: current@FreeBSD.ORG Subject: Re: mktemp() patch In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-current@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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