Patch php-move-upladed-files-race-condition.patch for Filesystem function related Bug #55576
Patch version 2011-09-03 11:35 UTC
Return to Bug #55576 |
Download this patch
Patch Revisions:
Developer: cjk@wwwtech.de
diff -ru php-5.3.8-orig//ext/standard/basic_functions.c php-5.3.8/ext/standard/basic_functions.c
--- php-5.3.8-orig//ext/standard/basic_functions.c 2011-09-03 12:46:32.559176875 +0200
+++ php-5.3.8/ext/standard/basic_functions.c 2011-09-03 13:33:41.478176780 +0200
@@ -117,6 +117,8 @@
#include "php_fopen_wrappers.h"
#include "streamsfuncs.h"
+#include <fcntl.h>
+
static zend_class_entry *incomplete_class_entry = NULL;
typedef struct _php_shutdown_function_entry {
@@ -834,9 +836,10 @@
ZEND_ARG_INFO(0, path)
ZEND_END_ARG_INFO()
-ZEND_BEGIN_ARG_INFO(arginfo_move_uploaded_file, 0)
+ZEND_BEGIN_ARG_INFO_EX(arginfo_move_uploaded_file, 0, 0, 2)
ZEND_ARG_INFO(0, path)
ZEND_ARG_INFO(0, new_path)
+ ZEND_ARG_INFO(0, dont_overwrite)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_parse_ini_file, 0, 0, 1)
@@ -5814,8 +5817,8 @@
PHP_FUNCTION(move_uploaded_file)
{
char *path, *new_path;
- int path_len, new_path_len;
- zend_bool successful = 0;
+ int path_len, new_path_len, fd;
+ zend_bool successful = 0, dont_overwrite = 0;
#ifndef PHP_WIN32
int oldmask; int ret;
@@ -5825,7 +5828,7 @@
RETURN_FALSE;
}
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &new_path, &new_path_len) == FAILURE) {
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &path, &path_len, &new_path, &new_path_len, &dont_overwrite) == FAILURE) {
return;
}
@@ -5849,7 +5852,20 @@
RETURN_FALSE;
}
- VCWD_UNLINK(new_path);
+ if (!dont_overwrite) {
+ oldmask = umask(077);
+ umask(oldmask);
+
+ if ((fd = open (new_path, O_RDWR|O_CREAT|O_EXCL, 0666 & ~oldmask)) == -1) {
+ /* file exists, return false */
+ RETURN_FALSE;
+ }
+
+ /* file does not exist, we created it successfully exclusive, continue */
+ close (fd);
+ }
+
+ /* VCWD_UNLINK(new_path); no longer unlink() because of the race condition */
if (VCWD_RENAME(path, new_path) == 0) {
successful = 1;
#ifndef PHP_WIN32
@@ -5870,6 +5886,10 @@
if (successful) {
zend_hash_del(SG(rfc1867_uploaded_files), path, path_len + 1);
} else {
+ if (dont_overwrite) {
+ VCWD_UNLINK(new_path); /* since we created a file with O_EXCL, we have to remove it again in error case */
+ }
+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to move '%s' to '%s'", path, new_path);
}
|