From ade731854d18839823e57fb2d3d67238c5467d15 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Wed, 27 Aug 2014 14:24:42 -0700 Subject: [PATCH] ART: Fix read-out-of-bounds in the compiler In case of a wide dalvik register, asking for the constant value can lead to a read out of bounds. Bug: 17302671 Change-Id: Ie1849cd67cc418c97cbd7a8524f027f9b66e4c96 --- compiler/dex/mir_graph.h | 2 ++ compiler/dex/quick/codegen_util.cc | 15 +++++++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h index 491d72e9e..5817f9214 100644 --- a/compiler/dex/mir_graph.h +++ b/compiler/dex/mir_graph.h @@ -726,6 +726,8 @@ class MIRGraph { int64_t ConstantValueWide(RegLocation loc) const { DCHECK(IsConst(loc)); + DCHECK(!loc.high_word); // Do not allow asking for the high partner. + DCHECK_LT(loc.orig_sreg + 1, GetNumSSARegs()); return (static_cast(constant_values_[loc.orig_sreg + 1]) << 32) | Low32Bits(static_cast(constant_values_[loc.orig_sreg])); } diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc index 2a51b496a..ee1c46797 100644 --- a/compiler/dex/quick/codegen_util.cc +++ b/compiler/dex/quick/codegen_util.cc @@ -56,16 +56,23 @@ bool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src) { bool res = false; if (rl_src.is_const) { if (rl_src.wide) { + // For wide registers, check whether we're the high partner. In that case we need to switch + // to the lower one for the correct value. + if (rl_src.high_word) { + rl_src.high_word = false; + rl_src.s_reg_low--; + rl_src.orig_sreg--; + } if (rl_src.fp) { - res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src)); + res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src)); } else { - res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src)); + res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src)); } } else { if (rl_src.fp) { - res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src)); + res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src)); } else { - res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src)); + res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src)); } } } -- 2.11.0