Skip to content

Commit 0ec5f50

Browse files
committed
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.
1 parent accd9af commit 0ec5f50

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7057,7 +7057,8 @@ int LLParser::ParseLoad(Instruction *&Inst, PerFunctionState &PFS) {
70577057
if (Ty != cast<PointerType>(Val->getType())->getElementType())
70587058
return Error(ExplicitTypeLoc,
70597059
"explicit pointee type doesn't match operand's pointee type");
7060-
if (!Alignment && !Ty->isSized())
7060+
SmallPtrSet<Type *, 4> Visited;
7061+
if (!Alignment && !Ty->isSized(&Visited))
70617062
return Error(ExplicitTypeLoc, "loading unsized types is not allowed");
70627063
if (!Alignment)
70637064
Alignment = M->getDataLayout().getABITypeAlign(Ty);
@@ -7107,7 +7108,8 @@ int LLParser::ParseStore(Instruction *&Inst, PerFunctionState &PFS) {
71077108
if (Ordering == AtomicOrdering::Acquire ||
71087109
Ordering == AtomicOrdering::AcquireRelease)
71097110
return Error(Loc, "atomic store cannot use Acquire ordering");
7110-
if (!Alignment && !Val->getType()->isSized())
7111+
SmallPtrSet<Type *, 4> Visited;
7112+
if (!Alignment && !Val->getType()->isSized(&Visited))
71117113
return Error(Loc, "storing unsized types is not allowed");
71127114
if (!Alignment)
71137115
Alignment = M->getDataLayout().getABITypeAlign(Val->getType());

llvm/lib/Bitcode/Reader/BitcodeReader.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4857,7 +4857,8 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
48574857
MaybeAlign Align;
48584858
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
48594859
return Err;
4860-
if (!Align && !Ty->isSized())
4860+
SmallPtrSet<Type *, 4> Visited;
4861+
if (!Align && !Ty->isSized(&Visited))
48614862
return error("load of unsized type");
48624863
if (!Align)
48634864
Align = TheModule->getDataLayout().getABITypeAlign(Ty);
@@ -4922,6 +4923,9 @@ Error BitcodeReader::parseFunctionBody(Function *F) {
49224923
MaybeAlign Align;
49234924
if (Error Err = parseAlignmentValue(Record[OpNum], Align))
49244925
return Err;
4926+
SmallPtrSet<Type *, 4> Visited;
4927+
if (!Align && !Val->getType()->isSized(&Visited))
4928+
return error("store of unsized type");
49254929
if (!Align)
49264930
Align = TheModule->getDataLayout().getABITypeAlign(Val->getType());
49274931
I = new StoreInst(Val, Ptr, Record[OpNum + 1], *Align);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
%rt2 = type { i32, { i8, %rt2, i8 }, i32 }
4+
5+
define i32 @f(%rt2* %p) nounwind {
6+
entry:
7+
; Check that recursive types trigger an error instead of segfaulting, when
8+
; the recursion isn't through a pointer to the type.
9+
; CHECK: loading unsized types is not allowed
10+
%0 = load %rt2, %rt2* %p
11+
ret i32 %0
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: not llvm-as %s -o /dev/null 2>&1 | FileCheck %s
2+
3+
%rt2 = type { i32, { i8, %rt2, i8 }, i32 }
4+
5+
define void @f(%rt2 %r, %rt2 *%p) nounwind {
6+
entry:
7+
; Check that recursive types trigger an error instead of segfaulting, when
8+
; the recursion isn't through a pointer to the type.
9+
; CHECK: storing unsized types is not allowed
10+
store %rt2 %r, %rt2 *%p
11+
ret void
12+
}

0 commit comments

Comments
 (0)