summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/driver/compiler_driver.cc47
-rw-r--r--dex2oat/dex2oat.cc1
-rw-r--r--test/719-dm-verify-redefinition/check22
-rw-r--r--test/719-dm-verify-redefinition/expected.txt3
-rw-r--r--test/719-dm-verify-redefinition/info.txt2
-rw-r--r--test/719-dm-verify-redefinition/run18
-rw-r--r--test/719-dm-verify-redefinition/src/Main.java27
-rw-r--r--test/719-dm-verify-redefinition/src/java/util/BitSet.java20
-rw-r--r--test/knownfailures.json8
9 files changed, 148 insertions, 0 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index e440eec735..d46cffb1e8 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1765,6 +1765,42 @@ static void LoadAndUpdateStatus(const ClassAccessor& accessor,
}
}
+// Returns true if any of the given dex files define a class from the boot classpath.
+static bool DexFilesRedefineBootClasses(
+ const std::vector<const DexFile*>& dex_files,
+ TimingLogger* timings) {
+ TimingLogger::ScopedTiming t("Fast Verify: Boot Class Redefinition Check", timings);
+
+ ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
+ Thread* self = Thread::Current();
+ ScopedObjectAccess soa(self);
+
+ bool foundRedefinition = false;
+ for (const DexFile* dex_file : dex_files) {
+ for (ClassAccessor accessor : dex_file->GetClasses()) {
+ const char* descriptor = accessor.GetDescriptor();
+ StackHandleScope<1> hs_class(self);
+ Handle<mirror::Class> klass =
+ hs_class.NewHandle(class_linker->FindSystemClass(self, descriptor));
+ if (klass == nullptr) {
+ self->ClearException();
+ } else {
+ LOG(WARNING) << "Redefinition of boot class " << descriptor
+ << " App dex file: " << accessor.GetDexFile().GetLocation()
+ << " Boot dex file: " << klass->GetDexFile().GetLocation();
+ foundRedefinition = true;
+ if (!VLOG_IS_ON(verifier)) {
+ // If we are not in verbose mode, return early.
+ // Otherwise continue and log all the collisions for easier debugging.
+ return true;
+ }
+ }
+ }
+ }
+
+ return foundRedefinition;
+}
+
bool CompilerDriver::FastVerify(jobject jclass_loader,
const std::vector<const DexFile*>& dex_files,
TimingLogger* timings,
@@ -1776,6 +1812,17 @@ bool CompilerDriver::FastVerify(jobject jclass_loader,
return false;
}
TimingLogger::ScopedTiming t("Fast Verify", timings);
+
+ // We cannot do fast verification if the app redefines classes from the boot classpath.
+ // Vdex does not record resolution chains for boot classes and we might wrongfully
+ // resolve a class to the app when it should have been resolved to the boot classpath
+ // (e.g. if we verified against the SDK and the app redefines a boot class which is not
+ // in the SDK.)
+ if (DexFilesRedefineBootClasses(dex_files, timings)) {
+ LOG(WARNING) << "Found redefinition of boot classes. Not doing fast verification.";
+ return false;
+ }
+
ScopedObjectAccess soa(Thread::Current());
StackHandleScope<2> hs(soa.Self());
Handle<mirror::ClassLoader> class_loader(
diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc
index 35af918757..808ad6c212 100644
--- a/dex2oat/dex2oat.cc
+++ b/dex2oat/dex2oat.cc
@@ -1367,6 +1367,7 @@ class Dex2Oat final {
LOG(WARNING) << "Could not open vdex file in DexMetadata archive: " << error_msg;
} else {
input_vdex_file_ = std::make_unique<VdexFile>(std::move(input_file));
+ VLOG(verifier) << "Doing fast verification with vdex from DexMetadata archive";
}
}
}
diff --git a/test/719-dm-verify-redefinition/check b/test/719-dm-verify-redefinition/check
new file mode 100644
index 0000000000..b3c717c280
--- /dev/null
+++ b/test/719-dm-verify-redefinition/check
@@ -0,0 +1,22 @@
+#!/bin/bash
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Search for the redefinition line and remove unnecessary tags.
+sed -e 's/^dex2oat[d]\?\(\|32\|64\)\ W.*\] Found redefinition of boot classes\. Not doing fast verification\./Found redefinition of boot classes\. Not doing fast verification\./g' "$2" > "$2.tmp1"
+# Remove all other dex2oat log lines.
+grep -v dex2oat "$2.tmp1" >> "$2.tmp2"
+
+./default-check "$1" "$2.tmp2"
diff --git a/test/719-dm-verify-redefinition/expected.txt b/test/719-dm-verify-redefinition/expected.txt
new file mode 100644
index 0000000000..64fb4ea7ea
--- /dev/null
+++ b/test/719-dm-verify-redefinition/expected.txt
@@ -0,0 +1,3 @@
+Found redefinition of boot classes. Not doing fast verification.
+Hello, world!
+Correct resolution of boot class.
diff --git a/test/719-dm-verify-redefinition/info.txt b/test/719-dm-verify-redefinition/info.txt
new file mode 100644
index 0000000000..1229bdb7db
--- /dev/null
+++ b/test/719-dm-verify-redefinition/info.txt
@@ -0,0 +1,2 @@
+Verifies that the vdex file from a DexMetadata archive is discarded
+if the app redefines boot classes.
diff --git a/test/719-dm-verify-redefinition/run b/test/719-dm-verify-redefinition/run
new file mode 100644
index 0000000000..8e568b59fb
--- /dev/null
+++ b/test/719-dm-verify-redefinition/run
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+export ANDROID_LOG_TAGS='*:w'
+exec ${RUN} --external-log-tags --dm "${@}"
diff --git a/test/719-dm-verify-redefinition/src/Main.java b/test/719-dm-verify-redefinition/src/Main.java
new file mode 100644
index 0000000000..37575b6fcf
--- /dev/null
+++ b/test/719-dm-verify-redefinition/src/Main.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import java.util.BitSet;
+
+public class Main {
+ public static void main(String[] args) {
+ System.out.println("Hello, world!");
+ if (BitSet.class.getClassLoader().equals(String.class.getClassLoader())) {
+ System.out.println("Correct resolution of boot class.");
+ } else {
+ System.out.println("Bogus resolution of boot class.");
+ }
+ }
+}
diff --git a/test/719-dm-verify-redefinition/src/java/util/BitSet.java b/test/719-dm-verify-redefinition/src/java/util/BitSet.java
new file mode 100644
index 0000000000..5d91fd8d59
--- /dev/null
+++ b/test/719-dm-verify-redefinition/src/java/util/BitSet.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.util;
+
+public class BitSet {
+}
diff --git a/test/knownfailures.json b/test/knownfailures.json
index c4764e8c2d..b97b4c1b88 100644
--- a/test/knownfailures.json
+++ b/test/knownfailures.json
@@ -1177,5 +1177,13 @@
"variant": "jit-on-first-use",
"bug": "b/120112467",
"description": [ "Fails on Android Build hosts with uncaught std::bad_alloc." ]
+ },
+ {
+ "tests": ["719-dm-verify-redefinition"],
+ "variant": "jvm | speed-profile | interp-ac | target",
+ "description": ["Doesn't run on RI because of boot class redefintion.",
+ "Doesn't work with profiles because the run-test is not setup to",
+ "support both. It also needs full verification, so no interp-ac.",
+ "Requires zip, which isn't available on device"]
}
]