[llvm] 0ec5f50 - Harden IR and bitcode parsers against infinite size types.
Eli Friedman via llvm-commits
llvm-commits at lists.llvm.org
Sat May 16 14:25:22 PDT 2020
Author: Eli Friedman
Date: 2020-05-16T14:24:51-07:00
New Revision: 0ec5f501964010d4a186a51438338656eebe7912
URL: https://github.com/llvm/llvm-project/commit/0ec5f501964010d4a186a51438338656eebe7912
DIFF: https://github.com/llvm/llvm-project/commit/0ec5f501964010d4a186a51438338656eebe7912.diff
LOG: Harden IR and bitcode parsers against infinite size types.
If isSized is passed a SmallPtrSet, it uses that set to catch infinitely
recursive types (for example, a struct that has itself as a member).
Otherwise, it just crashes on such types.
Added:
llvm/test/Verifier/recursive-type-load.ll
llvm/test/Verifier/recursive-type-store.ll
Modified:
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Removed:
################################################################################
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 13c7eafff381..c0db5884bc37 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -7057,7 +7057,8 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
if (Ty != cast<PointerType>(Val->getType())->getElementType())
return Error(ExplicitTypeLoc,
"explicit pointee type doesn't match operand's pointee type");
- if (!Alignment && !Ty->isSized())
+ SmallPtrSet<Type *, 4> Visited;
+ if (!Alignment && !Ty->isSized(&Visited))
return Error(ExplicitTypeLoc, "loading unsized types is not allowed");
if (!Alignment)
Alignment = M->getDataLayout().getABITypeAlign(Ty);
@@ -7107,7 +7108,8 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) {
if (Ordering == AtomicOrdering::Acquire ||
Ordering == AtomicOrdering::AcquireRelease)
return Error(Loc, "atomic store cannot use Acquire ordering");
- if (!Alignment && !Val->getType()->isSized())
+ SmallPtrSet<Type *, 4> Visited;
+ if (!Alignment && !Val->getType()->isSized(&Visited))
return Error(Loc, "storing unsized types is not allowed");
if (!Alignment)
Alignment = M->getDataLayout().getABITypeAlign(Val->getType());
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index 64427b75d5da..7b62bab3041d 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -4857,7 +4857,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
MaybeAlign Align;
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
return Err;
- if (!Align && !Ty->isSized())
+ SmallPtrSet<Type *, 4> Visited;
+ if (!Align && !Ty->isSized(&Visited))
return error("load of unsized type");
if (!Align)
Align = TheModule->getDataLayout().getABITypeAlign(Ty);
@@ -4922,6 +4923,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
MaybeAlign Align;
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
return Err;
+ SmallPtrSet<Type *, 4> Visited;
+ if (!Align && !Val->getType()->isSized(&Visited))
+ return error("store of unsized type");
if (!Align)
Align = TheModule->getDataLayout().getABITypeAlign(Val->getType());
I = new StoreInst(Val, Ptr, Record[OpNum + 1], *Align);
diff --git a/llvm/test/Verifier/recursive-type-load.ll b/llvm/test/Verifier/recursive-type-load.ll
new file mode 100644
index 000000000000..6a4215d815f4
--- /dev/null
+++ b/llvm/test/Verifier/recursive-type-load.ll
@@ -0,0 +1,12 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+%rt2 = type { i32, { i8, %rt2, i8 }, i32 }
+
+define i32 @f(%rt2* %p) nounwind {
+entry:
+ ; Check that recursive types trigger an error instead of segfaulting, when
+ ; the recursion isn't through a pointer to the type.
+ ; CHECK: loading unsized types is not allowed
+ %0 = load %rt2, %rt2* %p
+ ret i32 %0
+}
diff --git a/llvm/test/Verifier/recursive-type-store.ll b/llvm/test/Verifier/recursive-type-store.ll
new file mode 100644
index 000000000000..1756b0678d6a
--- /dev/null
+++ b/llvm/test/Verifier/recursive-type-store.ll
@@ -0,0 +1,12 @@
+; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
+
+%rt2 = type { i32, { i8, %rt2, i8 }, i32 }
+
+define void @f(%rt2 %r, %rt2 *%p) nounwind {
+entry:
+ ; Check that recursive types trigger an error instead of segfaulting, when
+ ; the recursion isn't through a pointer to the type.
+ ; CHECK: storing unsized types is not allowed
+ store %rt2 %r, %rt2 *%p
+ ret void
+}
More information about the llvm-commits
mailing list