[clang] [clang][StaticAnalyzer] Adding getentropy to CStringChecker. (PR #83675)
David CARLIER via cfe-commits
cfe-commits at lists.llvm.org
Sat Mar 2 06:57:52 PST 2024
https://github.com/devnexen created https://github.com/llvm/llvm-project/pull/83675
since it went way beyond just openbsd, adding basic check for possible misusage.
>From f9e571bfa3e64d9fb54e965f3c363aef40fa3b80 Mon Sep 17 00:00:00 2001
From: David Carlier <devnexen at gmail.com>
Date: Sat, 2 Mar 2024 14:56:15 +0000
Subject: [PATCH] [clang][StaticAnalyzer] Adding getentropy to CStringChecker.
since it went way beyond just openbsd, adding basic check for possible
misusage.
---
.../Checkers/CStringChecker.cpp | 42 +++++++++++++++++++
1 file changed, 42 insertions(+)
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.
//===----------------------------------------------------------------------===//
More information about the cfe-commits
mailing list