summaryrefslogtreecommitdiffstats
path: root/runtime/interpreter
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-04-14 21:07:05 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2015-04-14 21:07:05 +0000
commit503559045a794c2b376fc0ef74d9e7afb0acca64 (patch)
tree440b8cdbbba982351987b1cbc417a56f28933db1 /runtime/interpreter
parent0cbb4a8cab4c7824ab702404b832ee1ea5950aad (diff)
parentf778eb275986811a3e1aba82d364b7e6a94678f3 (diff)
downloadart-503559045a794c2b376fc0ef74d9e7afb0acca64.tar.gz
art-503559045a794c2b376fc0ef74d9e7afb0acca64.tar.bz2
art-503559045a794c2b376fc0ef74d9e7afb0acca64.zip
Merge "ART: Add Security cutout to unstarted runtime"
Diffstat (limited to 'runtime/interpreter')
-rw-r--r--runtime/interpreter/unstarted_runtime.cc97
1 files changed, 97 insertions, 0 deletions
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index a971c1b3cf..fbb07e8e8f 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -39,6 +39,7 @@
#include "thread.h"
#include "transaction.h"
#include "well_known_classes.h"
+#include "zip_archive.h"
namespace art {
namespace interpreter {
@@ -641,6 +642,100 @@ static void UnstartedMemoryPeekArrayEntry(
}
}
+// This allows reading security.properties in an unstarted runtime and initialize Security.
+static void UnstartedSecurityGetSecurityPropertiesReader(
+ Thread* self,
+ ShadowFrame* shadow_frame ATTRIBUTE_UNUSED,
+ JValue* result,
+ size_t arg_offset ATTRIBUTE_UNUSED)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ Runtime* runtime = Runtime::Current();
+ const std::vector<const DexFile*>& path = runtime->GetClassLinker()->GetBootClassPath();
+ std::string canonical(DexFile::GetDexCanonicalLocation(path[0]->GetLocation().c_str()));
+ mirror::String* string_data;
+
+ // Use a block to enclose the I/O and MemMap code so buffers are released early.
+ {
+ std::string error_msg;
+ std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(canonical.c_str(), &error_msg));
+ if (zip_archive.get() == nullptr) {
+ AbortTransactionOrFail(self, "Could not open zip file %s: %s", canonical.c_str(),
+ error_msg.c_str());
+ return;
+ }
+ std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find("java/security/security.properties",
+ &error_msg));
+ if (zip_entry.get() == nullptr) {
+ AbortTransactionOrFail(self, "Could not find security.properties file in %s: %s",
+ canonical.c_str(), error_msg.c_str());
+ return;
+ }
+ std::unique_ptr<MemMap> map(zip_entry->ExtractToMemMap(canonical.c_str(),
+ "java/security/security.properties",
+ &error_msg));
+ if (map.get() == nullptr) {
+ AbortTransactionOrFail(self, "Could not unzip security.properties file in %s: %s",
+ canonical.c_str(), error_msg.c_str());
+ return;
+ }
+
+ uint32_t length = zip_entry->GetUncompressedLength();
+ std::unique_ptr<char[]> tmp(new char[length + 1]);
+ memcpy(tmp.get(), map->Begin(), length);
+ tmp.get()[length] = 0; // null terminator
+
+ string_data = mirror::String::AllocFromModifiedUtf8(self, tmp.get());
+ }
+
+ if (string_data == nullptr) {
+ AbortTransactionOrFail(self, "Could not create string from file content of %s",
+ canonical.c_str());
+ return;
+ }
+
+ // Create a StringReader.
+ StackHandleScope<3> hs(self);
+ Handle<mirror::String> h_string(hs.NewHandle(string_data));
+
+ Handle<mirror::Class> h_class(hs.NewHandle(
+ runtime->GetClassLinker()->FindClass(self,
+ "Ljava/io/StringReader;",
+ NullHandle<mirror::ClassLoader>())));
+ if (h_class.Get() == nullptr) {
+ AbortTransactionOrFail(self, "Could not find StringReader class");
+ return;
+ }
+
+ if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
+ AbortTransactionOrFail(self, "Could not initialize StringReader class");
+ return;
+ }
+
+ Handle<mirror::Object> h_obj(hs.NewHandle(h_class->AllocObject(self)));
+ if (h_obj.Get() == nullptr) {
+ AbortTransactionOrFail(self, "Could not allocate StringReader object");
+ return;
+ }
+
+ mirror::ArtMethod* constructor = h_class->FindDeclaredDirectMethod("<init>",
+ "(Ljava/lang/String;)V");
+ if (constructor == nullptr) {
+ AbortTransactionOrFail(self, "Could not find StringReader constructor");
+ return;
+ }
+
+ uint32_t args[1];
+ args[0] = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(h_string.Get()));
+ EnterInterpreterFromInvoke(self, constructor, h_obj.Get(), args, nullptr);
+
+ if (self->IsExceptionPending()) {
+ AbortTransactionOrFail(self, "Could not run StringReader constructor");
+ return;
+ }
+
+ result->SetL(h_obj.Get());
+}
+
static void UnstartedJNIVMRuntimeNewUnpaddedArray(Thread* self,
mirror::ArtMethod* method ATTRIBUTE_UNUSED,
mirror::Object* receiver ATTRIBUTE_UNUSED,
@@ -963,6 +1058,8 @@ static void UnstartedRuntimeInitializeInvokeHandlers() {
&UnstartedMemoryPeekEntry },
{ "void libcore.io.Memory.peekByteArray(long, byte[], int, int)",
&UnstartedMemoryPeekArrayEntry },
+ { "java.io.Reader java.security.Security.getSecurityPropertiesReader()",
+ &UnstartedSecurityGetSecurityPropertiesReader },
};
for (auto& def : defs) {