Openwall Project   /home  Owl  JtR  Pro  crypt  pam_passwdqc  tcb  phpass  scanlogd  popa3d  msulogin  /  Linux  BIND  /  advisories  presentations  /  services  donations  /  wordlists  passwords  /  NEWS  community  lists  Wiki  CVSweb  mirrors  signatures
bringing security into open environments
 
Password Recovery Resources on the Net
[<prev] [next>] [<thread-prev] [thread-next>] [month] [year] [list]
Date: Fri, 15 Aug 2008 10:32:58 -0400
From: "Todd C. Miller" <Todd.Miller@...rtesan.com>
To: oss-security@...ts.openwall.com
Subject: Re: CVE id request: mktemp 

In message <20080815115550.GD31878@...lde.de>
	so spake Nico Golde (oss-security+ml):

> Hi,
> mktemp (not the coreutils one) from
> ftp://ftp.mktemp.org/pub/mktemp/ is not generating fully
> random names. Steve, can you assign a CVE id to this?
> 
> This is=20
> http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=3D495193
> I wrote an explanation on why this happens, available on:
> http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=3D495193#30

The private version of mktemp(3) used by mktemp(1) is based on the
BSD version which uses the pid as part of the file name.  If there
is a small number X's, only the pid will be used when constructing
the file name.

It's probably fine to just remove the pid from the equation entirely.
I'll look at putting out a new version of mktemp(1) in the next few
days with this fix and some other changes.

In the meantime, the following diff should suffice.

 - todd

Index: priv_mktemp.c
===================================================================
RCS file: /home/cvs/courtesan/mktemp/priv_mktemp.c,v
retrieving revision 1.8
diff -u -p -u -r1.8 priv_mktemp.c
--- priv_mktemp.c	26 Apr 2004 18:31:35 -0000	1.8
+++ priv_mktemp.c	15 Aug 2008 14:31:32 -0000
@@ -84,22 +84,23 @@ _gettemp(path, doopen, domkdir)
 		return(0);
 	}
 
-	pid = getpid();
+	if (*path == '\0') {
+		errno = EINVAL;
+		return(0);
+	}
+
 	for (trv = path; *trv; ++trv)
 		;
-	--trv;
-	while (trv >= path && *trv == 'X' && pid != 0) {
-		*trv-- = (pid % 10) + '0';
-		pid /= 10;
-	}
-	while (trv >= path && *trv == 'X') {
-		char c;
+	do {
+		--trv;
+	} while (trv >= path && *trv == 'X');
+	start = trv + 1;
 
+again:
+	for (trv = start; *trv; ++trv) {
 		pid = (get_random() & 0xffff) % (26+26);
-		c = alphabet[pid];
-		*trv-- = c;
+		*trv = alphabet[pid];
 	}
-	start = trv + 1;
 
 	/*
 	 * check the target directory; if you have six X's and it
@@ -124,58 +125,20 @@ _gettemp(path, doopen, domkdir)
 		}
 	}
 
-	for (;;) {
-		if (doopen) {
-			if ((*doopen =
-			    open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
-				return(1);
-			if (errno != EEXIST)
-				return(0);
-		} else if (domkdir) {
-			if (mkdir(path, 0700) == 0)
-				return(1);
-			if (errno != EEXIST)
-				return(0);
-		} else if (lstat(path, &sbuf))
-			return(errno == ENOENT ? 1 : 0);
+	if (doopen) {
+		if ((*doopen =
+		    open(path, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0)
+			return(1);
+		if (errno != EEXIST)
+			return(0);
+	} else if (domkdir) {
+		if (mkdir(path, 0700) == 0)
+			return(1);
+		if (errno != EEXIST)
+			return(0);
+	} else if (lstat(path, &sbuf))
+		return(errno == ENOENT ? 1 : 0);
 
-		/* tricky little algorithm for backward compatibility */
-		for (trv = start;;) {
-			if (!*trv)
-				return (0);
-			if (*trv == 'Z')
-				*trv++ = 'a';
-			else {
-				if (isdigit((unsigned char)(*trv)))
-					*trv = 'a';
-				else if (*trv == 'z')	/* wrap from z to A */
-					*trv = 'A';
-				else {
-#ifdef HAVE_EBCDIC
-					switch(*trv) {
-					case 'i':
-						*trv = 'j';
-						break;
-					case 'r':
-						*trv = 's';
-						break;
-					case 'I':
-						*trv = 'J';
-						break;
-					case 'R':
-						*trv = 'S';
-						break;
-					default:
-						++*trv;
-						break;
-					}
-#else
-					++*trv;
-#endif
-				}
-				break;
-			}
-		}
-	}
+	goto again;
 	/*NOTREACHED*/
 }

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Powered by Openwall GNU/*/Linux - Powered by OpenVZ