Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 12 Nov 2007 21:21:56 +0100
From:      Erik Stian Tefre <erik@tefre.com>
To:        freebsd-ports@freebsd.org
Subject:   apache 2.x + php 5.x http post temporary file name non-randomness
Message-ID:  <4738B5E4.30901@tefre.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------010805070703040804000808
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

There seems to be a bug (or feature?) somewhere that limits the number 
of unique temporary file names used when storing temporary files that 
are uploaded by posting a form. Looking through my webserver logs of 
110000 file uploads, I find no more than 495 unique temporary file names 
which are being reused again and again.
(File name example: /var/tmp/phpzzJuIt)

I think PHP is supposed to use mkstemp(). From the mkstemp(3) manual:
"The number of unique file names mktemp() can return depends on the 
number of `Xs' provided; six `Xs' will result in mktemp() selecting one 
of 56800235584 (62 ** 6) possible temporary file names."

PHP uses 6 Xs. This makes the low number of observed unique file names 
(495) a bit disappointing.

I have the same problem on the following 2 combinations:
amd64 + freebsd 6.0 + php 5.1 + apache 2.0 prefork MPM (+ several php 
extensions)
amd64 + freebsd 6.2 + php 5.2 + apache 2.2 prefork MPM (+ several php 
extensions)

Does anyone know what causes this and/or how to fix it?

The attached patch for php 5.2.4 Works For Me(tm), but I'd rather have 
the problem fixed at it's source than working around it...

--
Erik


--------------010805070703040804000808
Content-Type: text/plain;
 name="patch-main-php_open_temporary_file.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch-main-php_open_temporary_file.c"

--- main/php_open_temporary_file.c.orig	Mon Nov 12 18:46:03 2007
+++ main/php_open_temporary_file.c	Mon Nov 12 18:49:30 2007
@@ -101,6 +101,7 @@
 	char cwd[MAXPATHLEN];
 	cwd_state new_state;
 	int fd = -1;
+	struct timeval tval;
 #ifndef HAVE_MKSTEMP
 	int open_flags = O_CREAT | O_TRUNC | O_RDWR
 #ifdef PHP_WIN32
@@ -131,7 +132,8 @@
 		trailing_slash = "/";
 	}
 
-	if (spprintf(&opened_path, 0, "%s%s%sXXXXXX", new_state.cwd, trailing_slash, pfx) >= MAXPATHLEN) {
+	gettimeofday(&tval, NULL);
+	if (spprintf(&opened_path, 0, "%s%s%s_%d_%d_XXXXXX", new_state.cwd, trailing_slash, pfx, tval.tv_sec, tval.tv_usec) >= MAXPATHLEN) {
 		efree(opened_path);
 		free(new_state.cwd);
 		return -1;

--------------010805070703040804000808--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4738B5E4.30901>