From f9ce75bf1830d5488211ede06be71d08c694dcf3 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Mon, 23 Oct 2017 18:04:34 +0000 Subject: [PATCH] [wasm] readSection: Avoid reading past eof (fixes oss-fuzz #3219) A wasm file crafted with a bogus section size can trigger an ASan issue in the DWARFObjInMemory constructor. Nip the problem in the bud when we read the wasm section. Found by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3219 Differential Revision: https://reviews.llvm.org/D38777 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@316357 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Object/WasmObjectFile.cpp | 8 +++++--- .../tools/llvm-objdump/Inputs/corrupt-section.wasm | Bin 0 -> 22 bytes test/tools/llvm-objdump/wasm-corrupt-section.test | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 test/tools/llvm-objdump/Inputs/corrupt-section.wasm create mode 100644 test/tools/llvm-objdump/wasm-corrupt-section.test diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp index 15a78df5402..86ce9c2209c 100644 --- a/lib/Object/WasmObjectFile.cpp +++ b/lib/Object/WasmObjectFile.cpp @@ -178,14 +178,16 @@ static wasm::WasmTable readTable(const uint8_t *&Ptr) { } static Error readSection(WasmSection &Section, const uint8_t *&Ptr, - const uint8_t *Start) { - // TODO(sbc): Avoid reading past EOF in the case of malformed files. + const uint8_t *Start, const uint8_t *Eof) { Section.Offset = Ptr - Start; Section.Type = readVaruint7(Ptr); uint32_t Size = readVaruint32(Ptr); if (Size == 0) return make_error("Zero length section", object_error::parse_failed); + if (Ptr + Size > Eof) + return make_error("Section too large", + object_error::parse_failed); Section.Content = ArrayRef(Ptr, Size); Ptr += Size; return Error::success(); @@ -221,7 +223,7 @@ WasmObjectFile::WasmObjectFile(MemoryBufferRef Buffer, Error &Err) WasmSection Sec; while (Ptr < Eof) { - if ((Err = readSection(Sec, Ptr, getPtr(0)))) + if ((Err = readSection(Sec, Ptr, getPtr(0), Eof))) return; if ((Err = parseSection(Sec))) return; diff --git a/test/tools/llvm-objdump/Inputs/corrupt-section.wasm b/test/tools/llvm-objdump/Inputs/corrupt-section.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3bf45f715db6b29c65e47f068bf725ec4ffc5f19 GIT binary patch literal 22 YcmZQbEY4+Q0D^PpG|!zo2VwyM07T0LasU7T literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objdump/wasm-corrupt-section.test b/test/tools/llvm-objdump/wasm-corrupt-section.test new file mode 100644 index 00000000000..9ba7a7ef6bd --- /dev/null +++ b/test/tools/llvm-objdump/wasm-corrupt-section.test @@ -0,0 +1,2 @@ +# RUN: not llvm-objdump -h %p/Inputs/corrupt-section.wasm 2>&1 | FileCheck %s +# CHECK: '{{.*}}corrupt-section.wasm': Section too large -- 2.40.0