[clang] [analyzer] New optin.taint.TaintAlloc checker for catching unbounded memory allocation calls (PR #92420)
DonĂ¡t Nagy via cfe-commits
cfe-commits at lists.llvm.org
Wed May 29 01:44:35 PDT 2024
================
@@ -1779,18 +1797,76 @@ ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
const CallEvent &Call,
const Expr *SizeEx, SVal Init,
ProgramStateRef State,
- AllocationFamily Family) {
+ AllocationFamily Family) const {
if (!State)
return nullptr;
assert(SizeEx);
return MallocMemAux(C, Call, C.getSVal(SizeEx), Init, State, Family);
}
+void MallocChecker::reportTaintBug(StringRef Msg, ProgramStateRef State,
+ CheckerContext &C,
+ llvm::ArrayRef<SymbolRef> TaintedSyms,
+ AllocationFamily Family) const {
+
+ if (!ChecksEnabled[CK_TaintAllocChecker])
+ return;
+
+ if (ExplodedNode *N = C.generateNonFatalErrorNode(State, this)) {
+ if (!BT_TaintedAlloc)
+ BT_TaintedAlloc.reset(new BugType(CheckNames[CK_TaintAllocChecker],
+ "Tainted Memory Allocation",
+ categories::TaintedData));
+ auto R = std::make_unique<PathSensitiveBugReport>(*BT_TaintedAlloc, Msg, N);
+ for (auto TaintedSym : TaintedSyms) {
+ R->markInteresting(TaintedSym);
+ }
+ C.emitReport(std::move(R));
+ }
+}
+
+void MallocChecker::CheckTaintedness(CheckerContext &C, const CallEvent &Call,
+ const SVal SizeSVal, ProgramStateRef State,
+ AllocationFamily Family) const {
+ std::vector<SymbolRef> TaintedSyms =
+ taint::getTaintedSymbols(State, SizeSVal);
+ if (TaintedSyms.empty())
+ return;
+
+ SValBuilder &SVB = C.getSValBuilder();
+ QualType SizeTy = SVB.getContext().getSizeType();
+ QualType CmpTy = SVB.getConditionType();
+ // In case the symbol is tainted, we give a warning if the
+ // size is larger than SIZE_MAX/4
+ BasicValueFactory &BVF = SVB.getBasicValueFactory();
+ const llvm::APSInt MaxValInt = BVF.getMaxValue(SizeTy);
+ NonLoc MaxLength =
+ SVB.makeIntVal(MaxValInt / APSIntType(MaxValInt).getValue(4));
+ std::optional<NonLoc> SizeNL = SizeSVal.getAs<NonLoc>();
+ auto Cmp = SVB.evalBinOpNN(State, BO_GE, *SizeNL, MaxLength, CmpTy)
+ .getAs<DefinedOrUnknownSVal>();
+ if (!Cmp)
+ return;
+ auto [StateTooLarge, StateNotTooLarge] = State->assume(*Cmp);
+ if (!StateTooLarge && StateNotTooLarge) {
+ // we can prove that size is not too large so ok.
----------------
NagyDonat wrote:
```suggestion
// We can prove that size is not too large, so there is no issue."
```
https://github.com/llvm/llvm-project/pull/92420
More information about the cfe-commits
mailing list