ART: Fix unchecked register index validity
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
Change-Id: Ie4ed8bbda79f3f6403a24e727450a943447aa71d
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 0ee4414..8495ef2 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3520,12 +3520,24 @@
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