Skip to content

Commit

Permalink
Fixed bug #42560
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sj-i authored and nikic committed Jan 19, 2021
1 parent 68f5289 commit 5d31ee3
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 10 deletions.
6 changes: 1 addition & 5 deletions ext/standard/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -831,18 +831,14 @@ 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';
}

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);
}
Expand Down
17 changes: 17 additions & 0 deletions ext/standard/tests/file/bug42560.phpt
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 8 additions & 2 deletions main/php_open_temporary_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -322,7 +328,7 @@ PHPAPI int php_open_temporary_fd_ex(const char *dir, const char *pfx, zend_strin

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)
Expand Down
10 changes: 9 additions & 1 deletion main/php_open_temporary_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion main/rfc1867.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion tests/security/open_basedir_tempnam.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 5d31ee3

Please sign in to comment.