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);
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);
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:
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)
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];