diff options
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r-- | llvm/lib/Object/WasmObjectFile.cpp | 44 |
1 files changed, 40 insertions, 4 deletions
diff --git a/llvm/lib/Object/WasmObjectFile.cpp b/llvm/lib/Object/WasmObjectFile.cpp index 23f25ea9aed..044bd76e5f6 100644 --- a/llvm/lib/Object/WasmObjectFile.cpp +++ b/llvm/lib/Object/WasmObjectFile.cpp @@ -339,7 +339,7 @@ Error WasmObjectFile::parseLinkingSection(const uint8_t *Ptr, wasm::WasmInitFunc Init; Init.Priority = readVaruint32(Ptr); Init.Symbol = readVaruint32(Ptr); - if (!isValidFunctionSymbolIndex(Init.Symbol)) + if (!isValidFunctionSymbol(Init.Symbol)) return make_error<GenericBinaryError>("Invalid function symbol: " + Twine(Init.Symbol), object_error::parse_failed); @@ -554,9 +554,10 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr, return make_error<GenericBinaryError>("Invalid section code", object_error::parse_failed); uint32_t RelocCount = readVaruint32(Ptr); + uint32_t LastOffset = 0; + uint32_t EndOffset = Section->Content.size(); while (RelocCount--) { - wasm::WasmRelocation Reloc; - memset(&Reloc, 0, sizeof(Reloc)); + wasm::WasmRelocation Reloc = {}; Reloc.Type = readVaruint32(Ptr); Reloc.Offset = readVaruint32(Ptr); Reloc.Index = readVaruint32(Ptr); @@ -564,12 +565,26 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr, case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB: case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB: case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32: + if (!isValidFunctionSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("Bad relocation function index", + object_error::parse_failed); + break; case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB: + if (Reloc.Index >= Signatures.size()) + return make_error<GenericBinaryError>("Bad relocation type index", + object_error::parse_failed); + break; case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB: + if (!isValidGlobalSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("Bad relocation global index", + object_error::parse_failed); break; case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB: case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32: + if (!isValidDataSymbol(Reloc.Index)) + return make_error<GenericBinaryError>("Bad relocation data index", + object_error::parse_failed); Reloc.Addend = readVarint32(Ptr); break; default: @@ -577,6 +592,19 @@ Error WasmObjectFile::parseRelocSection(StringRef Name, const uint8_t *Ptr, Twine(Reloc.Type), object_error::parse_failed); } + + // Relocations must fit inside the section, and must appear in order. They + // also shouldn't overlap a function/element boundary, but we don't bother + // to check that. + uint64_t Size = 5; + if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 || + Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32) + Size = 4; + if (Reloc.Offset < LastOffset || Reloc.Offset + Size > EndOffset) + return make_error<GenericBinaryError>("Bad relocation offset", + object_error::parse_failed); + LastOffset = Reloc.Offset; + Section->Relocations.push_back(Reloc); } if (Ptr != End) @@ -787,10 +815,18 @@ bool WasmObjectFile::isDefinedGlobalIndex(uint32_t Index) const { return Index >= NumImportedGlobals && isValidGlobalIndex(Index); } -bool WasmObjectFile::isValidFunctionSymbolIndex(uint32_t Index) const { +bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const { return Index < Symbols.size() && Symbols[Index].isTypeFunction(); } +bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const { + return Index < Symbols.size() && Symbols[Index].isTypeGlobal(); +} + +bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const { + return Index < Symbols.size() && Symbols[Index].isTypeData(); +} + wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) { assert(isDefinedFunctionIndex(Index)); return Functions[Index - NumImportedFunctions]; |