summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArnaud Le Blanc <lbarnaud@php.net>2008-08-11 15:30:44 +0000
committerArnaud Le Blanc <lbarnaud@php.net>2008-08-11 15:30:44 +0000
commitde24949cce44c870139d35833c51b50a73e71231 (patch)
tree10d47929cbc91161814eb08d922743056d2d4398
parentba7cfd2fa77a1bddd6d4363d95fe2fa70b4c60d3 (diff)
downloadphp-git-de24949cce44c870139d35833c51b50a73e71231.tar.gz
MFH: Check the relevant path for open_basedir in symlink()
-rw-r--r--ext/standard/link.c13
-rw-r--r--ext/standard/tests/file/symlink_to_symlink.phpt6
-rw-r--r--tests/security/open_basedir_symlink.phpt9
3 files changed, 27 insertions, 1 deletions
diff --git a/ext/standard/link.c b/ext/standard/link.c
index 0c50586422..8ea64eb5c8 100644
--- a/ext/standard/link.c
+++ b/ext/standard/link.c
@@ -49,6 +49,7 @@
#include "safe_mode.h"
#include "php_link.h"
+#include "php_string.h"
/* {{{ proto string readlink(string filename)
Return the target of a symbolic link */
@@ -116,12 +117,22 @@ PHP_FUNCTION(symlink)
int ret;
char source_p[MAXPATHLEN];
char dest_p[MAXPATHLEN];
+ char dirname[MAXPATHLEN];
+ size_t len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
return;
}
+
+ if (!expand_filepath(frompath, source_p TSRMLS_CC)) {
+ php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
+ RETURN_FALSE;
+ }
- if (!expand_filepath(frompath, source_p TSRMLS_CC) || !expand_filepath(topath, dest_p TSRMLS_CC)) {
+ memcpy(dirname, source_p, sizeof(source_p));
+ len = php_dirname(dirname, strlen(dirname));
+
+ if (!expand_filepath_ex(topath, dest_p, dirname, len TSRMLS_CC)) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
RETURN_FALSE;
}
diff --git a/ext/standard/tests/file/symlink_to_symlink.phpt b/ext/standard/tests/file/symlink_to_symlink.phpt
index cf12a1d0b7..b7554f9bd0 100644
--- a/ext/standard/tests/file/symlink_to_symlink.phpt
+++ b/ext/standard/tests/file/symlink_to_symlink.phpt
@@ -1,5 +1,11 @@
--TEST--
symlink() using a relative path, and symlink() to a symlink
+--SKIPIF--
+<?php
+if (substr(PHP_OS, 0, 3) == 'WIN') {
+ die('skip no symlinks on Windows');
+}
+?>
--FILE--
<?php
$prefix = __FILE__;
diff --git a/tests/security/open_basedir_symlink.phpt b/tests/security/open_basedir_symlink.phpt
index 3b3f1d571f..3aaa07b820 100644
--- a/tests/security/open_basedir_symlink.phpt
+++ b/tests/security/open_basedir_symlink.phpt
@@ -31,6 +31,12 @@ $target = ($directory."/test/ok/ok.txt");
var_dump(symlink($target, $symlink));
var_dump(unlink($symlink));
+
+var_dump(mkdir("ok2"));
+$symlink = ($directory."/test/ok/ok2/ok.txt");
+var_dump(symlink("../ok.txt", $symlink)); // $target == (dirname($symlink)."/".$target) == ($directory."/test/ok/ok.txt");
+var_dump(unlink($symlink));
+
test_open_basedir_after("symlink");
?>
--CLEAN--
@@ -74,5 +80,8 @@ Warning: symlink(): open_basedir restriction in effect. File(%s/test/bad) is not
bool(false)
bool(true)
bool(true)
+bool(true)
+bool(true)
+bool(true)
*** Finished testing open_basedir configuration [symlink] ***