Bladeren bron

major improvements to temp file name generator

use current time in nanoseconds and some potentially-random (if aslr
is enabled) pointer values for the initial tempfile name generation,
and step via a cheap linear prng on collisions. limit the number of
retry attempts to prevent denial of service attacks even if an
attacker can guess the filenames.
Rich Felker 14 jaren geleden
bovenliggende
commit
446b4207cc
3 gewijzigde bestanden met toevoegingen van 21 en 16 verwijderingen
  1. 3 1
      src/temp/mkdtemp.c
  2. 3 2
      src/temp/mkstemp.c
  3. 15 13
      src/temp/mktemp.c

+ 3 - 1
src/temp/mkdtemp.c

@@ -12,7 +12,8 @@ char *__mktemp(char *);
 
 char *mkdtemp(char *template)
 {
-	for (;;) {
+	int retries = 100;
+	while (retries--) {
 		if (!__mktemp(template)) return 0;
 		if (!mkdir(template, 0700)) return template;
 		if (errno != EEXIST) return 0;
@@ -20,4 +21,5 @@ char *mkdtemp(char *template)
 		 * that we have a valid template string */
 		strcpy(template+strlen(template)-6, "XXXXXX");
 	}
+	return 0;
 }

+ 3 - 2
src/temp/mkstemp.c

@@ -11,8 +11,8 @@ char *__mktemp(char *);
 
 int mkstemp(char *template)
 {
-	int fd;
-	for (;;) {
+	int fd, retries = 100;
+	while (retries--) {
 		if (!__mktemp(template)) return 0;
 		if ((fd = open(template, O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
 			return fd;
@@ -21,6 +21,7 @@ int mkstemp(char *template)
 		 * that we have a valid template string */
 		strcpy(template+strlen(template)-6, "XXXXXX");
 	}
+	return -1;
 }
 
 LFS64(mkstemp);

+ 15 - 13
src/temp/mktemp.c

@@ -4,28 +4,30 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
+#include <time.h>
+#include <stdint.h>
 #include "libc.h"
 
 char *__mktemp(char *template)
 {
-	static int lock;
-	static int index;
-	int l = strlen(template);
+	struct timespec ts;
+	size_t l = strlen(template);
+	int retries = 10000;
+	unsigned long r;
 
 	if (l < 6 || strcmp(template+l-6, "XXXXXX")) {
 		errno = EINVAL;
-		return NULL;
+		return 0;
 	}
-	LOCK(&lock);
-	for (; index < 1000000; index++) {
-		snprintf(template+l-6, 6, "%06d", index);
-		if (access(template, F_OK) != 0) {
-			UNLOCK(&lock);
-			return template;
-		}
+	clock_gettime(CLOCK_REALTIME, &ts);
+	r = ts.tv_nsec + (uintptr_t)&ts / 16 + (uintptr_t)template;
+	while (retries--) {
+		snprintf(template+l-6, 7, "%06lX", r & 0xffffff);
+		if (access(template, F_OK) < 0) return template;
+		r = r * 1103515245 + 12345;
 	}
-	UNLOCK(&lock);
-	return NULL;	
+	errno = EEXIST;
+	return 0;
 }
 
 weak_alias(__mktemp, mktemp);