OSDN Git Service

ART: Fix unchecked register index validity
authorAndreas Gampe <agampe@google.com>
Sun, 7 Sep 2014 20:06:12 +0000 (13:06 -0700)
committerAndreas Gampe <agampe@google.com>
Tue, 9 Sep 2014 05:08:53 +0000 (22:08 -0700)
The static check of index validity is against the type given by
the instruction, e.g., boolean for SPUT_BOOLEAN, but the target_type
is the resolved field type and can differ. An additional check is
necessary to avoid a read out of bounds.

Bug: 17411109

(cherry picked from commit 74ae47a0590feceea31a2388f98c83e3ec0df0ec)

Change-Id: Ie4ed8bbda79f3f6403a24e727450a943447aa71d

runtime/verifier/method_verifier.cc

index ef6b343..c21a7a4 100644 (file)
@@ -3530,12 +3530,24 @@ void MethodVerifier::VerifyPrimitivePut(RegType& target_type, RegType& insn_type
     value_compatible = value_type.IsFloatTypes();
   } else if (target_type.IsLong()) {
     instruction_compatible = insn_type.IsLong();
-    RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
-    value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
+    // Additional register check: this is not checked statically (as part of VerifyInstructions),
+    // as target_type depends on the resolved type of the field.
+    if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
+      RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
+      value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
+    } else {
+      value_compatible = false;
+    }
   } else if (target_type.IsDouble()) {
     instruction_compatible = insn_type.IsLong();  // no put-double, so expect put-long
-    RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
-    value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
+    // Additional register check: this is not checked statically (as part of VerifyInstructions),
+    // as target_type depends on the resolved type of the field.
+    if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
+      RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
+      value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
+    } else {
+      value_compatible = false;
+    }
   } else {
     instruction_compatible = false;  // reference with primitive store
     value_compatible = false;  // unused