Skip to content

Commit de24949

Browse files
committed
MFH: Check the relevant path for open_basedir in symlink()
1 parent ba7cfd2 commit de24949

3 files changed

Lines changed: 27 additions & 1 deletion

File tree

ext/standard/link.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949

5050
#include "safe_mode.h"
5151
#include "php_link.h"
52+
#include "php_string.h"
5253

5354
/* {{{ proto string readlink(string filename)
5455
Return the target of a symbolic link */
@@ -116,12 +117,22 @@ PHP_FUNCTION(symlink)
116117
int ret;
117118
char source_p[MAXPATHLEN];
118119
char dest_p[MAXPATHLEN];
120+
char dirname[MAXPATHLEN];
121+
size_t len;
119122

120123
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
121124
return;
122125
}
126+
127+
if (!expand_filepath(frompath, source_p TSRMLS_CC)) {
128+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
129+
RETURN_FALSE;
130+
}
123131

124-
if (!expand_filepath(frompath, source_p TSRMLS_CC) || !expand_filepath(topath, dest_p TSRMLS_CC)) {
132+
memcpy(dirname, source_p, sizeof(source_p));
133+
len = php_dirname(dirname, strlen(dirname));
134+
135+
if (!expand_filepath_ex(topath, dest_p, dirname, len TSRMLS_CC)) {
125136
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
126137
RETURN_FALSE;
127138
}

ext/standard/tests/file/symlink_to_symlink.phpt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
--TEST--
22
symlink() using a relative path, and symlink() to a symlink
3+
--SKIPIF--
4+
<?php
5+
if (substr(PHP_OS, 0, 3) == 'WIN') {
6+
die('skip no symlinks on Windows');
7+
}
8+
?>
39
--FILE--
410
<?php
511
$prefix = __FILE__;

tests/security/open_basedir_symlink.phpt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ $target = ($directory."/test/ok/ok.txt");
3131

3232
var_dump(symlink($target, $symlink));
3333
var_dump(unlink($symlink));
34+
35+
var_dump(mkdir("ok2"));
36+
$symlink = ($directory."/test/ok/ok2/ok.txt");
37+
var_dump(symlink("../ok.txt", $symlink)); // $target == (dirname($symlink)."/".$target) == ($directory."/test/ok/ok.txt");
38+
var_dump(unlink($symlink));
39+
3440
test_open_basedir_after("symlink");
3541
?>
3642
--CLEAN--
@@ -74,5 +80,8 @@ Warning: symlink(): open_basedir restriction in effect. File(%s/test/bad) is not
7480
bool(false)
7581
bool(true)
7682
bool(true)
83+
bool(true)
84+
bool(true)
85+
bool(true)
7786
*** Finished testing open_basedir configuration [symlink] ***
7887

0 commit comments

Comments
 (0)