diff options
author | ckitagawa <ckitagawa@chromium.org> | 2019-12-16 19:53:11 +0000 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-07-25 20:58:51 -0700 |
commit | 065411df3e73efa49eb275523021103412326655 (patch) | |
tree | 83067a02c76f84d5a74d8b50392c4b2521cdb20c /disassembler_elf.cc | |
parent | a565cf1dc2375b11fbc5525e5b44103376f336d4 (diff) | |
download | zucchini-065411df3e73efa49eb275523021103412326655.tar.gz |
[Zucchini] Fix fuzzer checked_cast issues
The fuzzer for the disassembler_elf found a couple of ways to trigger
checked_cast failures in the ParseHeader function. Other disassemblers
handle such failures by cleanly exiting as opposed to crashing due to a
CHECK. This turned out to be a problem with numeric overflow in
JudgeSection.
Bug: 1029405
Change-Id: Idae395f74a43a1de4793db6222d7786e57e9ad30
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1967070
Reviewed-by: Etienne Pierre-Doray <etiennep@chromium.org>
Commit-Queue: Calder Kitagawa <ckitagawa@chromium.org>
Cr-Commit-Position: refs/heads/master@{#725225}
NOKEYCHECK=True
GitOrigin-RevId: 925bb161e0dcd816510f616190a2ba24c0bea2bb
Diffstat (limited to 'disassembler_elf.cc')
-rw-r--r-- | disassembler_elf.cc | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/disassembler_elf.cc b/disassembler_elf.cc index fdc104f..ad2cafd 100644 --- a/disassembler_elf.cc +++ b/disassembler_elf.cc @@ -44,6 +44,15 @@ enum SectionJudgement : int { // from SectionJudgement values. template <class Traits> int JudgeSection(size_t image_size, const typename Traits::Elf_Shdr* section) { + // BufferRegion uses |size_t| this can be 32-bit in some cases. For Elf64 + // |sh_addr|, |sh_offset| and |sh_size| are 64-bit this can result in + // overflows in the subsequent validation steps. + if (!base::IsValueInRangeForNumericType<size_t>(section->sh_addr) || + !base::IsValueInRangeForNumericType<size_t>(section->sh_offset) || + !base::IsValueInRangeForNumericType<size_t>(section->sh_size)) { + return SECTION_IS_MALFORMED; + } + // Examine RVA range: Reject if numerical overflow may happen. if (!BufferRegion{section->sh_addr, section->sh_size}.FitsIn(kSizeBound)) return SECTION_IS_MALFORMED; @@ -219,6 +228,9 @@ std::unique_ptr<ReferenceWriter> DisassemblerElf<Traits>::MakeWriteRelocs( template <class Traits> bool DisassemblerElf<Traits>::ParseHeader() { BufferSource source(image_); + // Ensure any offsets will fit within the |image_|'s bounds. + if (!base::IsValueInRangeForNumericType<offset_t>(image_.size())) + return false; // Ensures |header_| is valid later on. if (!QuickDetect(image_)) |