summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsj-i <shinji.igarashi@gmail.com>2020-12-20 15:57:54 +0900
committerNikita Popov <nikita.ppv@gmail.com>2021-01-19 11:41:58 +0100
commit5d31ee302db073d5e99cf307315d2d631eaa34a5 (patch)
tree93324ec78f3b18b1fb9581b47854c1e6406507de
parent68f5289e9e84b12b1a9ad671657702ce9a65a1e1 (diff)
downloadphp-git-5d31ee302db073d5e99cf307315d2d631eaa34a5.tar.gz
Fixed bug #42560
Check open_basedir after the fallback to the system's temporary directory in tempnam(). In order to preserve the current behavior of upload_tmp_dir (do not check explicitly specified dir, but check fallback), new flags are added to check open_basedir for explicit dir and for fallback. Closes GH-6526.
-rw-r--r--ext/standard/file.c6
-rw-r--r--ext/standard/tests/file/bug42560.phpt17
-rw-r--r--main/php_open_temporary_file.c10
-rw-r--r--main/php_open_temporary_file.h10
-rw-r--r--main/rfc1867.c2
-rw-r--r--tests/security/open_basedir_tempnam.phpt2
6 files changed, 37 insertions, 10 deletions
diff --git a/ext/standard/file.c b/ext/standard/file.c
index a68db967f1..12c21c93cd 100644
--- a/ext/standard/file.c
+++ b/ext/standard/file.c
@@ -831,10 +831,6 @@ PHP_FUNCTION(tempnam)
Z_PARAM_PATH(prefix, prefix_len)
ZEND_PARSE_PARAMETERS_END();
- if (php_check_open_basedir(dir)) {
- RETURN_FALSE;
- }
-
p = php_basename(prefix, prefix_len, NULL, 0);
if (ZSTR_LEN(p) > 64) {
ZSTR_VAL(p)[63] = '\0';
@@ -842,7 +838,7 @@ PHP_FUNCTION(tempnam)
RETVAL_FALSE;
- if ((fd = php_open_temporary_fd_ex(dir, ZSTR_VAL(p), &opened_path, 1)) >= 0) {
+ if ((fd = php_open_temporary_fd_ex(dir, ZSTR_VAL(p), &opened_path, PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ALWAYS)) >= 0) {
close(fd);
RETVAL_STR(opened_path);
}
diff --git a/ext/standard/tests/file/bug42560.phpt b/ext/standard/tests/file/bug42560.phpt
new file mode 100644
index 0000000000..286ced6ff0
--- /dev/null
+++ b/ext/standard/tests/file/bug42560.phpt
@@ -0,0 +1,17 @@
+--TEST--
+Bug #42560 Empty directory argument to tempnam yields open_basedir problems
+--FILE--
+<?php
+$tmpdir = sys_get_temp_dir();
+ini_set('open_basedir', $tmpdir);
+$tempnam = tempnam('', 'test');
+var_dump($tempnam !== false);
+var_dump(file_exists($tempnam));
+
+if (file_exists($tempnam)) {
+ unlink($tempnam);
+}
+?>
+--EXPECT--
+bool(true)
+bool(true)
diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c
index 6fca7e4cab..b15dec03e4 100644
--- a/main/php_open_temporary_file.c
+++ b/main/php_open_temporary_file.c
@@ -301,13 +301,19 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_strin
def_tmp:
temp_dir = php_get_temporary_directory();
- if (temp_dir && *temp_dir != '\0' && (!(flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK) || !php_check_open_basedir(temp_dir))) {
+ if (temp_dir &&
+ *temp_dir != '\0' &&
+ (!(flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK) || !php_check_open_basedir(temp_dir))) {
return php_do_open_temporary_file(temp_dir, pfx, opened_path_p);
} else {
return -1;
}
}
+ if ((flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_EXPLICIT_DIR) && php_check_open_basedir(dir)) {
+ return -1;
+ }
+
/* Try the directory given as parameter. */
fd = php_do_open_temporary_file(dir, pfx, opened_path_p);
if (fd == -1) {
@@ -322,7 +328,7 @@ def_tmp:
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, zend_string **opened_path_p)
{
- return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0);
+ return php_open_temporary_fd_ex(dir, pfx, opened_path_p, PHP_TMP_FILE_DEFAULT);
}
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_p)
diff --git a/main/php_open_temporary_file.h b/main/php_open_temporary_file.h
index 0195056e31..2c7d98fe86 100644
--- a/main/php_open_temporary_file.h
+++ b/main/php_open_temporary_file.h
@@ -19,8 +19,16 @@
#ifndef PHP_OPEN_TEMPORARY_FILE_H
#define PHP_OPEN_TEMPORARY_FILE_H
-#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK (1<<0)
+#define PHP_TMP_FILE_DEFAULT 0
+#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK (1<<0)
#define PHP_TMP_FILE_SILENT (1<<1)
+#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_EXPLICIT_DIR (1<<2)
+#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ALWAYS \
+ (PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK | PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_EXPLICIT_DIR)
+
+/* for compatibility purpose */
+#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK
+
BEGIN_EXTERN_C()
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_p);
diff --git a/main/rfc1867.c b/main/rfc1867.c
index 8bdc409296..edef19c16d 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -1009,7 +1009,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
/* in non-debug mode we have no problem with 0-length files */
{
#endif
- fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1);
+ fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK);
upload_cnt--;
if (fd == -1) {
sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");
diff --git a/tests/security/open_basedir_tempnam.phpt b/tests/security/open_basedir_tempnam.phpt
index b444164efd..7990f97ab2 100644
--- a/tests/security/open_basedir_tempnam.phpt
+++ b/tests/security/open_basedir_tempnam.phpt
@@ -63,7 +63,7 @@ bool(false)
Warning: tempnam(): open_basedir restriction in effect. File(./../.) is not within the allowed path(s): (.) in %s on line %d
bool(false)
-Warning: tempnam(): open_basedir restriction in effect. File() is not within the allowed path(s): (.) in %s on line %d
+Warning: tempnam(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d
bool(false)
string(%d) "%s"
bool(true)