Skip to content

Commit 5d31ee3

Browse files
sj-inikic
authored andcommitted
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 phpGH-6526.
1 parent 68f5289 commit 5d31ee3

File tree

6 files changed

+37
-10
lines changed

6 files changed

+37
-10
lines changed

ext/standard/file.c

+1-5
Original file line numberDiff line numberDiff line change
@@ -831,18 +831,14 @@ PHP_FUNCTION(tempnam)
831831
Z_PARAM_PATH(prefix, prefix_len)
832832
ZEND_PARSE_PARAMETERS_END();
833833

834-
if (php_check_open_basedir(dir)) {
835-
RETURN_FALSE;
836-
}
837-
838834
p = php_basename(prefix, prefix_len, NULL, 0);
839835
if (ZSTR_LEN(p) > 64) {
840836
ZSTR_VAL(p)[63] = '\0';
841837
}
842838

843839
RETVAL_FALSE;
844840

845-
if ((fd = php_open_temporary_fd_ex(dir, ZSTR_VAL(p), &opened_path, 1)) >= 0) {
841+
if ((fd = php_open_temporary_fd_ex(dir, ZSTR_VAL(p), &opened_path, PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ALWAYS)) >= 0) {
846842
close(fd);
847843
RETVAL_STR(opened_path);
848844
}

ext/standard/tests/file/bug42560.phpt

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Bug #42560 Empty directory argument to tempnam yields open_basedir problems
3+
--FILE--
4+
<?php
5+
$tmpdir = sys_get_temp_dir();
6+
ini_set('open_basedir', $tmpdir);
7+
$tempnam = tempnam('', 'test');
8+
var_dump($tempnam !== false);
9+
var_dump(file_exists($tempnam));
10+
11+
if (file_exists($tempnam)) {
12+
unlink($tempnam);
13+
}
14+
?>
15+
--EXPECT--
16+
bool(true)
17+
bool(true)

main/php_open_temporary_file.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -301,13 +301,19 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_strin
301301
def_tmp:
302302
temp_dir = php_get_temporary_directory();
303303

304-
if (temp_dir && *temp_dir != '\0' && (!(flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK) || !php_check_open_basedir(temp_dir))) {
304+
if (temp_dir &&
305+
*temp_dir != '\0' &&
306+
(!(flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK) || !php_check_open_basedir(temp_dir))) {
305307
return php_do_open_temporary_file(temp_dir, pfx, opened_path_p);
306308
} else {
307309
return -1;
308310
}
309311
}
310312

313+
if ((flags & PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_EXPLICIT_DIR) && php_check_open_basedir(dir)) {
314+
return -1;
315+
}
316+
311317
/* Try the directory given as parameter. */
312318
fd = php_do_open_temporary_file(dir, pfx, opened_path_p);
313319
if (fd == -1) {
@@ -322,7 +328,7 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_strin
322328

323329
PHPAPI int php_open_temporary_fd(const char *dir, const char *pfx, zend_string **opened_path_p)
324330
{
325-
return php_open_temporary_fd_ex(dir, pfx, opened_path_p, 0);
331+
return php_open_temporary_fd_ex(dir, pfx, opened_path_p, PHP_TMP_FILE_DEFAULT);
326332
}
327333

328334
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_p)

main/php_open_temporary_file.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@
1919
#ifndef PHP_OPEN_TEMPORARY_FILE_H
2020
#define PHP_OPEN_TEMPORARY_FILE_H
2121

22-
#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK (1<<0)
22+
#define PHP_TMP_FILE_DEFAULT 0
23+
#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK (1<<0)
2324
#define PHP_TMP_FILE_SILENT (1<<1)
25+
#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_EXPLICIT_DIR (1<<2)
26+
#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ALWAYS \
27+
(PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK | PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_EXPLICIT_DIR)
28+
29+
/* for compatibility purpose */
30+
#define PHP_TMP_FILE_OPEN_BASEDIR_CHECK PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK
31+
2432

2533
BEGIN_EXTERN_C()
2634
PHPAPI FILE *php_open_temporary_file(const char *dir, const char *pfx, zend_string **opened_path_p);

main/rfc1867.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
10091009
/* in non-debug mode we have no problem with 0-length files */
10101010
{
10111011
#endif
1012-
fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1);
1012+
fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, PHP_TMP_FILE_OPEN_BASEDIR_CHECK_ON_FALLBACK);
10131013
upload_cnt--;
10141014
if (fd == -1) {
10151015
sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file");

tests/security/open_basedir_tempnam.phpt

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ bool(false)
6363
Warning: tempnam(): open_basedir restriction in effect. File(./../.) is not within the allowed path(s): (.) in %s on line %d
6464
bool(false)
6565

66-
Warning: tempnam(): open_basedir restriction in effect. File() is not within the allowed path(s): (.) in %s on line %d
66+
Warning: tempnam(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (.) in %s on line %d
6767
bool(false)
6868
string(%d) "%s"
6969
bool(true)

0 commit comments

Comments
 (0)