[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