diff options
author | Calder Kitagawa <ckitagawa@chromium.org> | 2018-07-09 18:53:48 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-07-25 20:15:33 -0700 |
commit | 3a5639aa4b0c0fabb9c4db823e478d07091e6a98 (patch) | |
tree | 0c4df581ca36ddcad1e1ac2d4da29bebe8b8fe34 /disassembler_dex.cc | |
parent | 9ae7c82d685435555fab5e47d6413a26dcdd3e2b (diff) | |
download | zucchini-3a5639aa4b0c0fabb9c4db823e478d07091e6a98.tar.gz |
[Zucchini] Fix DEX target index CHECK
When a bad input is created the target indices can point far out of
bounds. Based on the fuzzing this should be promoted to a runtime
LOG(ERROR). Once we have a method to fail a write gracefully this
should be updated to fail the write step.
Bug: 860857
Change-Id: Ie8e4eaf9a655a71e0a2bf3efe2efae52574813db
Reviewed-on: https://chromium-review.googlesource.com/1128813
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Reviewed-by: Samuel Huang <huangs@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573393}
NOKEYCHECK=True
GitOrigin-RevId: 8b47a6add32d3f7e1dab7c929f1d7a978beb94cc
Diffstat (limited to 'disassembler_dex.cc')
-rw-r--r-- | disassembler_dex.cc | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/disassembler_dex.cc b/disassembler_dex.cc index 8a1b339..e94dbc9 100644 --- a/disassembler_dex.cc +++ b/disassembler_dex.cc @@ -698,12 +698,17 @@ static void WriteTargetIndex(const dex::MapItem& target_map_item, size_t target_item_size, Reference ref, MutableBufferView image) { - const size_t idx = (ref.target - target_map_item.offset) / target_item_size; + const size_t unsafe_idx = + (ref.target - target_map_item.offset) / target_item_size; // Verify that index is within bound. - DCHECK_LT(idx, target_map_item.size); + if (unsafe_idx >= target_map_item.size) { + LOG(ERROR) << "Target index out of bounds at: " << AsHex<8>(ref.location) + << "."; + return; + } // Verify that |ref.target| points to start of item. - DCHECK_EQ(ref.target, target_map_item.offset + idx * target_item_size); - image.write<INT>(ref.location, base::checked_cast<INT>(idx)); + DCHECK_EQ(ref.target, target_map_item.offset + unsafe_idx * target_item_size); + image.write<INT>(ref.location, base::checked_cast<INT>(unsafe_idx)); } // Buffer for ReadDexHeader() to optionally return results. @@ -1453,7 +1458,7 @@ std::unique_ptr<ReferenceWriter> DisassemblerDex::MakeWriteRelCode8( // |ref.location|. The subtraction above removed too much, so +1 to fix. base::CheckedNumeric<int8_t> delta((unsafe_byte_diff / kInstrUnitSize) + 1); if (!delta.IsValid()) { - LOG(ERROR) << "Invalid reference at: " << AsHex<8>(ref.location); + LOG(ERROR) << "Invalid reference at: " << AsHex<8>(ref.location) << "."; return; } image.write<int8_t>(ref.location, delta.ValueOrDie()); @@ -1472,7 +1477,7 @@ std::unique_ptr<ReferenceWriter> DisassemblerDex::MakeWriteRelCode16( base::CheckedNumeric<int16_t> delta((unsafe_byte_diff / kInstrUnitSize) + 1); if (!delta.IsValid()) { - LOG(ERROR) << "Invalid reference at: " << AsHex<8>(ref.location); + LOG(ERROR) << "Invalid reference at: " << AsHex<8>(ref.location) << "."; return; } image.write<int16_t>(ref.location, delta.ValueOrDie()); @@ -1491,7 +1496,7 @@ std::unique_ptr<ReferenceWriter> DisassemblerDex::MakeWriteRelCode32( base::CheckedNumeric<int32_t> delta((unsafe_byte_diff / kInstrUnitSize) + 1); if (!delta.IsValid()) { - LOG(ERROR) << "Invalid reference at: " << AsHex<8>(ref.location); + LOG(ERROR) << "Invalid reference at: " << AsHex<8>(ref.location) << "."; return; } image.write<int32_t>(ref.location, delta.ValueOrDie()); |