llvm.org GIT mirror llvm / 50ad62d
[BitcodeReader] Use tighter upper bound to validate forward references. At the moment, bitcode files with invalid forward reference can easily cause the bitcode reader to run out of memory, by creating a forward reference with a very high index. We can use the size of the bitcode file as an upper bound, because a valid bitcode file can never contain more records. This should be sufficient to fail early in most cases. The only exception is large files with invalid forward references close to the file size. There are a couple of clusterfuzz runs that fail with out-of-memory because of very high forward references and they should be fixed by this patch. A concrete example for this is D64507, which causes out-of-memory on systems with low memory, like the hexagon upstream bots. Reviewers: t.p.northover, thegameg, jfb, efriedma, hfinkel Reviewed By: jfb Differential Revision: https://reviews.llvm.org/D64577 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366017 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn a month ago
6 changed file(s) with 38 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
293293 BitsInCurWord = 0;
294294 }
295295
296 /// Return the size of the stream in bytes.
297 size_t SizeInBytes() const { return BitcodeBytes.size(); }
298
296299 /// Skip to the end of the file.
297300 void skipToEnd() { NextChar = BitcodeBytes.size(); }
298301 };
363366 explicit BitstreamCursor(MemoryBufferRef BitcodeBytes)
364367 : SimpleBitstreamCursor(BitcodeBytes) {}
365368
369 using SimpleBitstreamCursor::AtEndOfStream;
366370 using SimpleBitstreamCursor::canSkipToPos;
367 using SimpleBitstreamCursor::AtEndOfStream;
371 using SimpleBitstreamCursor::fillCurWord;
368372 using SimpleBitstreamCursor::getBitcodeBytes;
369373 using SimpleBitstreamCursor::GetCurrentBitNo;
370374 using SimpleBitstreamCursor::getCurrentByteNo;
371375 using SimpleBitstreamCursor::getPointerToByte;
372376 using SimpleBitstreamCursor::JumpToBit;
373 using SimpleBitstreamCursor::fillCurWord;
374377 using SimpleBitstreamCursor::Read;
375378 using SimpleBitstreamCursor::ReadVBR;
376379 using SimpleBitstreamCursor::ReadVBR64;
380 using SimpleBitstreamCursor::SizeInBytes;
377381
378382 /// Return the number of bits used to encode an abbrev #.
379383 unsigned getAbbrevIDWidth() const { return CurCodeSize; }
857857 StringRef ProducerIdentification,
858858 LLVMContext &Context)
859859 : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context),
860 ValueList(Context) {
860 ValueList(Context, Stream.SizeInBytes()) {
861861 this->ProducerIdentification = ProducerIdentification;
862862 }
863863
129129
130130 LLVMContext &Context;
131131
132 /// Maximum number of valid references. Forward references exceeding the
133 /// maximum must be invalid.
134 unsigned RefsUpperBound;
135
132136 public:
133 BitcodeReaderMetadataList(LLVMContext &C) : Context(C) {}
137 BitcodeReaderMetadataList(LLVMContext &C, size_t RefsUpperBound)
138 : Context(C),
139 RefsUpperBound(std::min((size_t)std::numeric_limits::max(),
140 RefsUpperBound)) {}
134141
135142 // vector compatibility methods
136143 unsigned size() const { return MetadataPtrs.size(); }
217224 }
218225
219226 Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
227 // Bail out for a clearly invalid value.
228 if (Idx >= RefsUpperBound)
229 return nullptr;
230
220231 if (Idx >= size())
221232 resize(Idx + 1);
222233
624635 BitcodeReaderValueList &ValueList,
625636 std::function getTypeByID,
626637 bool IsImporting)
627 : MetadataList(TheModule.getContext()), ValueList(ValueList),
628 Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule),
629 getTypeByID(std::move(getTypeByID)), IsImporting(IsImporting) {}
638 : MetadataList(TheModule.getContext(), Stream.SizeInBytes()),
639 ValueList(ValueList), Stream(Stream), Context(TheModule.getContext()),
640 TheModule(TheModule), getTypeByID(std::move(getTypeByID)),
641 IsImporting(IsImporting) {}
630642
631643 Error parseMetadata(bool ModuleLevel);
632644
9696 }
9797
9898 Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty) {
99 // Bail out for a clearly invalid value.
100 if (Idx >= RefsUpperBound)
101 return nullptr;
102
99103 if (Idx >= size())
100104 resize(Idx + 1);
101105
113117
114118 Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
115119 Type **FullTy) {
116 // Bail out for a clearly invalid value. This would make us call resize(0)
117 if (Idx == std::numeric_limits::max())
120 // Bail out for a clearly invalid value.
121 if (Idx >= RefsUpperBound)
118122 return nullptr;
119123
120124 if (Idx >= size())
4545 ResolveConstantsTy ResolveConstants;
4646 LLVMContext &Context;
4747
48 /// Maximum number of valid references. Forward references exceeding the
49 /// maximum must be invalid.
50 unsigned RefsUpperBound;
51
4852 public:
49 BitcodeReaderValueList(LLVMContext &C) : Context(C) {}
53 BitcodeReaderValueList(LLVMContext &C, size_t RefsUpperBound)
54 : Context(C),
55 RefsUpperBound(std::min((size_t)std::numeric_limits::max(),
56 RefsUpperBound)) {}
5057
5158 ~BitcodeReaderValueList() {
5259 assert(ResolveConstants.empty() && "Constants not resolved?");
0 ; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
11
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Never resolved value found in function
2 ; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Invalid record
33
44 ; pr18704.ll.bc has an instruction referring to invalid type.
55 ; The test checks that LLVM reports the error and doesn't access freed memory