Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Jan 2000 16:21:55 +1100
From:      Peter Jeremy <peter.jeremy@alcatel.com.au>
To:        Kris Kennaway <kris@hub.freebsd.org>
Cc:        audit@FreeBSD.ORG
Subject:   Re: libc patch to warn about tempfiles
Message-ID:  <00Jan24.162158est.115251@border.alcanet.com.au>
In-Reply-To: <Pine.BSF.4.21.0001231945020.3724-100000@hub.freebsd.org>; from kris@hub.freebsd.org on Mon, Jan 24, 2000 at 02:55:15PM %2B1100
References:  <Pine.BSF.4.21.0001161946030.44688-100000@hub.freebsd.org> <Pine.BSF.4.21.0001231945020.3724-100000@hub.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 2000-Jan-24 14:55:15 +1100, Kris Kennaway <kris@hub.freebsd.org> wrote:
>On Sun, 16 Jan 2000, Kris Kennaway wrote:
>
>> > I think that changing the algorithm to use a denser encoding (eg
>> > encoding the PID in base-62 or more, rather than base 10) would be
>> > a better solution.  This way you don't need to change the functions
>> > using mktemp() et al.
>> 
>> Hmm..that's not a bad idea. With base-64 we'd have 36 bits, of which about
>> 17 would be taken up by the encoded PID, leaving about 520000 possible
>> tempfiles (a factor of 10^4 better than now). OTOH, using 10 X's in the
>> current system has a target space of size 52^6, or 1.97e+10 :-)
>
>Okay, here's a (lightly tested) patch which implements this.

Adn here's a (non-tested) alternative.  This differs from your patch
as follows:
- Add a few const's.
- The program flow remains identical to the current code, just the
  modulus constants change.
- I prefer (sizeof(padchar) - 1) to remove the need for a strlen inside
  a loop.
- Correctly increment the random filename if the first choice exists.

Index: mktemp.c
===================================================================
RCS file: /home/CVSROOT/src/lib/libc/stdio/mktemp.c,v
retrieving revision 1.18
diff -u -r1.18 mktemp.c
--- mktemp.c	2000/01/12 09:23:41	1.18
+++ mktemp.c	2000/01/24 05:15:04
@@ -52,6 +52,11 @@
 
 static int _gettemp __P((char *, int *, int, int));
 
+static unsigned char base64[] =
+	".#0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+static unsigned char padchar[] =
+"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!@#%^&-_=+:,.~";
+
 int
 mkstemps(path, slen)
 	char *path;
@@ -103,8 +108,10 @@
 	int slen;
 {
 	register char *start, *trv, *suffp;
+	char *pad;
 	struct stat sbuf;
-	int pid, rval;
+	uint32_t pid;
+	int rval, n;
 
 	if (doopen && domkdir) {
 		errno = EINVAL;
@@ -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;
 	}
-	while (*trv == 'X') {
-		char c;
+	if (n < 3) {	/* Not enough characters to encode PID */
+		errno = EINVAL;
+		return(0);
+	}
 
-		pid = (arc4random() & 0xffff) % (26+26);
-		if (pid < 26)
-			c = pid + 'A';
-		else
-			c = (pid - 26) + 'a';
-		*trv-- = c;
+	/* Fill remaining space with random characters */
+	while (*trv == 'X') {
+		pid = arc4random() % (sizeof(padchar) - 1);
+		*trv-- = padchar[pid];
 	}
 	start = trv + 1;
 
@@ -179,15 +188,11 @@
 		for (trv = start;;) {
 			if (*trv == '\0' || trv == suffp)
 				return(0);
-			if (*trv == 'Z')
-				*trv++ = 'a';
+			pad = strchr(padchar, *trv);
+			if (pad == NULL || !*++pad)
+				*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;
 			}
 		}


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?00Jan24.162158est.115251>