[llvm] [BPF] Fix out-of-bounds write in fillGenericConstant (PR #203759)

Quanye Yang via llvm-commits llvm-commits at lists.llvm.org
Sun Jun 14 03:19:43 PDT 2026


https://github.com/quanyeyang created https://github.com/llvm/llvm-project/pull/203759

Fixes #187756
Check that Offset + Size fits within Vals before writing bytes.
Without this, malformed constant globals with overflowing layout
sizes could cause a vector index out-of-bounds in PreprocessLoad.


>From 9f591c0612a7a5b9416352ce7190eb271011c334 Mon Sep 17 00:00:00 2001
From: quanyeyang <quanyemostima at gmail.com>
Date: Sun, 14 Jun 2026 18:17:03 +0800
Subject: [PATCH] [BPF] Fix out-of-bounds write in fillGenericConstant

Signed-off-by: quanyeyang <quanyemostima at gmail.com>
---
 llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp         |  9 +++++++--
 .../CodeGen/BPF/constant-load-large-offset.ll   | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 2 deletions(-)
 create mode 100644 llvm/test/CodeGen/BPF/constant-load-large-offset.ll

diff --git a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
index af034b134e632..5c7aad631cd4a 100644
--- a/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
+++ b/llvm/lib/Target/BPF/BPFISelDAGToDAG.cpp
@@ -26,6 +26,7 @@
 #include "llvm/Support/Endian.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
+#include <cstdint>
 
 using namespace llvm;
 
@@ -397,6 +398,10 @@ bool BPFDAGToDAGISel::fillGenericConstant(const DataLayout &DL,
                                           val_vec_type &Vals, uint64_t Offset) {
   uint64_t Size = DL.getTypeAllocSize(CV->getType());
 
+  uint64_t ValsSize = Vals.size();
+  if (Offset > ValsSize || Size > ValsSize - Offset)
+    return false;
+
   if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
     return true; // already done
 
@@ -491,8 +496,8 @@ void BPFDAGToDAGISel::PreprocessTrunc(SDNode *Node,
         (IntNo == Intrinsic::bpf_load_word && MaskV == 0xFFFFFFFF)))
     return;
 
-  LLVM_DEBUG(dbgs() << "Remove the redundant AND operation in: ";
-             Node->dump(); dbgs() << '\n');
+  LLVM_DEBUG(dbgs() << "Remove the redundant AND operation in: "; Node->dump();
+             dbgs() << '\n');
 
   I--;
   CurDAG->ReplaceAllUsesWith(SDValue(Node, 0), BaseV);
diff --git a/llvm/test/CodeGen/BPF/constant-load-large-offset.ll b/llvm/test/CodeGen/BPF/constant-load-large-offset.ll
new file mode 100644
index 0000000000000..bada8196bc53a
--- /dev/null
+++ b/llvm/test/CodeGen/BPF/constant-load-large-offset.ll
@@ -0,0 +1,17 @@
+; Regression test for https://github.com/llvm/llvm-project/issues/187756
+; RUN: llc -mtriple=bpf < %s | FileCheck %s
+target datalayout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
+target triple = "bpf"
+
+%elem = type { [3735923519 x i8], i8, [1152921500870923457 x i8] }
+
+ at g = constant [16 x %elem] [%elem { [3735923519 x i8] zeroinitializer, i8 42, [1152921500870923457 x i8] zeroinitializer }, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer, %elem zeroinitializer]
+
+define i8 @test() {
+entry:
+  %v = load i8, ptr @g, align 1
+  ret i8 %v
+; CHECK-LABEL: test:
+; CHECK: r1 = g
+; CHECK: w0 = *(u8 *)(r1 + 0)
+}



More information about the llvm-commits mailing list