summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2019-05-06 13:00:40 -0700
committer Treehugger Robot <treehugger-gerrit@google.com> 2019-05-08 17:09:33 +0000
commitb34981b0b7a16b084a4ab30ce509ee98bf171e63 (patch)
tree3f9b8aa799d7bd20ac1d40397026030746046599
parentb9f1d3e5f109048de0055e9f19f1d5af13040e8f (diff)
ART: Fix hidden hard fail in instance field verification
Move the reference type check for the given object upfront so that it isn't hidden by other soft-fail cases. Bug: 122501785 Test: m test-art-host Test: art/test/testrunner/testrunner.py -b --host -t 800 Change-Id: I715a859665a9550bc23defa63ba6fbecd13d7531
-rw-r--r--runtime/verifier/method_verifier.cc11
-rw-r--r--test/800-smali/expected.txt1
-rw-r--r--test/800-smali/smali/b_122501785.smali14
-rw-r--r--test/800-smali/src/Main.java2
4 files changed, 23 insertions, 5 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 32cd47a750..79b3178efc 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -4692,6 +4692,12 @@ ArtField* MethodVerifier<kVerifierDebug>::GetStaticField(int field_idx) {
template <bool kVerifierDebug>
ArtField* MethodVerifier<kVerifierDebug>::GetInstanceField(const RegType& obj_type, int field_idx) {
+ if (!obj_type.IsZeroOrNull() && !obj_type.IsReferenceTypes()) {
+ // Trying to read a field from something that isn't a reference.
+ Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
+ << "non-reference type " << obj_type;
+ return nullptr;
+ }
const dex::FieldId& field_id = dex_file_->GetFieldId(field_idx);
// Check access to class.
const RegType& klass_type = ResolveClass<CheckAccess::kYes>(field_id.class_idx_);
@@ -4725,11 +4731,6 @@ ArtField* MethodVerifier<kVerifierDebug>::GetInstanceField(const RegType& obj_ty
} else if (obj_type.IsZeroOrNull()) {
// Cannot infer and check type, however, access will cause null pointer exception.
// Fall through into a few last soft failure checks below.
- } else if (!obj_type.IsReferenceTypes()) {
- // Trying to read a field from something that isn't a reference.
- Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
- << "non-reference type " << obj_type;
- return nullptr;
} else {
std::string temp;
ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
diff --git a/test/800-smali/expected.txt b/test/800-smali/expected.txt
index 291de725b3..63859fe4e5 100644
--- a/test/800-smali/expected.txt
+++ b/test/800-smali/expected.txt
@@ -74,4 +74,5 @@ b/30458218
b/31313170
ConstClassAliasing
b/121191566
+b/122501785
Done!
diff --git a/test/800-smali/smali/b_122501785.smali b/test/800-smali/smali/b_122501785.smali
new file mode 100644
index 0000000000..240aad9c6e
--- /dev/null
+++ b/test/800-smali/smali/b_122501785.smali
@@ -0,0 +1,14 @@
+.class public LB122501785;
+
+# Test that a hard + soft verifier failure in instance field access
+# correctly triggers the hard fail to protect the compiler.
+
+.super Ljava/lang/Object;
+
+.method public static run(LB122501785;Ljava/lang/Object;)V
+ .registers 4
+ const/4 v0, 0
+ const/4 v1, 1
+ iput-boolean v0, v1, Ldoes/not/Exist;->field:Z
+ return-void
+.end method
diff --git a/test/800-smali/src/Main.java b/test/800-smali/src/Main.java
index d7979e1d30..d10fdf1612 100644
--- a/test/800-smali/src/Main.java
+++ b/test/800-smali/src/Main.java
@@ -195,6 +195,8 @@ public class Main {
null, true));
testCases.add(new TestCase("b/121191566", "B121191566", "run", new Object[] { "a" }, null,
true, false));
+ testCases.add(new TestCase("b/122501785", "B122501785", "run", null, new VerifyError(),
+ 0));
}
public void runTests() {