[clang] [analyzer] Fix nullptr dereference for symbols from pointer invalidation (PR #106568)

Arseniy Zaostrovnykh via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 29 08:23:51 PDT 2024


https://github.com/necto updated https://github.com/llvm/llvm-project/pull/106568

>From 71aae8d0cc96d389da95c2231b1145b7ffeb2132 Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Thu, 29 Aug 2024 16:39:12 +0200
Subject: [PATCH 1/2] [analyzer] Fix nullptr dereference for symbols from
 pointer invalidation

As reported in https://github.com/llvm/llvm-project/pull/105648#issuecomment-2317144635
commit 08ad8dc7154bf3ab79f750e6d5fb7df597c7601a
introduced a nullptr dereference in the case when store contains a binding
to a symbol that has no origin region associated with it,
such as the symbol generated when a pointer is passed to an opaque function.
---
 .../Checkers/StackAddrEscapeChecker.cpp       |  5 ++++-
 clang/test/Analysis/stack-addr-ps.c           | 19 +++++++++++++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index 20232405d572d2..d3b185541729d3 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -308,7 +308,10 @@ static const MemSpaceRegion *getStackOrGlobalSpaceRegion(const MemRegion *R) {
 const MemRegion *getOriginBaseRegion(const MemRegion *Reg) {
   Reg = Reg->getBaseRegion();
   while (const auto *SymReg = dyn_cast<SymbolicRegion>(Reg)) {
-    Reg = SymReg->getSymbol()->getOriginRegion()->getBaseRegion();
+    const auto* OriginReg = SymReg->getSymbol()->getOriginRegion();
+    if (!OriginReg)
+      break;
+    Reg = OriginReg->getBaseRegion();
   }
   return Reg;
 }
diff --git a/clang/test/Analysis/stack-addr-ps.c b/clang/test/Analysis/stack-addr-ps.c
index 138b8c16b02bde..f47529623a6f57 100644
--- a/clang/test/Analysis/stack-addr-ps.c
+++ b/clang/test/Analysis/stack-addr-ps.c
@@ -126,3 +126,22 @@ void caller_for_nested_leaking() {
   int *ptr = 0;
   caller_mid_for_nested_leaking(&ptr);
 }
+
+// This used to crash StackAddrEscapeChecker because
+// it features a symbol conj_$1{struct c *, LC1, S763, #1}
+// that has no origin region.
+// bbi-98571
+struct a {
+  int member;
+};
+
+struct c {
+  struct a *nested_ptr;
+};
+long global_var;
+void opaque(struct c*);
+void bbi_98571_no_crash() {
+  struct c *ptr = (struct c *)global_var;
+  opaque(ptr);
+  ptr->nested_ptr->member++;
+}

>From dcd5ade96e45c4a2e86b7886a430e12f2b6e096f Mon Sep 17 00:00:00 2001
From: Arseniy Zaostrovnykh <necto.ne at gmail.com>
Date: Thu, 29 Aug 2024 17:23:16 +0200
Subject: [PATCH 2/2] [NFC] Fix the code format

---
 clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
index d3b185541729d3..ec577c36188e6c 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StackAddrEscapeChecker.cpp
@@ -308,7 +308,7 @@ static const MemSpaceRegion *getStackOrGlobalSpaceRegion(const MemRegion *R) {
 const MemRegion *getOriginBaseRegion(const MemRegion *Reg) {
   Reg = Reg->getBaseRegion();
   while (const auto *SymReg = dyn_cast<SymbolicRegion>(Reg)) {
-    const auto* OriginReg = SymReg->getSymbol()->getOriginRegion();
+    const auto *OriginReg = SymReg->getSymbol()->getOriginRegion();
     if (!OriginReg)
       break;
     Reg = OriginReg->getBaseRegion();



More information about the cfe-commits mailing list