diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 20 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/ValueList.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/ValueList.h | 9 |
4 files changed, 31 insertions, 8 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 09bd0f4ec71..d07edefcffa 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -858,7 +858,7 @@ BitcodeReader::BitcodeReader(BitstreamCursor Stream, StringRef Strtab, StringRef ProducerIdentification, LLVMContext &Context) : BitcodeReaderBase(std::move(Stream), Strtab), Context(Context), - ValueList(Context) { + ValueList(Context, Stream.SizeInBytes()) { this->ProducerIdentification = ProducerIdentification; } diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 24620ed10d7..108f7118958 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -130,8 +130,15 @@ class BitcodeReaderMetadataList { LLVMContext &Context; + /// Maximum number of valid references. Forward references exceeding the + /// maximum must be invalid. + unsigned RefsUpperBound; + public: - BitcodeReaderMetadataList(LLVMContext &C) : Context(C) {} + BitcodeReaderMetadataList(LLVMContext &C, size_t RefsUpperBound) + : Context(C), + RefsUpperBound(std::min((size_t)std::numeric_limits<unsigned>::max(), + RefsUpperBound)) {} // vector compatibility methods unsigned size() const { return MetadataPtrs.size(); } @@ -218,6 +225,10 @@ void BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) { } Metadata *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) { + // Bail out for a clearly invalid value. + if (Idx >= RefsUpperBound) + return nullptr; + if (Idx >= size()) resize(Idx + 1); @@ -625,9 +636,10 @@ public: BitcodeReaderValueList &ValueList, std::function<Type *(unsigned)> getTypeByID, bool IsImporting) - : MetadataList(TheModule.getContext()), ValueList(ValueList), - Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule), - getTypeByID(std::move(getTypeByID)), IsImporting(IsImporting) {} + : MetadataList(TheModule.getContext(), Stream.SizeInBytes()), + ValueList(ValueList), Stream(Stream), Context(TheModule.getContext()), + TheModule(TheModule), getTypeByID(std::move(getTypeByID)), + IsImporting(IsImporting) {} Error parseMetadata(bool ModuleLevel); diff --git a/llvm/lib/Bitcode/Reader/ValueList.cpp b/llvm/lib/Bitcode/Reader/ValueList.cpp index da2d24d103b..431995fd40a 100644 --- a/llvm/lib/Bitcode/Reader/ValueList.cpp +++ b/llvm/lib/Bitcode/Reader/ValueList.cpp @@ -97,6 +97,10 @@ void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx, Type *FullTy) { } Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty) { + // Bail out for a clearly invalid value. + if (Idx >= RefsUpperBound) + return nullptr; + if (Idx >= size()) resize(Idx + 1); @@ -114,8 +118,8 @@ Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, Type *Ty) { Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty, Type **FullTy) { - // Bail out for a clearly invalid value. This would make us call resize(0) - if (Idx == std::numeric_limits<unsigned>::max()) + // Bail out for a clearly invalid value. + if (Idx >= RefsUpperBound) return nullptr; if (Idx >= size()) diff --git a/llvm/lib/Bitcode/Reader/ValueList.h b/llvm/lib/Bitcode/Reader/ValueList.h index 1c54911650f..49900498c29 100644 --- a/llvm/lib/Bitcode/Reader/ValueList.h +++ b/llvm/lib/Bitcode/Reader/ValueList.h @@ -46,8 +46,15 @@ class BitcodeReaderValueList { ResolveConstantsTy ResolveConstants; LLVMContext &Context; + /// Maximum number of valid references. Forward references exceeding the + /// maximum must be invalid. + unsigned RefsUpperBound; + public: - BitcodeReaderValueList(LLVMContext &C) : Context(C) {} + BitcodeReaderValueList(LLVMContext &C, size_t RefsUpperBound) + : Context(C), + RefsUpperBound(std::min((size_t)std::numeric_limits<unsigned>::max(), + RefsUpperBound)) {} ~BitcodeReaderValueList() { assert(ResolveConstants.empty() && "Constants not resolved?"); |