Преглед изворни кода

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 година
родитељ
комит
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);