[PATCH] D73151: [analyzer] Fix handle leak false positive when the handle dies too early

Gábor Horváth via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 21 17:44:11 PST 2020


xazax.hun updated this revision to Diff 239469.
xazax.hun added a comment.

- Minor refactoring.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D73151/new/

https://reviews.llvm.org/D73151

Files:
  clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
  clang/test/Analysis/fuchsia_handle.cpp


Index: clang/test/Analysis/fuchsia_handle.cpp
===================================================================
--- clang/test/Analysis/fuchsia_handle.cpp
+++ clang/test/Analysis/fuchsia_handle.cpp
@@ -63,6 +63,14 @@
     zx_handle_close(sa);
 }
 
+void handleDieBeforeErrorSymbol() {
+  zx_handle_t sa, sb;
+  zx_status_t status = zx_channel_create(0, &sa, &sb);
+  if (status < 0)
+    return;
+  __builtin_trap();
+}
+
 void checkNoCrash01() {
   zx_handle_t sa, sb;
   zx_channel_create(0, &sa, &sb);
Index: clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/FuchsiaHandleChecker.cpp
@@ -130,6 +130,9 @@
   static HandleState getEscaped() {
     return HandleState(Kind::Escaped, nullptr);
   }
+  static HandleState getWithoutError(HandleState S) {
+    return HandleState(S.K, nullptr);
+  }
 
   SymbolRef getErrorSym() const { return ErrorSym; }
 
@@ -149,6 +152,10 @@
       CASE(Kind::Released)
       CASE(Kind::Escaped)
     }
+    if (ErrorSym) {
+      OS << " ErrorSym: ";
+      ErrorSym->dumpToStream(OS);
+    }
   }
 
   LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
@@ -160,7 +167,7 @@
 
 class FuchsiaHandleChecker
     : public Checker<check::PostCall, check::PreCall, check::DeadSymbols,
-                     check::PointerEscape, eval::Assume> {
+                     check::LiveSymbols, check::PointerEscape, eval::Assume> {
   BugType LeakBugType{this, "Fuchsia handle leak", "Fuchsia Handle Error",
                       /*SuppressOnSink=*/true};
   BugType DoubleReleaseBugType{this, "Fuchsia handle double release",
@@ -172,6 +179,7 @@
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
+  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const;
   ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond,
                              bool Assumption) const;
   ProgramStateRef checkPointerEscape(ProgramStateRef State,
@@ -381,6 +389,10 @@
   SmallVector<SymbolRef, 2> LeakedSyms;
   HStateMapTy TrackedHandles = State->get<HStateMap>();
   for (auto &CurItem : TrackedHandles) {
+    SymbolRef ErrorSym = CurItem.second.getErrorSym();
+    if (ErrorSym && SymReaper.isDead(ErrorSym))
+      State = State->set<HStateMap>(
+          CurItem.first, HandleState::getWithoutError(CurItem.second));
     if (!SymReaper.isDead(CurItem.first))
       continue;
     if (CurItem.second.isAllocated() || CurItem.second.maybeAllocated())
@@ -395,6 +407,15 @@
   C.addTransition(State, N);
 }
 
+void FuchsiaHandleChecker::checkLiveSymbols(ProgramStateRef State,
+                                            SymbolReaper &SymReaper) const {
+  HStateMapTy TrackedHandles = State->get<HStateMap>();
+  for (auto &CurItem : TrackedHandles) {
+    if (CurItem.second.getErrorSym())
+      SymReaper.markLive(CurItem.first);
+  }
+}
+
 // Acquiring a handle is not always successful. In Fuchsia most functions
 // return a status code that determines the status of the handle.
 // When we split the path based on this status code we know that on one


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D73151.239469.patch
Type: text/x-patch
Size: 3346 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200122/affcdd93/attachment-0001.bin>


More information about the cfe-commits mailing list