[clang] [clang][StaticAnalyzer] Adding getentropy to CStringChecker. (PR #83675)

via cfe-commits cfe-commits at lists.llvm.org
Sat Mar 2 06:58:19 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: David CARLIER (devnexen)

<details>
<summary>Changes</summary>

since it went way beyond just openbsd, adding basic check for possible misusage.

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


1 Files Affected:

- (modified) clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp (+42) 


``````````diff
diff --git a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index b7b64c3da4f6c8..b6b0878459f0c2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -166,6 +166,7 @@ class CStringChecker : public Checker< eval::Call,
       {{CDF_MaybeBuiltin, {"explicit_bzero"}, 2}, &CStringChecker::evalBzero},
       {{CDF_MaybeBuiltin, {"sprintf"}, 2}, &CStringChecker::evalSprintf},
       {{CDF_MaybeBuiltin, {"snprintf"}, 2}, &CStringChecker::evalSnprintf},
+      {{CDF_MaybeBuiltin, {"getentropy"}, 2}, &CStringChecker::evalGetentropy},
   };
 
   // These require a bit of special handling.
@@ -220,6 +221,7 @@ class CStringChecker : public Checker< eval::Call,
   void evalSnprintf(CheckerContext &C, const CallEvent &Call) const;
   void evalSprintfCommon(CheckerContext &C, const CallEvent &Call,
                          bool IsBounded, bool IsBuiltin) const;
+  void evalGetentropy(CheckerContext &C, const CallEvent &Call) const;
 
   // Utility methods
   std::pair<ProgramStateRef , ProgramStateRef >
@@ -2516,6 +2518,46 @@ void CStringChecker::evalSprintfCommon(CheckerContext &C, const CallEvent &Call,
   C.addTransition(State);
 }
 
+void CStringChecker::evalGetentropy(CheckerContext &C, const CallEvent &Call) const {
+  DestinationArgExpr Buffer = {{Call.getArgExpr(0), 0}};
+  SizeArgExpr Size = {{Call.getArgExpr(1), 1}};
+  ProgramStateRef State = C.getState();
+  constexpr int BufferMaxSize = 256;
+
+  SVal SizeVal = C.getSVal(Size.Expression);
+  QualType SizeTy = Size.Expression->getType();
+
+  ProgramStateRef StateZeroSize, StateNonZeroSize;
+  std::tie(StateZeroSize, StateNonZeroSize) =
+    assumeZero(C, State, SizeVal, SizeTy);
+
+  SVal Buff = C.getSVal(Buffer.Expression);
+  State = checkNonNull(C, StateNonZeroSize, Buffer, Buff);
+  if (!State)
+    return;
+
+  State = CheckBufferAccess(C, State, Buffer, Size, AccessKind::write);
+  if (!State)
+    return;
+
+  auto SizeLoc = SizeVal.getAs<nonloc::ConcreteInt>();
+  auto size = SizeLoc->getValue().getExtValue();
+
+  if (size > BufferMaxSize) {
+    ErrorMessage Message;
+    llvm::raw_svector_ostream Os(Message);
+    Os << " destination buffer size is greater than " << BufferMaxSize;
+    emitOutOfBoundsBug(C, StateNonZeroSize, Buffer.Expression, Message);
+    return;
+  }
+
+  State = invalidateDestinationBufferBySize(
+      C, State, Buffer.Expression, C.getSVal(Buffer.Expression), SizeVal,
+      SizeTy);
+
+  C.addTransition(State);
+}
+
 //===----------------------------------------------------------------------===//
 // The driver method, and other Checker callbacks.
 //===----------------------------------------------------------------------===//

``````````

</details>


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


More information about the cfe-commits mailing list