Fix an issue in the verifier where we could try to read information out of a malforme...
authorOwen Anderson <resistor@mac.com>
Tue, 10 Mar 2015 05:58:21 +0000 (05:58 +0000)
committerOwen Anderson <resistor@mac.com>
Tue, 10 Mar 2015 05:58:21 +0000 (05:58 +0000)
In this situation we would always have already flagged an error on the statepoint intrinsic,
but then we carry on to parse other, related GC intrinsics, and could end up crashing during that
verification when they try to access data from the malformed statepoint.

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

lib/IR/Verifier.cpp
test/Verifier/invalid-statepoint.ll [new file with mode: 0644]

index 06104d54cbacb9d1a0d09ab61bcc9f3c25e4a3df..10f934bedac251151bdf41c7a60b0c2dc880684f 100644 (file)
@@ -2969,8 +2969,12 @@ void Verifier::visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI) {
 
     // Check that BaseIndex and DerivedIndex fall within the 'gc parameters'
     // section of the statepoint's argument
-    const int NumCallArgs =
+    Assert(StatepointCS.arg_size() > 0,
+           "gc.statepoint: insufficient arguments");
+    const unsigned NumCallArgs =
       cast<ConstantInt>(StatepointCS.getArgument(1))->getZExtValue();
+    Assert(StatepointCS.arg_size() > NumCallArgs+3,
+           "gc.statepoint: mismatch in number of call arguments");
     const int NumDeoptArgs =
       cast<ConstantInt>(StatepointCS.getArgument(NumCallArgs + 3))->getZExtValue();
     const int GCParamArgsStart = NumCallArgs + NumDeoptArgs + 4;
diff --git a/test/Verifier/invalid-statepoint.ll b/test/Verifier/invalid-statepoint.ll
new file mode 100644 (file)
index 0000000..7000973
--- /dev/null
@@ -0,0 +1,20 @@
+; RUN: not opt -verify 2>&1 < %s | FileCheck %s
+
+; CHECK: gc.statepoint: mismatch in number of call arguments 
+
+declare zeroext i1 @return0i1()
+
+; Function Attrs: nounwind
+declare i32 @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()*, i32, i32, ...) #0
+
+; Function Attrs: nounwind
+declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32) #0
+
+define i32 addrspace(1)* @0(i32 addrspace(1)* %dparam) {
+  %a00 = load i32, i32 addrspace(1)* %dparam
+  %to0 = call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f0i1f(i1 ()* @return0i1, i32 9, i32 0, i2 0, i32 addrspace(1)* %dparam)
+  %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %to0, i32 0, i32 4)
+  ret i32 addrspace(1)* %relocate
+}
+
+attributes #0 = { nounwind }