diff options
| author | 2019-05-06 13:00:40 -0700 | |
|---|---|---|
| committer | 2019-05-08 17:09:33 +0000 | |
| commit | b34981b0b7a16b084a4ab30ce509ee98bf171e63 (patch) | |
| tree | 3f9b8aa799d7bd20ac1d40397026030746046599 | |
| parent | b9f1d3e5f109048de0055e9f19f1d5af13040e8f (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.cc | 11 | ||||
| -rw-r--r-- | test/800-smali/expected.txt | 1 | ||||
| -rw-r--r-- | test/800-smali/smali/b_122501785.smali | 14 | ||||
| -rw-r--r-- | test/800-smali/src/Main.java | 2 |
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() { |