[llvm] [LLVM][Verifier] Fix buffer overflow when verifying gc.statepoint (PR #208278)

Tulio Magno Quites Machado Filho via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 8 10:52:53 PDT 2026


https://github.com/tuliom created https://github.com/llvm/llvm-project/pull/208278

When a negative base index is passed, the verification detects the out-of-bounds value and start printing information that helps to identify what caused the error. In order to print all the information, it tries to dereference the Base pointer at
GCRelocateInst::getBasePtr(), causing the buffer overflow. Avoid this by stop printing all the information, leaving just the initial error message, i.e.:

gc.relocate: statepoint base|derived index out of bounds

Improve the test in order to validate negative values passed as indexes. They're based on the reproducer from issue #199191.

Fixes #199191

>From 03fc1c797b94e806d0124544c026fe035acd6d33 Mon Sep 17 00:00:00 2001
From: Tulio Magno Quites Machado Filho <tuliom at redhat.com>
Date: Wed, 8 Jul 2026 13:41:14 -0300
Subject: [PATCH] [LLVM][Verifier] Fix buffer overflow when verifying
 gc.statepoint

When a negative base index is passed, the verification detects the
out-of-bounds value and start printing information that helps to
identify what caused the error. In order to print all the information,
it tries to dereference the Base pointer at
GCRelocateInst::getBasePtr(), causing the buffer overflow.
Avoid this by stop printing all the information, leaving just the
initial error message, i.e.:

gc.relocate: statepoint base|derived index out of bounds

Improve the test in order to validate negative values passed as indexes.
They're based on the reproducer from issue #199191.

Fixes #199191
---
 llvm/lib/IR/Verifier.cpp                        |  6 ++++--
 llvm/test/Verifier/gc_relocate_out_of_bounds.ll | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index f605af1d0a31b..b0d4957211b3e 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -6421,10 +6421,12 @@ void Verifier::visitIntrinsicCall(Intrinsic::ID ID, CallBase &Call) {
       break;
     if (auto Opt = cast<GCStatepointInst>(StatepointCall)
                        .getOperandBundle(LLVMContext::OB_gc_live)) {
+      // Avoid printing extra information as that would cause the Base or
+      // Derived pointers to get read, causing an out-of-bounds access.
       Check(BaseIndex < Opt->Inputs.size(),
-            "gc.relocate: statepoint base index out of bounds", Call);
+            "gc.relocate: statepoint base index out of bounds");
       Check(DerivedIndex < Opt->Inputs.size(),
-            "gc.relocate: statepoint derived index out of bounds", Call);
+            "gc.relocate: statepoint derived index out of bounds");
     }
 
     // Relocated value must be either a pointer type or vector-of-pointer type,
diff --git a/llvm/test/Verifier/gc_relocate_out_of_bounds.ll b/llvm/test/Verifier/gc_relocate_out_of_bounds.ll
index 86a1d0d685200..1c391307f5779 100644
--- a/llvm/test/Verifier/gc_relocate_out_of_bounds.ll
+++ b/llvm/test/Verifier/gc_relocate_out_of_bounds.ll
@@ -17,3 +17,19 @@ entry:
   %reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token,  i32 0, i32 1)
   ret ptr addrspace(1) %reloc
 }
+
+; CHECK: gc.relocate: statepoint base index out of bounds
+define ptr addrspace(1) @test3(ptr addrspace(1) %a) gc "statepoint-example" {
+entry:
+  %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]
+  %reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token,  i32 -1, i32 0)
+  ret ptr addrspace(1) %reloc
+}
+
+; CHECK: gc.relocate: statepoint derived index out of bounds
+define ptr addrspace(1) @test4(ptr addrspace(1) %a) gc "statepoint-example" {
+entry:
+  %safepoint_token = tail call token (i64, i32, ptr, i32, i32, ...) @llvm.experimental.gc.statepoint.p0(i64 0, i32 0, ptr elementtype(void ()) @foo, i32 0, i32 0, i32 0, i32 0) ["gc-live" (ptr addrspace(1) %a)]
+  %reloc = call ptr addrspace(1) @llvm.experimental.gc.relocate.p1(token %safepoint_token,  i32 0, i32 -1)
+  ret ptr addrspace(1) %reloc
+}



More information about the llvm-commits mailing list