Просмотр исходного кода

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 лет назад
Родитель
Сommit
446b4207cc
3 измененных файлов с 21 добавлено и 16 удалено
  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);