summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Bitstream/BitstreamReader.h8
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp2
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp20
-rw-r--r--llvm/lib/Bitcode/Reader/ValueList.cpp8
-rw-r--r--llvm/lib/Bitcode/Reader/ValueList.h9
-rw-r--r--llvm/test/Bitcode/pr18704.ll2
6 files changed, 38 insertions, 11 deletions
diff --git a/llvm/include/llvm/Bitstream/BitstreamReader.h b/llvm/include/llvm/Bitstream/BitstreamReader.h
index ccb4a492b9d..ee82e7ec1ba 100644
--- a/llvm/include/llvm/Bitstream/BitstreamReader.h
+++ b/llvm/include/llvm/Bitstream/BitstreamReader.h
@@ -294,6 +294,9 @@ public:
BitsInCurWord = 0;
}
+ /// Return the size of the stream in bytes.
+ size_t SizeInBytes() const { return BitcodeBytes.size(); }
+
/// Skip to the end of the file.
void skipToEnd() { NextChar = BitcodeBytes.size(); }
};
@@ -364,17 +367,18 @@ public:
explicit BitstreamCursor(MemoryBufferRef BitcodeBytes)
: SimpleBitstreamCursor(BitcodeBytes) {}
- using SimpleBitstreamCursor::canSkipToPos;
using SimpleBitstreamCursor::AtEndOfStream;
+ using SimpleBitstreamCursor::canSkipToPos;
+ using SimpleBitstreamCursor::fillCurWord;
using SimpleBitstreamCursor::getBitcodeBytes;
using SimpleBitstreamCursor::GetCurrentBitNo;
using SimpleBitstreamCursor::getCurrentByteNo;
using SimpleBitstreamCursor::getPointerToByte;
using SimpleBitstreamCursor::JumpToBit;
- using SimpleBitstreamCursor::fillCurWord;
using SimpleBitstreamCursor::Read;
using SimpleBitstreamCursor::ReadVBR;
using SimpleBitstreamCursor::ReadVBR64;
+ using SimpleBitstreamCursor::SizeInBytes;
/// Return the number of bits used to encode an abbrev #.
unsigned getAbbrevIDWidth() const { return CurCodeSize; }
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?");
diff --git a/llvm/test/Bitcode/pr18704.ll b/llvm/test/Bitcode/pr18704.ll
index e57ce3cec4c..1f1abfaab94 100644
--- a/llvm/test/Bitcode/pr18704.ll
+++ b/llvm/test/Bitcode/pr18704.ll
@@ -1,6 +1,6 @@
; RUN: not llvm-dis < %s.bc 2>&1 | FileCheck %s
-; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Never resolved value found in function
+; CHECK: llvm-dis{{(\.EXE|\.exe)?}}: error: Invalid record
; pr18704.ll.bc has an instruction referring to invalid type.
; The test checks that LLVM reports the error and doesn't access freed memory
OpenPOWER on IntegriCloud