OSDN Git Service

ART: Fix read-out-of-bounds in the compiler
authorAndreas Gampe <agampe@google.com>
Wed, 27 Aug 2014 21:24:42 +0000 (14:24 -0700)
committerAndreas Gampe <agampe@google.com>
Wed, 27 Aug 2014 21:24:42 +0000 (14:24 -0700)
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
compiler/dex/quick/codegen_util.cc

index 491d72e..5817f92 100644 (file)
@@ -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<int64_t>(constant_values_[loc.orig_sreg + 1]) << 32) |
         Low32Bits(static_cast<int64_t>(constant_values_[loc.orig_sreg]));
   }
index 2a51b49..ee1c467 100644 (file)
@@ -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));
       }
     }
   }