From ee56af273999b9c88deda2789729ec468f65da80 Mon Sep 17 00:00:00 2001 From: Yi LIU Date: Thu, 12 Feb 2026 08:48:08 +0800 Subject: [PATCH] Fix out-of-bounds read in objdump reloc section handling BinaryReaderObjdump::OnRelocCount ignored the error returned by BinaryReaderObjdumpBase::OnRelocCount when the section_index was invalid. This caused the function to proceed to GetSectionName which called GetSectionStart with BinarySection::Invalid (~0), resulting in an out-of-bounds read on the stack-allocated section_starts_ array of size kBinarySectionCount (14). Propagate the error via CHECK_RESULT so that the out-of-bounds access is never reached. Add a regression test with a crafted wasm binary containing a reloc custom section that references a non-existent section index. --- CMakeLists.txt | 1 + src/binary-reader-objdump.cc | 2 +- src/test-binary-reader.cc | 37 ++++++++++++++++++++++++++++++++++++ test/binary/bad-relocs.txt | 1 - 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0677862e70..5ea198a3b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -712,6 +712,7 @@ if (BUILD_TESTS) # wabt-unittests set(UNITTESTS_SRCS + src/binary-reader-objdump.cc src/test-binary-reader.cc src/test-interp.cc src/test-intrusive-list.cc diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc index 086bdae13c..b51babeadf 100644 --- a/src/binary-reader-objdump.cc +++ b/src/binary-reader-objdump.cc @@ -2161,7 +2161,7 @@ Result BinaryReaderObjdump::OnDylinkNeeded(std::string_view so_name) { } Result BinaryReaderObjdump::OnRelocCount(Index count, Index section_index) { - BinaryReaderObjdumpBase::OnRelocCount(count, section_index); + CHECK_RESULT(BinaryReaderObjdumpBase::OnRelocCount(count, section_index)); PrintDetails(" - relocations for section: %d (" PRIstringview ") [%d]\n", section_index, WABT_PRINTF_STRING_VIEW_ARG(GetSectionName(section_index)), diff --git a/src/test-binary-reader.cc b/src/test-binary-reader.cc index b3e3540d4f..9994aaf617 100644 --- a/src/test-binary-reader.cc +++ b/src/test-binary-reader.cc @@ -17,6 +17,7 @@ #include "gtest/gtest.h" #include "wabt/binary-reader-nop.h" +#include "wabt/binary-reader-objdump.h" #include "wabt/binary-reader.h" #include "wabt/leb128.h" #include "wabt/opcode.h" @@ -73,3 +74,39 @@ TEST(BinaryReader, DisabledOpcodes) { << "Got error message: " << message; } } + +TEST(BinaryReaderObjdump, RelocInvalidSectionIndex) { + // Minimal wasm with a reloc section referencing a section_index that exceeds + // the actual number of sections. Before the fix, the derived-class + // OnRelocCount ignored the error returned by the base class and proceeded + // to call GetSectionName with BinarySection::Invalid, causing an + // out-of-bounds read on the section_starts_ array. + // + // The fix propagates the base class error via CHECK_RESULT so that the + // out-of-bounds GetSectionName call is never reached. The overall result + // is still Ok because custom section errors are not fatal by default. + + uint8_t data[] = { + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, // magic + version + + // Custom section pretending to be "reloc." (section id 0) + 0x00, // section code: custom + 0x0a, // section size: 10 bytes + // section name "reloc." (length-prefixed) + 0x06, // name length + 'r', 'e', 'l', 'o', 'c', '.', 0xff, + 0x01, // section_index = 255 (invalid, LEB128) + 0x00, // relocation count = 0 + }; + + ObjdumpOptions options; + memset(&options, 0, sizeof(options)); + options.mode = ObjdumpMode::Details; + options.details = true; + ObjdumpState state; + + // Should not crash. Custom section errors are suppressed, so the overall + // result is Ok even though the reloc section itself fails. + Result result = ReadBinaryObjdump(data, sizeof(data), &options, &state); + EXPECT_EQ(Result::Ok, result); +} diff --git a/test/binary/bad-relocs.txt b/test/binary/bad-relocs.txt index 6240ced061..5c609292b9 100644 --- a/test/binary/bad-relocs.txt +++ b/test/binary/bad-relocs.txt @@ -20,7 +20,6 @@ Section Details: Custom: - name: "reloc.BAD" - - relocations for section: 99 () [0] Code Disassembly: