From 74ae47a0590feceea31a2388f98c83e3ec0df0ec Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Sun, 7 Sep 2014 13:06:12 -0700 Subject: [PATCH] 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 --- runtime/verifier/method_verifier.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 0ee4414d2..8495ef2a1 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -3520,12 +3520,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 -- 2.11.0