Index: include/llvm/Bitcode/BitstreamReader.h =================================================================== --- include/llvm/Bitcode/BitstreamReader.h +++ include/llvm/Bitcode/BitstreamReader.h @@ -212,6 +212,8 @@ CurCodeSize = 2; } + size_t MaxChunkSize() { return sizeof(word_t) * 8; } + void freeState(); bool canSkipToPos(size_t pos) const { @@ -335,7 +337,7 @@ } word_t Read(unsigned NumBits) { - static const unsigned BitsInWord = sizeof(word_t) * 8; + static const unsigned BitsInWord = MaxChunkSize(); assert(NumBits && NumBits <= BitsInWord && "Cannot return zero or more than BitsInWord bits!"); Index: lib/Bitcode/Reader/BitstreamReader.cpp =================================================================== --- lib/Bitcode/Reader/BitstreamReader.cpp +++ lib/Bitcode/Reader/BitstreamReader.cpp @@ -60,8 +60,12 @@ case BitCodeAbbrevOp::Blob: llvm_unreachable("Should not reach here"); case BitCodeAbbrevOp::Fixed: + if ((unsigned)Op.getEncodingData() > Cursor.MaxChunkSize()) + report_fatal_error("Invalid record"); return Cursor.Read((unsigned)Op.getEncodingData()); case BitCodeAbbrevOp::VBR: + if ((unsigned)Op.getEncodingData() > Cursor.MaxChunkSize()) + report_fatal_error("Invalid record"); return Cursor.ReadVBR64((unsigned)Op.getEncodingData()); case BitCodeAbbrevOp::Char6: return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6)); @@ -79,9 +83,13 @@ case BitCodeAbbrevOp::Blob: llvm_unreachable("Should not reach here"); case BitCodeAbbrevOp::Fixed: + if ((unsigned)Op.getEncodingData() > Cursor.MaxChunkSize()) + report_fatal_error("Invalid record"); Cursor.Read((unsigned)Op.getEncodingData()); break; case BitCodeAbbrevOp::VBR: + if ((unsigned)Op.getEncodingData() > Cursor.MaxChunkSize()) + report_fatal_error("Invalid record"); Cursor.ReadVBR64((unsigned)Op.getEncodingData()); break; case BitCodeAbbrevOp::Char6: Index: test/Bitcode/invalid.test =================================================================== --- test/Bitcode/invalid.test +++ test/Bitcode/invalid.test @@ -55,3 +55,8 @@ RUN: FileCheck --check-prefix=NO-MODULE %s NO-MODULE: Malformed IR file + +RUN: not llvm-dis -disable-output %p/Inputs/invalid-VBR-too-big.bc 2>&1 | \ +RUN: FileCheck --check-prefix=HUGE-VBR %s + +HUGE-VBR: Invalid record