llvm.org GIT mirror llvm / e0316ce
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326697 91177308-0d34-0410-b5e6-96231b3b80d8 Nicholas Wilson 1 year, 5 months ago
4 changed file(s) with 67 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
202202 bool isDefinedFunctionIndex(uint32_t Index) const;
203203 bool isValidGlobalIndex(uint32_t Index) const;
204204 bool isDefinedGlobalIndex(uint32_t Index) const;
205 bool isValidFunctionSymbolIndex(uint32_t Index) const;
205 bool isValidFunctionSymbol(uint32_t Index) const;
206 bool isValidGlobalSymbol(uint32_t Index) const;
207 bool isValidDataSymbol(uint32_t Index) const;
206208 wasm::WasmFunction &getDefinedFunction(uint32_t Index);
207209 wasm::WasmGlobal &getDefinedGlobal(uint32_t Index);
208210
338338 wasm::WasmInitFunc Init;
339339 Init.Priority = readVaruint32(Ptr);
340340 Init.Symbol = readVaruint32(Ptr);
341 if (!isValidFunctionSymbolIndex(Init.Symbol))
341 if (!isValidFunctionSymbol(Init.Symbol))
342342 return make_error("Invalid function symbol: " +
343343 Twine(Init.Symbol),
344344 object_error::parse_failed);
553553 return make_error("Invalid section code",
554554 object_error::parse_failed);
555555 uint32_t RelocCount = readVaruint32(Ptr);
556 uint32_t LastOffset = 0;
557 uint32_t EndOffset = Section->Content.size();
556558 while (RelocCount--) {
557 wasm::WasmRelocation Reloc;
558 memset(&Reloc, 0, sizeof(Reloc));
559 wasm::WasmRelocation Reloc = {};
559560 Reloc.Type = readVaruint32(Ptr);
560561 Reloc.Offset = readVaruint32(Ptr);
561562 Reloc.Index = readVaruint32(Ptr);
563564 case wasm::R_WEBASSEMBLY_FUNCTION_INDEX_LEB:
564565 case wasm::R_WEBASSEMBLY_TABLE_INDEX_SLEB:
565566 case wasm::R_WEBASSEMBLY_TABLE_INDEX_I32:
567 if (!isValidFunctionSymbol(Reloc.Index))
568 return make_error("Bad relocation function index",
569 object_error::parse_failed);
570 break;
566571 case wasm::R_WEBASSEMBLY_TYPE_INDEX_LEB:
572 if (Reloc.Index >= Signatures.size())
573 return make_error("Bad relocation type index",
574 object_error::parse_failed);
575 break;
567576 case wasm::R_WEBASSEMBLY_GLOBAL_INDEX_LEB:
577 if (!isValidGlobalSymbol(Reloc.Index))
578 return make_error("Bad relocation global index",
579 object_error::parse_failed);
568580 break;
569581 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_LEB:
570582 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_SLEB:
571583 case wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32:
584 if (!isValidDataSymbol(Reloc.Index))
585 return make_error("Bad relocation data index",
586 object_error::parse_failed);
572587 Reloc.Addend = readVarint32(Ptr);
573588 break;
574589 default:
576591 Twine(Reloc.Type),
577592 object_error::parse_failed);
578593 }
594
595 // Relocations must fit inside the section, and must appear in order. They
596 // also shouldn't overlap a function/element boundary, but we don't bother
597 // to check that.
598 uint64_t Size = 5;
599 if (Reloc.Type == wasm::R_WEBASSEMBLY_TABLE_INDEX_I32 ||
600 Reloc.Type == wasm::R_WEBASSEMBLY_MEMORY_ADDR_I32)
601 Size = 4;
602 if (Reloc.Offset < LastOffset || Reloc.Offset + Size > EndOffset)
603 return make_error("Bad relocation offset",
604 object_error::parse_failed);
605 LastOffset = Reloc.Offset;
606
579607 Section->Relocations.push_back(Reloc);
580608 }
581609 if (Ptr != End)
786814 return Index >= NumImportedGlobals && isValidGlobalIndex(Index);
787815 }
788816
789 bool WasmObjectFile::isValidFunctionSymbolIndex(uint32_t Index) const {
817 bool WasmObjectFile::isValidFunctionSymbol(uint32_t Index) const {
790818 return Index < Symbols.size() && Symbols[Index].isTypeFunction();
819 }
820
821 bool WasmObjectFile::isValidGlobalSymbol(uint32_t Index) const {
822 return Index < Symbols.size() && Symbols[Index].isTypeGlobal();
823 }
824
825 bool WasmObjectFile::isValidDataSymbol(uint32_t Index) const {
826 return Index < Symbols.size() && Symbols[Index].isTypeData();
791827 }
792828
793829 wasm::WasmFunction &WasmObjectFile::getDefinedFunction(uint32_t Index) {
3636 - Type: I32
3737 Count: 1
3838 Body: 108180808000210020000F0B
39 - Type: CUSTOM
40 Name: linking
41 SymbolTable:
42 - Index: 0
43 Kind: FUNCTION
44 Name: func1
45 Flags: [ ]
46 Function: 0
47 - Index: 1
48 Kind: FUNCTION
49 Name: func2
50 Flags: [ ]
51 Function: 1
3952 ...
4053 # CHECK: --- !WASM
4154 # CHECK: FileHeader:
2121 Index: 0
2222 Offset: 0x00000006
2323 Addend: -6
24 - Type: CUSTOM
25 Name: linking
26 SymbolTable:
27 - Index: 0
28 Kind: DATA
29 Name: dataSymbol
30 Flags: [ ]
31 Segment: 0
32 Offset: 0
33 Size: 4
2434 ...
2535 # CHECK: --- !WASM
2636 # CHECK: FileHeader:
4353 # CHECK-NEXT: Opcode: I32_CONST
4454 # CHECK-NEXT: Value: 4
4555 # CHECK-NEXT: Content: '10001000'
46 # CHECK-NEXT: ...
56 # CHECK-NEXT: - Type: CUSTOM