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 <devne...@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. //===----------------------------------------------------------------------===// _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits