From e4564d63bbf5b996a08c8262b8bf7e6c0d7c7be3 Mon Sep 17 00:00:00 2001 From: Filipe Cabecinhas Date: Mon, 16 Feb 2015 00:03:11 +0000 Subject: [PATCH] [Bitcode reader] Fix a few assertions when reading invalid files Summary: When creating {insert,extract}value instructions from a BitcodeReader, we weren't verifying the fields were valid. Bugs found with afl-fuzz Reviewers: rafael Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D7325 llvm-svn: 229345 --- lib/Bitcode/Reader/BitcodeReader.cpp | 32 ++++++++++++++++++ .../Inputs/invalid-extractval-array-idx.bc | Bin 0 -> 450 bytes .../Inputs/invalid-extractval-struct-idx.bc | Bin 0 -> 444 bytes .../invalid-extractval-too-many-idxs.bc | Bin 0 -> 452 bytes .../Inputs/invalid-insertval-array-idx.bc | Bin 0 -> 452 bytes .../Inputs/invalid-insertval-struct-idx.bc | Bin 0 -> 444 bytes .../Inputs/invalid-insertval-too-many-idxs.bc | Bin 0 -> 452 bytes test/Bitcode/invalid.test | 21 ++++++++++++ 8 files changed, 53 insertions(+) create mode 100644 test/Bitcode/Inputs/invalid-extractval-array-idx.bc create mode 100644 test/Bitcode/Inputs/invalid-extractval-struct-idx.bc create mode 100644 test/Bitcode/Inputs/invalid-extractval-too-many-idxs.bc create mode 100644 test/Bitcode/Inputs/invalid-insertval-array-idx.bc create mode 100644 test/Bitcode/Inputs/invalid-insertval-struct-idx.bc create mode 100644 test/Bitcode/Inputs/invalid-insertval-too-many-idxs.bc diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 92a1dcce5bb..4fe054de370 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3065,12 +3065,27 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid record"); SmallVector EXTRACTVALIdx; + Type *CurTy = Agg->getType(); for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("EXTRACTVAL: Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("EXTRACTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("EXTRACTVAL: Invalid array index"); EXTRACTVALIdx.push_back((unsigned)Index); + + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); @@ -3089,12 +3104,29 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { return Error("Invalid record"); SmallVector INSERTVALIdx; + Type *CurTy = Agg->getType(); for (unsigned RecSize = Record.size(); OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return Error("INSERTVAL: Invalid type"); + if (!CurTy->isStructTy() && !CurTy->isArrayTy()) + return Error("Invalid type"); if ((unsigned)Index != Index) return Error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return Error("INSERTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return Error("INSERTVAL: Invalid array index"); + INSERTVALIdx.push_back((unsigned)Index); + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; } I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); diff --git a/test/Bitcode/Inputs/invalid-extractval-array-idx.bc b/test/Bitcode/Inputs/invalid-extractval-array-idx.bc new file mode 100644 index 0000000000000000000000000000000000000000..7465df361c0557e284b7c1388bd194493df00b7b GIT binary patch literal 450 zcmZ>AK5$Qwhk+rFfq{X$Nr8b0NDBcmd!zD1#}h1`Yyw7>lNeigR9QJB}F$U~Vl5k}h%XN#7@Jx&eml@;v8GYWa0 zG4Q_?;QP|RXUyXycj%z(xrH)m2CQIZ&C+L>ZBIDc_AuK5%_vl0U;vpXwn3rS#U+?k zM9&`6j5d{ mF$U6`1)CWd78f33-~;&?AK5$Qwhk+r7fq{X$Nr8b0NDBcmd!zD1#}h1`Yyw7>lNeigR9QJBF7tbiM0?SU_R1NJI`2O4y?em-^#I=+hC&4f za5%FC$Q;>Z!N8CRAK5$Qwhk+rFfq{X$Nr8b0NDBcmd!zD1#}h1`Yyw7>lNeigR9QJB}F$U~Vl5k}h%XN#7@Jx&eml@;v8GYWa0 zG4Q_?;QP|RXUyXycj%z(xrH)m2CQIZ&C+L>ZBIDc_AuK5%_vl0U;vpXwn3rS#U+?k zM9&`6j5d{ oF$U6$6`L6tHVYnN2$0|d`5NRdgxR7%ldh%#O-g~71e62<09fy0xc~qF literal 0 HcmV?d00001 diff --git a/test/Bitcode/Inputs/invalid-insertval-array-idx.bc b/test/Bitcode/Inputs/invalid-insertval-array-idx.bc new file mode 100644 index 0000000000000000000000000000000000000000..79c3c038a1cd0509d443a97de870c0f801e32e07 GIT binary patch literal 452 zcmZ>AK5$Qwhk+rFfq{X$Nr8b0NDBcmd!zD1#}h1`Yyw7>lNeigR9QJB}F$U~Vl5k}h%XN#7@Jx&eml@;v8GYWa0 zG4Q_?;QP|RXUyXycj%z(xrH)m2CQIZ&C+L>ZBIDc_AuK5%_vl0U;vpXwn3rS#U+?k zM9&`6j5d{ nF$U6`1)G6H;UR_q2|kdoLGD7BEebU0Y8ud_6o^ScNgx0KYCmHc literal 0 HcmV?d00001 diff --git a/test/Bitcode/Inputs/invalid-insertval-struct-idx.bc b/test/Bitcode/Inputs/invalid-insertval-struct-idx.bc new file mode 100644 index 0000000000000000000000000000000000000000..ec70384909a6052abcb99e269eb6020b617ba0fc GIT binary patch literal 444 zcmZ>AK5$Qwhk+r7fq{X$Nr8b0NDBcmd!zD1#}h1`Yyw7>lNeigR9QJBF7tbiM0?SU_R1NJI`2O4y?em-^#I=+hC&4f za5%FC$Q;>Z!N8CRAK5$Qwhk+rFfq{X$Nr8b0NDBcmd!zD1#}h1`Yyw7>lNeigR9QJB}F$U~Vl5k}h%XN#7@Jx&eml@;v8GYWa0 zG4Q_?;QP|RXUyXycj%z(xrH)m2CQIZ&C+L>ZBIDc_AuK5%_vl0U;vpXwn3rS#U+?k zM9&`6j5d{ nF$U6`6`O&C;30+p2|kdoLGD7BEebU0Y8ud_6o^ScNgx0KTrXnD literal 0 HcmV?d00001 diff --git a/test/Bitcode/invalid.test b/test/Bitcode/invalid.test index 3eaa0394dba..84bc9278d91 100644 --- a/test/Bitcode/invalid.test +++ b/test/Bitcode/invalid.test @@ -17,3 +17,24 @@ UNEXPECTED-EOF: Unexpected end of file BAD-ABBREV-NUMBER: Invalid abbrev number BAD-TYPE-TABLE-FORWARD-REF: Invalid TYPE table: Only named structs can be forward referenced BAD-BITWIDTH: Bitwidth for integer type out of range + +RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-array-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=EXTRACT-ARRAY %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-struct-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=EXTRACT-STRUCT %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-extractval-too-many-idxs.bc 2>&1 | \ +RUN: FileCheck --check-prefix=EXTRACT-IDXS %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-insertval-array-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=INSERT-ARRAY %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-insertval-struct-idx.bc 2>&1 | \ +RUN: FileCheck --check-prefix=INSERT-STRUCT %s +RUN: not llvm-dis -disable-output %p/Inputs/invalid-insertval-too-many-idxs.bc 2>&1 | \ +RUN: FileCheck --check-prefix=INSERT-IDXS %s + + +EXTRACT-ARRAY: EXTRACTVAL: Invalid array index +EXTRACT-STRUCT: EXTRACTVAL: Invalid struct index +EXTRACT-IDXS: EXTRACTVAL: Invalid type +INSERT-ARRAY: INSERTVAL: Invalid array index +INSERT-STRUCT: INSERTVAL: Invalid struct index +INSERT-IDXS: INSERTVAL: Invalid type