[Bitcode] Diagnose errors instead of asserting from bad input
authorFilipe Cabecinhas <me@filcab.net>
Sat, 24 Jan 2015 04:15:05 +0000 (04:15 +0000)
committerFilipe Cabecinhas <me@filcab.net>
Sat, 24 Jan 2015 04:15:05 +0000 (04:15 +0000)
Eventually we can make some of these pass the error along to the caller.

Reports a fatal error if:
We find an invalid abbrev record
We try to get an invalid abbrev number
We can't fill the current word due to an EOF

Fixed an invalid bitcode test to check for output with FileCheck

Bugs found with afl-fuzz

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226986 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Bitcode/BitstreamReader.h
lib/Bitcode/Reader/BitstreamReader.cpp
test/Bitcode/Inputs/invalid-abbrev.bc [new file with mode: 0644]
test/Bitcode/Inputs/invalid-bad-abbrev-number.bc [new file with mode: 0644]
test/Bitcode/Inputs/invalid-unexpected-eof.bc [new file with mode: 0644]
test/Bitcode/invalid.test

index 865a3e66842889428f43a3a9cf9df1ed74949e88..bc3e48a43416b2f5347e1d701c8140a524db9aec 100644 (file)
@@ -315,7 +315,8 @@ public:
   }
 
   void fillCurWord() {
-    assert(Size == 0 || NextChar < (unsigned)Size);
+    if (Size != 0 && NextChar >= (unsigned)Size)
+      report_fatal_error("Unexpected end of file");
 
     // Read the next word from the stream.
     uint8_t Array[sizeof(word_t)] = {0};
@@ -490,11 +491,11 @@ private:
   //===--------------------------------------------------------------------===//
 
 public:
-
   /// Return the abbreviation for the specified AbbrevId.
   const BitCodeAbbrev *getAbbrev(unsigned AbbrevID) {
-    unsigned AbbrevNo = AbbrevID-bitc::FIRST_APPLICATION_ABBREV;
-    assert(AbbrevNo < CurAbbrevs.size() && "Invalid abbrev #!");
+    unsigned AbbrevNo = AbbrevID - bitc::FIRST_APPLICATION_ABBREV;
+    if (AbbrevNo >= CurAbbrevs.size())
+      report_fatal_error("Invalid abbrev number");
     return CurAbbrevs[AbbrevNo].get();
   }
 
index 5e3232e531351ef66f0e6d0f90f587b94c95dc27..9d5fab9147a7605e32e4209068f30a12dcb65c7c 100644 (file)
@@ -170,8 +170,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);
diff --git a/test/Bitcode/Inputs/invalid-abbrev.bc b/test/Bitcode/Inputs/invalid-abbrev.bc
new file mode 100644 (file)
index 0000000..4e8f394
Binary files /dev/null and b/test/Bitcode/Inputs/invalid-abbrev.bc differ
diff --git a/test/Bitcode/Inputs/invalid-bad-abbrev-number.bc b/test/Bitcode/Inputs/invalid-bad-abbrev-number.bc
new file mode 100644 (file)
index 0000000..e4e1fb3
--- /dev/null
@@ -0,0 +1 @@
+BCÀÞ!0000000\ 6000
\ No newline at end of file
diff --git a/test/Bitcode/Inputs/invalid-unexpected-eof.bc b/test/Bitcode/Inputs/invalid-unexpected-eof.bc
new file mode 100644 (file)
index 0000000..a487393
--- /dev/null
@@ -0,0 +1 @@
+BCÀÞ!\f000000\v00000000000000
\ No newline at end of file
index 5f88da45f6a9046ac643144a09a454c2a5fa1ebc..19ef3267cc6627981f94d42c6857831070c98506 100644 (file)
@@ -1 +1,13 @@
-RUN: not llvm-dis -disable-output %p/Inputs/invalid-pr20485.bc
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-pr20485.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=INVALID-ENCODING %s
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-abbrev.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=BAD-ABBREV %s
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-unexpected-eof.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=UNEXPECTED-EOF %s
+RUN: not llvm-dis -disable-output %p/Inputs/invalid-bad-abbrev-number.bc 2>&1 | \
+RUN:   FileCheck --check-prefix=BAD-ABBREV-NUMBER %s
+
+INVALID-ENCODING: Invalid encoding
+BAD-ABBREV: Abbreviation starts with an Array or a Blob
+UNEXPECTED-EOF: Unexpected end of file
+BAD-ABBREV-NUMBER: Invalid abbrev number