[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:04 PST 2024
https://github.com/vabridgers created https://github.com/llvm/llvm-project/pull/115791
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)
```
>From 90d95dd89a9c2f7b8c8b71c1042ad61d0a6e6729 Mon Sep 17 00:00:00 2001
From: Vince Bridgers <vince.a.bridgers at ericsson.com>
Date: Tue, 12 Nov 2024 00:56:14 +0100
Subject: [PATCH] [codegen] Fix crash in codegan caused by pointer calculation
overflow
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)
---
clang/lib/CodeGen/CGExprScalar.cpp | 13 +++++++++----
.../CodeGen/ubsan-emit-bounds-check-crash-msp.c | 7 +++++++
.../CodeGen/ubsan-emit-bounds-check-crash-x86.c | 7 +++++++
3 files changed, 23 insertions(+), 4 deletions(-)
create mode 100644 clang/test/CodeGen/ubsan-emit-bounds-check-crash-msp.c
create mode 100644 clang/test/CodeGen/ubsan-emit-bounds-check-crash-x86.c
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;
+}
More information about the cfe-commits
mailing list