diff options
author | Nicholas Wilson <nicholas@nicholaswilson.me.uk> | 2018-03-05 13:32:38 +0000 |
---|---|---|
committer | Nicholas Wilson <nicholas@nicholaswilson.me.uk> | 2018-03-05 13:32:38 +0000 |
commit | b3748f71df37d2ec7031a99fbe4f0323a264a013 (patch) | |
tree | 824a03a5aeb5011158b1b0d2e9438fc01e9f916f /llvm/lib | |
parent | f20222a83c8f76c52c89201627857c055e879f02 (diff) | |
download | bcm5719-llvm-b3748f71df37d2ec7031a99fbe4f0323a264a013.tar.gz bcm5719-llvm-b3748f71df37d2ec7031a99fbe4f0323a264a013.zip |
[WebAssembly] Add validation to reloc section
We now check relocations offsets are within range, and the relocation
index is valid.
Also updated tests which contained invalid Wasm files that were
previously not checked.
Differential Revision: https://reviews.llvm.org/D43684
llvm-svn: 326697
Diffstat (limited to 'llvm/lib')
-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]; |