diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-05-27 18:44:32 +0000 | 
| commit | 5a5ac124e1efaf208671f01c46edb15f29ed2a0b (patch) | |
| tree | a6140557876943cdd800ee997c9317283394b22c /lib/Bitcode/Reader/BitstreamReader.cpp | |
| parent | f03b5bed27d0d2eafd68562ce14f8b5e3f1f0801 (diff) | |
Notes
Diffstat (limited to 'lib/Bitcode/Reader/BitstreamReader.cpp')
| -rw-r--r-- | lib/Bitcode/Reader/BitstreamReader.cpp | 40 | 
1 files changed, 32 insertions, 8 deletions
| diff --git a/lib/Bitcode/Reader/BitstreamReader.cpp b/lib/Bitcode/Reader/BitstreamReader.cpp index 5e3232e531351..a103fbdf4a93a 100644 --- a/lib/Bitcode/Reader/BitstreamReader.cpp +++ b/lib/Bitcode/Reader/BitstreamReader.cpp @@ -39,15 +39,16 @@ bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) {    // Get the codesize of this block.    CurCodeSize = ReadVBR(bitc::CodeLenWidth); +  // We can't read more than MaxChunkSize at a time +  if (CurCodeSize > MaxChunkSize) +    return true; +    SkipToFourByteBoundary();    unsigned NumWords = Read(bitc::BlockSizeWidth);    if (NumWordsP) *NumWordsP = NumWords;    // Validate that this block is sane. -  if (CurCodeSize == 0 || AtEndOfStream()) -    return true; - -  return false; +  return CurCodeSize == 0 || AtEndOfStream();  }  static uint64_t readAbbreviatedField(BitstreamCursor &Cursor, @@ -60,8 +61,10 @@ static uint64_t readAbbreviatedField(BitstreamCursor &Cursor,    case BitCodeAbbrevOp::Blob:      llvm_unreachable("Should not reach here");    case BitCodeAbbrevOp::Fixed: +    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);      return Cursor.Read((unsigned)Op.getEncodingData());    case BitCodeAbbrevOp::VBR: +    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);      return Cursor.ReadVBR64((unsigned)Op.getEncodingData());    case BitCodeAbbrevOp::Char6:      return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6)); @@ -79,9 +82,11 @@ static void skipAbbreviatedField(BitstreamCursor &Cursor,    case BitCodeAbbrevOp::Blob:      llvm_unreachable("Should not reach here");    case BitCodeAbbrevOp::Fixed: +    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);      Cursor.Read((unsigned)Op.getEncodingData());      break;    case BitCodeAbbrevOp::VBR: +    assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize);      Cursor.ReadVBR64((unsigned)Op.getEncodingData());      break;    case BitCodeAbbrevOp::Char6: @@ -170,8 +175,12 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,    unsigned Code;    if (CodeOp.isLiteral())      Code = CodeOp.getLiteralValue(); -  else +  else { +    if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array || +        CodeOp.getEncoding() == BitCodeAbbrevOp::Blob) +      report_fatal_error("Abbreviation starts with an Array or a Blob");      Code = readAbbreviatedField(*this, CodeOp); +  }    for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) {      const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); @@ -191,8 +200,15 @@ unsigned BitstreamCursor::readRecord(unsigned AbbrevID,        unsigned NumElts = ReadVBR(6);        // Get the element encoding. -      assert(i+2 == e && "array op not second to last?"); +      if (i + 2 != e) +        report_fatal_error("Array op not second to last");        const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); +      if (!EltEnc.isEncoding()) +        report_fatal_error( +            "Array element type has to be an encoding of a type"); +      if (EltEnc.getEncoding() == BitCodeAbbrevOp::Array || +          EltEnc.getEncoding() == BitCodeAbbrevOp::Blob) +        report_fatal_error("Array element type can't be an Array or a Blob");        // Read all the elements.        for (; NumElts; --NumElts) @@ -241,7 +257,7 @@ void BitstreamCursor::ReadAbbrevRecord() {    BitCodeAbbrev *Abbv = new BitCodeAbbrev();    unsigned NumOpInfo = ReadVBR(5);    for (unsigned i = 0; i != NumOpInfo; ++i) { -    bool IsLiteral = Read(1) ? true : false; +    bool IsLiteral = Read(1);      if (IsLiteral) {        Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8)));        continue; @@ -249,7 +265,7 @@ void BitstreamCursor::ReadAbbrevRecord() {      BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3);      if (BitCodeAbbrevOp::hasEncodingData(E)) { -      unsigned Data = ReadVBR64(5); +      uint64_t Data = ReadVBR64(5);        // As a special case, handle fixed(0) (i.e., a fixed field with zero bits)        // and vbr(0) as a literal zero.  This is decoded the same way, and avoids @@ -260,10 +276,18 @@ void BitstreamCursor::ReadAbbrevRecord() {          continue;        } +      if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) && +          Data > MaxChunkSize) +        report_fatal_error( +            "Fixed or VBR abbrev record with size > MaxChunkData"); +        Abbv->Add(BitCodeAbbrevOp(E, Data));      } else        Abbv->Add(BitCodeAbbrevOp(E));    } + +  if (Abbv->getNumOperandInfos() == 0) +    report_fatal_error("Abbrev record with no operands");    CurAbbrevs.push_back(Abbv);  } | 
