[clang] [codegen] Fix crash in codegan caused by pointer calculation overflow (PR #115791)

via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 11 16:10:37 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: None (vabridgers)

<details>
<summary>Changes</summary>

Fixes https://github.com/llvm/llvm-project/issues/48168

Under certain conditions, the front end does not detect a possible overflow address calculations until codegen. This change emits a warning instead of allowing the compiler to crash.

```
clang: <root>/clang/lib/CodeGen/CGExprScalar.cpp:5834: llvm::Value* clang::CodeGen::CodeGenFunction::EmitCheckedInBoundsGEP(
    llvm::Type*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, bool, bool, clang::SourceLocation, const llvm::Twine&):
    Assertion `(!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) || EvaluatedGEP.OffsetOverflows == Builder.getFalse())
    && "If the offset got constant-folded, we don't expect that there was an " "overflow."' failed.

0.      Program arguments: clang -c --target=x86_64-- -fsanitize=undefined ubsan-emit-bounds-check-crash-x86.c
1.      <eof> parser at end of file
2.      ubsan-emit-bounds-check-crash-x86.c:4:5: LLVM IR generation of declaration 'main'
3.      ubsan-emit-bounds-check-crash-x86.c:4:5: Generating code for declaration 'main'
...
 #<!-- -->9 <addr> clang::CodeGen::CodeGenFunction::EmitCheckedInBoundsGEP(clang::CodeGen::Address,
             llvm::ArrayRef<llvm::Value*>, llvm::Type*, bool, bool, clang::SourceLocation,
             clang::CharUnits, llvm::Twine const&)
             llvm::ArrayRef<llvm::Value*>, clang::QualType, bool, bool, clang::SourceLocation,
             clang::QualType*, clang::Expr const*, llvm::Twine const&) CGExpr.cpp:0:0
             bool)
```

---
Full diff: https://github.com/llvm/llvm-project/pull/115791.diff


3 Files Affected:

- (modified) clang/lib/CodeGen/CGExprScalar.cpp (+9-4) 
- (added) clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c (+7) 
- (added) clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c (+7) 


``````````diff
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 287d911e10ba58..5ed865820a9151 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -5831,10 +5831,15 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr,
   GEPOffsetAndOverflow EvaluatedGEP =
       EmitGEPOffsetInBytes(Ptr, GEPVal, getLLVMContext(), CGM, Builder);
 
-  assert((!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
-          EvaluatedGEP.OffsetOverflows == Builder.getFalse()) &&
-         "If the offset got constant-folded, we don't expect that there was an "
-         "overflow.");
+  if (!(!isa<llvm::Constant>(EvaluatedGEP.TotalOffset) ||
+        EvaluatedGEP.OffsetOverflows == Builder.getFalse())) {
+    DiagnosticsEngine &Diags = CGM.getDiags();
+    unsigned DiagID = Diags.getCustomDiagID(
+        DiagnosticsEngine::Error, "Expression caused pointer calculation "
+                                  "overflow during code generation");
+    Diags.Report(Loc, DiagID);
+    return GEPVal;
+  }
 
   auto *Zero = llvm::ConstantInt::getNullValue(IntPtrTy);
 
diff --git a/clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c
new file mode 100644
index 00000000000000..b4da2f2b7ee720
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c
@@ -0,0 +1,7 @@
+// REQUIRES: msp430-registered-target
+// RUN: %clang -c -fsanitize=undefined -Wno-tentative-definition-array -Wno-return-type -Wno-unused-value -Wno-array-bounds -Xclang -verify --target=msp430-- %s
+int a;
+_Complex double b[1][1];
+void c(void) {
+  b[a][8920]; // expected-error {{Expression caused pointer calculation overflow during code generation}}
+}
diff --git a/clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c
new file mode 100644
index 00000000000000..63bda82c14ae20
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c
@@ -0,0 +1,7 @@
+// REQUIRES: x86-registered-target
+// RUN: %clang -c -Wno-tentative-definition-array -Wno-return-type -Wno-unused-value -Wno-array-bounds -Xclang -verify --target=x86_64-- -fsanitize=undefined %s 
+int **a[];
+int main() {
+  (*a)[3300220222222200000]; // expected-error {{Expression caused pointer calculation overflow during code generation}}
+  return 0;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/115791


More information about the cfe-commits mailing list