Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Jan 2000 19:54:11 -0800 (PST)
From:      Kris Kennaway <kris@hub.freebsd.org>
To:        Peter Jeremy <peter.jeremy@alcatel.com.au>
Cc:        audit@FreeBSD.ORG
Subject:   Re: libc patch to warn about tempfiles
Message-ID:  <Pine.BSF.4.21.0001231945020.3724-100000@hub.freebsd.org>
In-Reply-To: <Pine.BSF.4.21.0001161946030.44688-100000@hub.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
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. It base-64
encodes the PID into the first 3 characters (first 17 bits) + 1 random bit
from arc4random() :) The remaining characters are taken from a larger set
- basically all of the non-special characters which aren't likely to cause
problems with code. With 6 X's and 76 characters in the second set this
gives us 877952 possible tempfiles per PID, which is probably "good
enough". Comments?

Kris

Index: stdio/mktemp.c
===================================================================
RCS file: /home/ncvs/src/lib/libc/stdio/mktemp.c,v
retrieving revision 1.18
diff -u -r1.18 mktemp.c
--- stdio/mktemp.c	2000/01/12 09:23:41	1.18
+++ stdio/mktemp.c	2000/01/24 03:48:46
@@ -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;
@@ -104,7 +109,8 @@
 {
 	register char *start, *trv, *suffp;
 	struct stat sbuf;
-	int pid, rval;
+	int n, numx, pid, rval;
+	uint32_t in;
 
 	if (doopen && domkdir) {
 		errno = EINVAL;
@@ -121,22 +127,29 @@
 		return (0);
 	}
 	pid = getpid();
-	while (*trv == 'X' && pid != 0) {
-		*trv-- = (pid % 10) + '0';
-		pid /= 10;
+	while (*trv == 'X')
+		trv--;
+	start = trv++;
+	numx = (suffp - trv);
+	if (numx < 3) { /* Not enough bits to base64-encode PID */
+		errno = EINVAL;
+		return(0);
 	}
-	while (*trv == 'X') {
-		char c;
-
-		pid = (arc4random() & 0xffff) % (26+26);
-		if (pid < 26)
-			c = pid + 'A';
-		else
-			c = (pid - 26) + 'a';
-		*trv-- = c;
+	in = (arc4random() & 0x00007FFF) | (pid << 15);
+	n = 3;
+	/* Base-64 encode the PID */
+	while (--n >= 0) {
+		*trv++ = base64[(in & 0xFC000000) >> 26];
+		in <<= 6;
 	}
-	start = trv + 1;
 
+	/* Pad out the remaining X's with random characters from our enlarged
+	   set */
+	while (trv < suffp) {
+		pid = (arc4random() % sizeof(padchar));
+		*trv++ = padchar[pid];
+	}
+	trv = start;
 	/*
 	 * check the target directory; if you have six X's and it
 	 * doesn't exist this runs for a *very* long time.



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?Pine.BSF.4.21.0001231945020.3724-100000>