summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2014-08-27 14:24:42 -0700
committerAndreas Gampe <agampe@google.com>2014-09-02 17:24:48 -0700
commitde0b996661351450fa4d918706c5322e001c29c9 (patch)
treea74031a9577d63786e22c0965f2446072558eb72 /compiler
parent6e3604287f73fbc58d8297c0bca6bfe808524a2b (diff)
downloadart-de0b996661351450fa4d918706c5322e001c29c9.zip
art-de0b996661351450fa4d918706c5322e001c29c9.tar.gz
art-de0b996661351450fa4d918706c5322e001c29c9.tar.bz2
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 (cherry picked from commit ade731854d18839823e57fb2d3d67238c5467d15) Change-Id: Ie1849cd67cc418c97cbd7a8524f027f9b66e4c96
Diffstat (limited to 'compiler')
-rw-r--r--compiler/dex/mir_graph.h2
-rw-r--r--compiler/dex/quick/codegen_util.cc15
2 files changed, 13 insertions, 4 deletions
diff --git a/compiler/dex/mir_graph.h b/compiler/dex/mir_graph.h
index ef43ea2..078970d 100644
--- a/compiler/dex/mir_graph.h
+++ b/compiler/dex/mir_graph.h
@@ -760,6 +760,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]));
}
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 08e1c1a..6d8f288 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -57,16 +57,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));
}
}
}