27class ReturnPointerRangeChecker :
28 public Checker< check::PreStmt<ReturnStmt> > {
31 const BugType BT{
this,
"Buffer overflow"};
34 void checkPreStmt(
const ReturnStmt *RS, CheckerContext &
C)
const;
38void ReturnPointerRangeChecker::checkPreStmt(
const ReturnStmt *RS,
50 SVal
V =
C.getSVal(RetE);
51 const MemRegion *R =
V.getAsRegion();
53 const ElementRegion *ER = dyn_cast_or_null<ElementRegion>(R);
57 DefinedOrUnknownSVal Idx = ER->
getIndex().
castAs<DefinedOrUnknownSVal>();
70 if (Idx == ElementCount)
74 std::tie(StInBound, StOutBound) = state->assumeInBoundDual(Idx, ElementCount);
75 if (StOutBound && !StInBound) {
76 ExplodedNode *N =
C.generateErrorNode(StOutBound);
81 constexpr llvm::StringLiteral Msg =
82 "Returned pointer value points outside the original object "
83 "(potential buffer overflow)";
86 auto Report = std::make_unique<PathSensitiveBugReport>(BT, Msg, N);
89 const auto ConcreteElementCount = ElementCount.
getAs<nonloc::ConcreteInt>();
90 const auto ConcreteIdx = Idx.
getAs<nonloc::ConcreteInt>();
95 Report->addNote(
"Original object declared here",
96 {DeclR->getDecl(),
C.getSourceManager()});
98 if (ConcreteElementCount) {
99 SmallString<128> SBuf;
100 llvm::raw_svector_ostream
OS(SBuf);
101 OS <<
"Original object ";
104 DeclR->getDecl()->printName(
OS);
107 OS <<
"is an array of " << ConcreteElementCount->getValue() <<
" '";
109 PrintingPolicy(
C.getASTContext().getLangOpts()));
112 OS <<
", returned pointer points at index " << ConcreteIdx->
getValue();
116 {RetE,
C.getSourceManager(),
C.getLocationContext()});
121 C.emitReport(std::move(
Report));
125void ento::registerReturnPointerRangeChecker(CheckerManager &mgr) {
129bool ento::shouldRegisterReturnPointerRangeChecker(
const CheckerManager &mgr) {
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
CHECKER * registerChecker(AT &&...Args)
Register a single-part checker (derived from Checker): construct its singleton instance,...
Simple checker classes that implement one frontend (i.e.
QualType getValueType() const override
const RegionTy * getAs() const
bool isZeroConstant() const
std::optional< T > getAs() const
Convert to the specified SVal type, returning std::nullopt if this SVal is not of the desired type.
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getSuperRegion() const
APSIntPtr getValue() const
bool trackExpressionValue(const ExplodedNode *N, const Expr *E, PathSensitiveBugReport &R, TrackingOptions Opts={})
Attempts to add visitors to track expression value back to its point of origin.
DefinedOrUnknownSVal getDynamicElementCount(ProgramStateRef State, const MemRegion *MR, SValBuilder &SVB, QualType Ty)
IntrusiveRefCntPtr< const ProgramState > ProgramStateRef
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.