summaryrefslogtreecommitdiff
path: root/runtime/runtime.cc
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2016-08-30 17:15:26 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-08-30 17:15:26 +0000
commitd7eabc2cc1a88c1f7f927da61246ae65aab0626c (patch)
treedc61a7fd80e1289777f6a991102b0fe4a2ef032d /runtime/runtime.cc
parent99fd9f39f2cd74864bdc750a3444ddd776da534c (diff)
parentd106d9f871c957286ccdeb79c1c2a5ed41f859a6 (diff)
Merge "Save environment snapshot and use at fork/exec"
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r--runtime/runtime.cc41
1 files changed, 41 insertions, 0 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index ddcfb6d5aa..f3fcd34de9 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -26,6 +26,9 @@
#include <signal.h>
#include <sys/syscall.h>
#include "base/memory_tool.h"
+#if defined(__APPLE__)
+#include <crt_externs.h> // for _NSGetEnviron
+#endif
#include <cstdio>
#include <cstdlib>
@@ -156,6 +159,22 @@ struct TraceConfig {
size_t trace_file_size;
};
+namespace {
+#ifdef __APPLE__
+inline char** GetEnviron() {
+ // When Google Test is built as a framework on MacOS X, the environ variable
+ // is unavailable. Apple's documentation (man environ) recommends using
+ // _NSGetEnviron() instead.
+ return *_NSGetEnviron();
+}
+#else
+// Some POSIX platforms expect you to declare environ. extern "C" makes
+// it reside in the global namespace.
+extern "C" char** environ;
+inline char** GetEnviron() { return environ; }
+#endif
+} // namespace
+
Runtime::Runtime()
: resolution_method_(nullptr),
imt_conflict_method_(nullptr),
@@ -904,6 +923,10 @@ void Runtime::SetSentinel(mirror::Object* sentinel) {
}
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
+ // (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
+ // Take a snapshot of the environment at the time the runtime was created, for use by Exec, etc.
+ env_snapshot_.TakeSnapshot();
+
RuntimeArgumentMap runtime_options(std::move(runtime_options_in));
ScopedTrace trace(__FUNCTION__);
CHECK_EQ(sysconf(_SC_PAGE_SIZE), kPageSize);
@@ -2021,4 +2044,22 @@ bool Runtime::UseJitCompilation() const {
return (jit_ != nullptr) && jit_->UseJitCompilation();
}
+void Runtime::EnvSnapshot::TakeSnapshot() {
+ char** env = GetEnviron();
+ for (size_t i = 0; env[i] != nullptr; ++i) {
+ name_value_pairs_.emplace_back(new std::string(env[i]));
+ }
+ // The strings in name_value_pairs_ retain ownership of the c_str, but we assign pointers
+ // for quick use by GetSnapshot. This avoids allocation and copying cost at Exec.
+ c_env_vector_.reset(new char*[name_value_pairs_.size() + 1]);
+ for (size_t i = 0; env[i] != nullptr; ++i) {
+ c_env_vector_[i] = const_cast<char*>(name_value_pairs_[i]->c_str());
+ }
+ c_env_vector_[name_value_pairs_.size()] = nullptr;
+}
+
+char** Runtime::EnvSnapshot::GetSnapshot() const {
+ return c_env_vector_.get();
+}
+
} // namespace art