summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/WasmObjectFile.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Object/WasmObjectFile.cpp')
-rw-r--r--llvm/lib/Object/WasmObjectFile.cpp44
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];
OpenPOWER on IntegriCloud