Created
February 20, 2014 23:46
-
-
Save ptarjan/9125827 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/hphp/runtime/base/execution-context.cpp b/hphp/runtime/base/execution-context.cpp | |
index f61160c..ecf0a41 100644 | |
--- a/hphp/runtime/base/execution-context.cpp | |
+++ b/hphp/runtime/base/execution-context.cpp | |
@@ -54,6 +54,8 @@ int64_t VMExecutionContext::s_threadIdxCounter = 0; | |
Mutex VMExecutionContext::s_threadIdxLock; | |
hphp_hash_map<pid_t, int64_t> VMExecutionContext::s_threadIdxMap; | |
+const StaticString s_dot("."); | |
+ | |
BaseExecutionContext::BaseExecutionContext() : | |
m_fp(nullptr), m_pc(nullptr), | |
m_transport(nullptr), | |
@@ -112,27 +114,33 @@ BaseExecutionContext::BaseExecutionContext() : | |
}); | |
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_SYSTEM, | |
"doc_root", &RuntimeOption::SourceRoot); | |
- IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ALL, | |
- "open_basedir", | |
- [](const std::string& value, void* p) { | |
- RuntimeOption::AllowedDirectories.clear(); | |
- auto boom = f_explode(";", value).toCArrRef(); | |
- for (ArrayIter iter(boom); iter; ++iter) { | |
- RuntimeOption::AllowedDirectories.push_back( | |
- iter.second().toCStrRef().toCppString() | |
- ); | |
- } | |
- return true; | |
- }, | |
- [](void*) { | |
- std::string out = ""; | |
- for (auto& dir : RuntimeOption::AllowedDirectories) { | |
- if (!dir.empty()) { | |
- out += dir + ";"; | |
- } | |
- } | |
- return out; | |
- }); | |
+ IniSetting::Bind( | |
+ IniSetting::CORE, IniSetting::PHP_INI_ALL, | |
+ "open_basedir", | |
+ [this](const std::string& value, void* p) { | |
+ auto boom = f_explode(";", value).toCArrRef(); | |
+ Variant v; | |
+ for (MutableArrayIter iter(boom.get(), nullptr, v); | |
+ iter.advance(); ) { | |
+ if (File::TranslatePathKeepRelative(v.toString()).empty()) { | |
+ return false; | |
+ } | |
+ if (v.toString().equal(s_dot)) { | |
+ v = getCwd(); | |
+ } | |
+ } | |
+ setAllowedDirectoires(boom); | |
+ setSafeFileAccess(!boom.empty()); | |
+ return true; | |
+ }, | |
+ [this](void*) -> std::string { | |
+ if (!hasSafeFileAccess()) { | |
+ return ""; | |
+ } | |
+ return f_implode(";", getAllowedDirectories()) | |
+ .toCppString(); | |
+ } | |
+ ); | |
// FastCGI | |
IniSetting::Bind(IniSetting::CORE, IniSetting::PHP_INI_ONLY, | |
diff --git a/hphp/runtime/base/execution-context.h b/hphp/runtime/base/execution-context.h | |
index 4a59b40..141d41e 100644 | |
--- a/hphp/runtime/base/execution-context.h | |
+++ b/hphp/runtime/base/execution-context.h | |
@@ -340,6 +340,12 @@ public: | |
void setIncludePath(const String& path); | |
String getIncludePath() const; | |
Array getIncludePathArray() const { return m_include_paths; } | |
+ | |
+ const Array getAllowedDirectories() const { return m_allowedDirectories; } | |
+ void setAllowedDirectoires(const Array& dirs) { m_allowedDirectories = dirs; } | |
+ const bool hasSafeFileAccess() const { return m_safeFileAccess; } | |
+ void setSafeFileAccess(const bool b) { m_safeFileAccess = b; } | |
+ | |
const VirtualHost *getVirtualHost() const { return m_vhost; } | |
void setVirtualHost(const VirtualHost *vhost) { m_vhost = vhost; } | |
@@ -407,6 +413,9 @@ private: | |
// include_path configuration option | |
Array m_include_paths; | |
+ | |
+ Array m_allowedDirectories; | |
+ bool m_safeFileAccess; | |
// cache the sandbox id for the request | |
String m_sandboxId; | |
diff --git a/hphp/runtime/base/file.cpp b/hphp/runtime/base/file.cpp | |
index 9bcb600d..1c291b3 100644 | |
--- a/hphp/runtime/base/file.cpp | |
+++ b/hphp/runtime/base/file.cpp | |
@@ -53,7 +53,7 @@ String File::TranslatePathKeepRelative(const String& filename) { | |
strlen(filename.data()) // canonicalize asserts that we don't have nulls | |
), | |
AttachString); | |
- if (RuntimeOption::SafeFileAccess) { | |
+ if (g_context->hasSafeFileAccess()) { | |
auto const& allowedDirectories = VirtualHost::GetAllowedDirectories(); | |
auto it = std::upper_bound(allowedDirectories.begin(), | |
allowedDirectories.end(), canonicalized, | |
diff --git a/hphp/runtime/base/runtime-option.cpp b/hphp/runtime/base/runtime-option.cpp | |
index 975bb92..9c8dd0e 100644 | |
--- a/hphp/runtime/base/runtime-option.cpp | |
+++ b/hphp/runtime/base/runtime-option.cpp | |
@@ -890,7 +890,6 @@ void RuntimeOption::Load(Hdf &config, | |
UploadMaxFileSize = | |
(upload["UploadMaxFileSize"].getInt32(100)) * (1LL << 20); | |
UploadTmpDir = upload["UploadTmpDir"].getString("/tmp"); | |
- RuntimeOption::AllowedDirectories.push_back(UploadTmpDir); | |
EnableFileUploads = upload["EnableFileUploads"].getBool(true); | |
EnableUploadProgress = upload["EnableUploadProgress"].getBool(); | |
Rfc1867Freq = upload["Rfc1867Freq"].getInt32(256 * 1024); | |
diff --git a/hphp/runtime/ext/ext_file.cpp b/hphp/runtime/ext/ext_file.cpp | |
index f9586c2..1639b5f 100644 | |
--- a/hphp/runtime/ext/ext_file.cpp | |
+++ b/hphp/runtime/ext/ext_file.cpp | |
@@ -1222,7 +1222,7 @@ Variant f_glob(const String& pattern, int flags /* = 0 */) { | |
} | |
int nret = glob(work_pattern.data(), flags & GLOB_FLAGMASK, NULL, &globbuf); | |
if (nret == GLOB_NOMATCH || !globbuf.gl_pathc || !globbuf.gl_pathv) { | |
- if (RuntimeOption::SafeFileAccess) { | |
+ if (g_context->hasSafeFileAccess()) { | |
if (!f_is_dir(work_pattern)) { | |
return false; | |
} | |
diff --git a/hphp/runtime/server/virtual-host.cpp b/hphp/runtime/server/virtual-host.cpp | |
index 7f6d75f..0229ad1 100644 | |
--- a/hphp/runtime/server/virtual-host.cpp | |
+++ b/hphp/runtime/server/virtual-host.cpp | |
@@ -60,13 +60,18 @@ int64_t VirtualHost::GetUploadMaxFileSize() { | |
return RuntimeOption::UploadMaxFileSize; | |
} | |
-const std::vector<std::string> &VirtualHost::GetAllowedDirectories() { | |
+const std::vector<std::string> VirtualHost::GetAllowedDirectories() { | |
const VirtualHost *vh = GetCurrent(); | |
assert(vh); | |
if (!vh->m_runtimeOption.allowedDirectories.empty()) { | |
return vh->m_runtimeOption.allowedDirectories; | |
} | |
- return RuntimeOption::AllowedDirectories; | |
+ std::vector<std::string> ret; | |
+ auto& dirs = g_context->getAllowedDirectories(); | |
+ for (ArrayIter iter(dirs); iter; ++iter) { | |
+ ret.push_back(iter.second().toString().toCppString()); | |
+ } | |
+ return ret; | |
} | |
void VirtualHost::SortAllowedDirectories(std::vector<std::string>& dirs) { | |
diff --git a/hphp/runtime/server/virtual-host.h b/hphp/runtime/server/virtual-host.h | |
index 9a954e3..a24a9ea 100644 | |
--- a/hphp/runtime/server/virtual-host.h | |
+++ b/hphp/runtime/server/virtual-host.h | |
@@ -32,7 +32,7 @@ public: | |
static const VirtualHost *GetCurrent(); | |
static int64_t GetMaxPostSize(); | |
static int64_t GetUploadMaxFileSize(); | |
- static const std::vector<std::string> &GetAllowedDirectories(); | |
+ static const std::vector<std::string> GetAllowedDirectories(); | |
static void SortAllowedDirectories(std::vector<std::string>& dirs); | |
public: | |
VirtualHost(); | |
diff --git a/hphp/test/slow/ext_options/ini_set.php.expectf b/hphp/test/slow/ext_options/ini_set.php.expectf | |
index aa5d073..bcf5661 100644 | |
--- a/hphp/test/slow/ext_options/ini_set.php.expectf | |
+++ b/hphp/test/slow/ext_options/ini_set.php.expectf | |
@@ -1,4 +1,4 @@ | |
-string(5) "/tmp;" | |
+string(0) "" | |
string(14) "/foo/a;/foo/b;" | |
string(%d) "%s" | |
string(%d) "%s" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment