MallocChecker.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. //=== MallocChecker.cpp - A malloc/free checker -------------------*- C++ -*--//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file defines malloc/free checker, which checks for potential memory
  11. // leaks, double free, and use-after-free problems.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "ClangSACheckers.h"
  15. #include "clang/StaticAnalyzer/Core/Checker.h"
  16. #include "clang/StaticAnalyzer/Core/CheckerManager.h"
  17. #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
  18. #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
  19. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
  20. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
  21. #include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
  22. #include "llvm/ADT/ImmutableMap.h"
  23. #include "llvm/ADT/STLExtras.h"
  24. using namespace clang;
  25. using namespace ento;
  26. namespace {
  27. class RefState {
  28. enum Kind { AllocateUnchecked, AllocateFailed, Released, Escaped,
  29. Relinquished } K;
  30. const Stmt *S;
  31. public:
  32. RefState(Kind k, const Stmt *s) : K(k), S(s) {}
  33. bool isAllocated() const { return K == AllocateUnchecked; }
  34. //bool isFailed() const { return K == AllocateFailed; }
  35. bool isReleased() const { return K == Released; }
  36. //bool isEscaped() const { return K == Escaped; }
  37. //bool isRelinquished() const { return K == Relinquished; }
  38. bool operator==(const RefState &X) const {
  39. return K == X.K && S == X.S;
  40. }
  41. static RefState getAllocateUnchecked(const Stmt *s) {
  42. return RefState(AllocateUnchecked, s);
  43. }
  44. static RefState getAllocateFailed() {
  45. return RefState(AllocateFailed, 0);
  46. }
  47. static RefState getReleased(const Stmt *s) { return RefState(Released, s); }
  48. static RefState getEscaped(const Stmt *s) { return RefState(Escaped, s); }
  49. static RefState getRelinquished(const Stmt *s) {
  50. return RefState(Relinquished, s);
  51. }
  52. void Profile(llvm::FoldingSetNodeID &ID) const {
  53. ID.AddInteger(K);
  54. ID.AddPointer(S);
  55. }
  56. };
  57. class RegionState {};
  58. class MallocChecker : public Checker<eval::Call,
  59. check::DeadSymbols,
  60. check::EndPath,
  61. check::PreStmt<ReturnStmt>,
  62. check::Location,
  63. check::Bind,
  64. eval::Assume>
  65. {
  66. mutable llvm::OwningPtr<BuiltinBug> BT_DoubleFree;
  67. mutable llvm::OwningPtr<BuiltinBug> BT_Leak;
  68. mutable llvm::OwningPtr<BuiltinBug> BT_UseFree;
  69. mutable llvm::OwningPtr<BuiltinBug> BT_UseRelinquished;
  70. mutable llvm::OwningPtr<BuiltinBug> BT_BadFree;
  71. mutable IdentifierInfo *II_malloc, *II_free, *II_realloc, *II_calloc;
  72. public:
  73. MallocChecker() : II_malloc(0), II_free(0), II_realloc(0), II_calloc(0) {}
  74. bool evalCall(const CallExpr *CE, CheckerContext &C) const;
  75. void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
  76. void checkEndPath(CheckerContext &C) const;
  77. void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
  78. ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
  79. bool Assumption) const;
  80. void checkLocation(SVal l, bool isLoad, const Stmt *S,
  81. CheckerContext &C) const;
  82. void checkBind(SVal location, SVal val, const Stmt*S,
  83. CheckerContext &C) const;
  84. private:
  85. static void MallocMem(CheckerContext &C, const CallExpr *CE);
  86. static void MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
  87. const OwnershipAttr* Att);
  88. static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
  89. const Expr *SizeEx, SVal Init,
  90. ProgramStateRef state) {
  91. return MallocMemAux(C, CE,
  92. state->getSVal(SizeEx, C.getLocationContext()),
  93. Init, state);
  94. }
  95. static ProgramStateRef MallocMemAux(CheckerContext &C, const CallExpr *CE,
  96. SVal SizeEx, SVal Init,
  97. ProgramStateRef state);
  98. void FreeMem(CheckerContext &C, const CallExpr *CE) const;
  99. void FreeMemAttr(CheckerContext &C, const CallExpr *CE,
  100. const OwnershipAttr* Att) const;
  101. ProgramStateRef FreeMemAux(CheckerContext &C, const CallExpr *CE,
  102. ProgramStateRef state, unsigned Num,
  103. bool Hold) const;
  104. void ReallocMem(CheckerContext &C, const CallExpr *CE) const;
  105. static void CallocMem(CheckerContext &C, const CallExpr *CE);
  106. static bool SummarizeValue(raw_ostream &os, SVal V);
  107. static bool SummarizeRegion(raw_ostream &os, const MemRegion *MR);
  108. void ReportBadFree(CheckerContext &C, SVal ArgVal, SourceRange range) const;
  109. };
  110. } // end anonymous namespace
  111. typedef llvm::ImmutableMap<SymbolRef, RefState> RegionStateTy;
  112. namespace clang {
  113. namespace ento {
  114. template <>
  115. struct ProgramStateTrait<RegionState>
  116. : public ProgramStatePartialTrait<RegionStateTy> {
  117. static void *GDMIndex() { static int x; return &x; }
  118. };
  119. }
  120. }
  121. bool MallocChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
  122. const FunctionDecl *FD = C.getCalleeDecl(CE);
  123. if (!FD)
  124. return false;
  125. ASTContext &Ctx = C.getASTContext();
  126. if (!II_malloc)
  127. II_malloc = &Ctx.Idents.get("malloc");
  128. if (!II_free)
  129. II_free = &Ctx.Idents.get("free");
  130. if (!II_realloc)
  131. II_realloc = &Ctx.Idents.get("realloc");
  132. if (!II_calloc)
  133. II_calloc = &Ctx.Idents.get("calloc");
  134. if (FD->getIdentifier() == II_malloc) {
  135. MallocMem(C, CE);
  136. return true;
  137. }
  138. if (FD->getIdentifier() == II_free) {
  139. FreeMem(C, CE);
  140. return true;
  141. }
  142. if (FD->getIdentifier() == II_realloc) {
  143. ReallocMem(C, CE);
  144. return true;
  145. }
  146. if (FD->getIdentifier() == II_calloc) {
  147. CallocMem(C, CE);
  148. return true;
  149. }
  150. // Check all the attributes, if there are any.
  151. // There can be multiple of these attributes.
  152. bool rv = false;
  153. if (FD->hasAttrs()) {
  154. for (specific_attr_iterator<OwnershipAttr>
  155. i = FD->specific_attr_begin<OwnershipAttr>(),
  156. e = FD->specific_attr_end<OwnershipAttr>();
  157. i != e; ++i) {
  158. switch ((*i)->getOwnKind()) {
  159. case OwnershipAttr::Returns: {
  160. MallocMemReturnsAttr(C, CE, *i);
  161. rv = true;
  162. break;
  163. }
  164. case OwnershipAttr::Takes:
  165. case OwnershipAttr::Holds: {
  166. FreeMemAttr(C, CE, *i);
  167. rv = true;
  168. break;
  169. }
  170. }
  171. }
  172. }
  173. return rv;
  174. }
  175. void MallocChecker::MallocMem(CheckerContext &C, const CallExpr *CE) {
  176. ProgramStateRef state = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(),
  177. C.getState());
  178. C.addTransition(state);
  179. }
  180. void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
  181. const OwnershipAttr* Att) {
  182. if (Att->getModule() != "malloc")
  183. return;
  184. OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
  185. if (I != E) {
  186. ProgramStateRef state =
  187. MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
  188. C.addTransition(state);
  189. return;
  190. }
  191. ProgramStateRef state = MallocMemAux(C, CE, UnknownVal(), UndefinedVal(),
  192. C.getState());
  193. C.addTransition(state);
  194. }
  195. ProgramStateRef MallocChecker::MallocMemAux(CheckerContext &C,
  196. const CallExpr *CE,
  197. SVal Size, SVal Init,
  198. ProgramStateRef state) {
  199. unsigned Count = C.getCurrentBlockCount();
  200. SValBuilder &svalBuilder = C.getSValBuilder();
  201. // Set the return value.
  202. SVal retVal = svalBuilder.getConjuredSymbolVal(NULL, CE,
  203. CE->getType(), Count);
  204. state = state->BindExpr(CE, C.getLocationContext(), retVal);
  205. // Fill the region with the initialization value.
  206. state = state->bindDefault(retVal, Init);
  207. // Set the region's extent equal to the Size parameter.
  208. const SymbolicRegion *R = cast<SymbolicRegion>(retVal.getAsRegion());
  209. DefinedOrUnknownSVal Extent = R->getExtent(svalBuilder);
  210. DefinedOrUnknownSVal DefinedSize = cast<DefinedOrUnknownSVal>(Size);
  211. DefinedOrUnknownSVal extentMatchesSize =
  212. svalBuilder.evalEQ(state, Extent, DefinedSize);
  213. state = state->assume(extentMatchesSize, true);
  214. assert(state);
  215. SymbolRef Sym = retVal.getAsLocSymbol();
  216. assert(Sym);
  217. // Set the symbol's state to Allocated.
  218. return state->set<RegionState>(Sym, RefState::getAllocateUnchecked(CE));
  219. }
  220. void MallocChecker::FreeMem(CheckerContext &C, const CallExpr *CE) const {
  221. ProgramStateRef state = FreeMemAux(C, CE, C.getState(), 0, false);
  222. if (state)
  223. C.addTransition(state);
  224. }
  225. void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
  226. const OwnershipAttr* Att) const {
  227. if (Att->getModule() != "malloc")
  228. return;
  229. for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
  230. I != E; ++I) {
  231. ProgramStateRef state =
  232. FreeMemAux(C, CE, C.getState(), *I,
  233. Att->getOwnKind() == OwnershipAttr::Holds);
  234. if (state)
  235. C.addTransition(state);
  236. }
  237. }
  238. ProgramStateRef MallocChecker::FreeMemAux(CheckerContext &C,
  239. const CallExpr *CE,
  240. ProgramStateRef state,
  241. unsigned Num,
  242. bool Hold) const {
  243. const Expr *ArgExpr = CE->getArg(Num);
  244. SVal ArgVal = state->getSVal(ArgExpr, C.getLocationContext());
  245. DefinedOrUnknownSVal location = cast<DefinedOrUnknownSVal>(ArgVal);
  246. // Check for null dereferences.
  247. if (!isa<Loc>(location))
  248. return state;
  249. // FIXME: Technically using 'Assume' here can result in a path
  250. // bifurcation. In such cases we need to return two states, not just one.
  251. ProgramStateRef notNullState, nullState;
  252. llvm::tie(notNullState, nullState) = state->assume(location);
  253. // The explicit NULL case, no operation is performed.
  254. if (nullState && !notNullState)
  255. return nullState;
  256. assert(notNullState);
  257. // Unknown values could easily be okay
  258. // Undefined values are handled elsewhere
  259. if (ArgVal.isUnknownOrUndef())
  260. return notNullState;
  261. const MemRegion *R = ArgVal.getAsRegion();
  262. // Nonlocs can't be freed, of course.
  263. // Non-region locations (labels and fixed addresses) also shouldn't be freed.
  264. if (!R) {
  265. ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
  266. return NULL;
  267. }
  268. R = R->StripCasts();
  269. // Blocks might show up as heap data, but should not be free()d
  270. if (isa<BlockDataRegion>(R)) {
  271. ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
  272. return NULL;
  273. }
  274. const MemSpaceRegion *MS = R->getMemorySpace();
  275. // Parameters, locals, statics, and globals shouldn't be freed.
  276. if (!(isa<UnknownSpaceRegion>(MS) || isa<HeapSpaceRegion>(MS))) {
  277. // FIXME: at the time this code was written, malloc() regions were
  278. // represented by conjured symbols, which are all in UnknownSpaceRegion.
  279. // This means that there isn't actually anything from HeapSpaceRegion
  280. // that should be freed, even though we allow it here.
  281. // Of course, free() can work on memory allocated outside the current
  282. // function, so UnknownSpaceRegion is always a possibility.
  283. // False negatives are better than false positives.
  284. ReportBadFree(C, ArgVal, ArgExpr->getSourceRange());
  285. return NULL;
  286. }
  287. const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R);
  288. // Various cases could lead to non-symbol values here.
  289. // For now, ignore them.
  290. if (!SR)
  291. return notNullState;
  292. SymbolRef Sym = SR->getSymbol();
  293. const RefState *RS = state->get<RegionState>(Sym);
  294. // If the symbol has not been tracked, return. This is possible when free() is
  295. // called on a pointer that does not get its pointee directly from malloc().
  296. // Full support of this requires inter-procedural analysis.
  297. if (!RS)
  298. return notNullState;
  299. // Check double free.
  300. if (RS->isReleased()) {
  301. if (ExplodedNode *N = C.generateSink()) {
  302. if (!BT_DoubleFree)
  303. BT_DoubleFree.reset(
  304. new BuiltinBug("Double free",
  305. "Try to free a memory block that has been released"));
  306. // FIXME: should find where it's freed last time.
  307. BugReport *R = new BugReport(*BT_DoubleFree,
  308. BT_DoubleFree->getDescription(), N);
  309. C.EmitReport(R);
  310. }
  311. return NULL;
  312. }
  313. // Normal free.
  314. if (Hold)
  315. return notNullState->set<RegionState>(Sym, RefState::getRelinquished(CE));
  316. return notNullState->set<RegionState>(Sym, RefState::getReleased(CE));
  317. }
  318. bool MallocChecker::SummarizeValue(raw_ostream &os, SVal V) {
  319. if (nonloc::ConcreteInt *IntVal = dyn_cast<nonloc::ConcreteInt>(&V))
  320. os << "an integer (" << IntVal->getValue() << ")";
  321. else if (loc::ConcreteInt *ConstAddr = dyn_cast<loc::ConcreteInt>(&V))
  322. os << "a constant address (" << ConstAddr->getValue() << ")";
  323. else if (loc::GotoLabel *Label = dyn_cast<loc::GotoLabel>(&V))
  324. os << "the address of the label '" << Label->getLabel()->getName() << "'";
  325. else
  326. return false;
  327. return true;
  328. }
  329. bool MallocChecker::SummarizeRegion(raw_ostream &os,
  330. const MemRegion *MR) {
  331. switch (MR->getKind()) {
  332. case MemRegion::FunctionTextRegionKind: {
  333. const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl();
  334. if (FD)
  335. os << "the address of the function '" << *FD << '\'';
  336. else
  337. os << "the address of a function";
  338. return true;
  339. }
  340. case MemRegion::BlockTextRegionKind:
  341. os << "block text";
  342. return true;
  343. case MemRegion::BlockDataRegionKind:
  344. // FIXME: where the block came from?
  345. os << "a block";
  346. return true;
  347. default: {
  348. const MemSpaceRegion *MS = MR->getMemorySpace();
  349. if (isa<StackLocalsSpaceRegion>(MS)) {
  350. const VarRegion *VR = dyn_cast<VarRegion>(MR);
  351. const VarDecl *VD;
  352. if (VR)
  353. VD = VR->getDecl();
  354. else
  355. VD = NULL;
  356. if (VD)
  357. os << "the address of the local variable '" << VD->getName() << "'";
  358. else
  359. os << "the address of a local stack variable";
  360. return true;
  361. }
  362. if (isa<StackArgumentsSpaceRegion>(MS)) {
  363. const VarRegion *VR = dyn_cast<VarRegion>(MR);
  364. const VarDecl *VD;
  365. if (VR)
  366. VD = VR->getDecl();
  367. else
  368. VD = NULL;
  369. if (VD)
  370. os << "the address of the parameter '" << VD->getName() << "'";
  371. else
  372. os << "the address of a parameter";
  373. return true;
  374. }
  375. if (isa<GlobalsSpaceRegion>(MS)) {
  376. const VarRegion *VR = dyn_cast<VarRegion>(MR);
  377. const VarDecl *VD;
  378. if (VR)
  379. VD = VR->getDecl();
  380. else
  381. VD = NULL;
  382. if (VD) {
  383. if (VD->isStaticLocal())
  384. os << "the address of the static variable '" << VD->getName() << "'";
  385. else
  386. os << "the address of the global variable '" << VD->getName() << "'";
  387. } else
  388. os << "the address of a global variable";
  389. return true;
  390. }
  391. return false;
  392. }
  393. }
  394. }
  395. void MallocChecker::ReportBadFree(CheckerContext &C, SVal ArgVal,
  396. SourceRange range) const {
  397. if (ExplodedNode *N = C.generateSink()) {
  398. if (!BT_BadFree)
  399. BT_BadFree.reset(new BuiltinBug("Bad free"));
  400. llvm::SmallString<100> buf;
  401. llvm::raw_svector_ostream os(buf);
  402. const MemRegion *MR = ArgVal.getAsRegion();
  403. if (MR) {
  404. while (const ElementRegion *ER = dyn_cast<ElementRegion>(MR))
  405. MR = ER->getSuperRegion();
  406. // Special case for alloca()
  407. if (isa<AllocaRegion>(MR))
  408. os << "Argument to free() was allocated by alloca(), not malloc()";
  409. else {
  410. os << "Argument to free() is ";
  411. if (SummarizeRegion(os, MR))
  412. os << ", which is not memory allocated by malloc()";
  413. else
  414. os << "not memory allocated by malloc()";
  415. }
  416. } else {
  417. os << "Argument to free() is ";
  418. if (SummarizeValue(os, ArgVal))
  419. os << ", which is not memory allocated by malloc()";
  420. else
  421. os << "not memory allocated by malloc()";
  422. }
  423. BugReport *R = new BugReport(*BT_BadFree, os.str(), N);
  424. R->addRange(range);
  425. C.EmitReport(R);
  426. }
  427. }
  428. void MallocChecker::ReallocMem(CheckerContext &C, const CallExpr *CE) const {
  429. ProgramStateRef state = C.getState();
  430. const Expr *arg0Expr = CE->getArg(0);
  431. const LocationContext *LCtx = C.getLocationContext();
  432. DefinedOrUnknownSVal arg0Val
  433. = cast<DefinedOrUnknownSVal>(state->getSVal(arg0Expr, LCtx));
  434. SValBuilder &svalBuilder = C.getSValBuilder();
  435. DefinedOrUnknownSVal PtrEQ =
  436. svalBuilder.evalEQ(state, arg0Val, svalBuilder.makeNull());
  437. // Get the size argument. If there is no size arg then give up.
  438. const Expr *Arg1 = CE->getArg(1);
  439. if (!Arg1)
  440. return;
  441. // Get the value of the size argument.
  442. DefinedOrUnknownSVal Arg1Val =
  443. cast<DefinedOrUnknownSVal>(state->getSVal(Arg1, LCtx));
  444. // Compare the size argument to 0.
  445. DefinedOrUnknownSVal SizeZero =
  446. svalBuilder.evalEQ(state, Arg1Val,
  447. svalBuilder.makeIntValWithPtrWidth(0, false));
  448. // If the ptr is NULL and the size is not 0, the call is equivalent to
  449. // malloc(size).
  450. ProgramStateRef stateEqual = state->assume(PtrEQ, true);
  451. if (stateEqual && state->assume(SizeZero, false)) {
  452. // Hack: set the NULL symbolic region to released to suppress false warning.
  453. // In the future we should add more states for allocated regions, e.g.,
  454. // CheckedNull, CheckedNonNull.
  455. SymbolRef Sym = arg0Val.getAsLocSymbol();
  456. if (Sym)
  457. stateEqual = stateEqual->set<RegionState>(Sym, RefState::getReleased(CE));
  458. ProgramStateRef stateMalloc = MallocMemAux(C, CE, CE->getArg(1),
  459. UndefinedVal(), stateEqual);
  460. C.addTransition(stateMalloc);
  461. }
  462. if (ProgramStateRef stateNotEqual = state->assume(PtrEQ, false)) {
  463. // If the size is 0, free the memory.
  464. if (ProgramStateRef stateSizeZero =
  465. stateNotEqual->assume(SizeZero, true))
  466. if (ProgramStateRef stateFree =
  467. FreeMemAux(C, CE, stateSizeZero, 0, false)) {
  468. // Bind the return value to NULL because it is now free.
  469. C.addTransition(stateFree->BindExpr(CE, LCtx,
  470. svalBuilder.makeNull(), true));
  471. }
  472. if (ProgramStateRef stateSizeNotZero =
  473. stateNotEqual->assume(SizeZero,false))
  474. if (ProgramStateRef stateFree = FreeMemAux(C, CE, stateSizeNotZero,
  475. 0, false)) {
  476. // FIXME: We should copy the content of the original buffer.
  477. ProgramStateRef stateRealloc = MallocMemAux(C, CE, CE->getArg(1),
  478. UnknownVal(), stateFree);
  479. C.addTransition(stateRealloc);
  480. }
  481. }
  482. }
  483. void MallocChecker::CallocMem(CheckerContext &C, const CallExpr *CE) {
  484. ProgramStateRef state = C.getState();
  485. SValBuilder &svalBuilder = C.getSValBuilder();
  486. const LocationContext *LCtx = C.getLocationContext();
  487. SVal count = state->getSVal(CE->getArg(0), LCtx);
  488. SVal elementSize = state->getSVal(CE->getArg(1), LCtx);
  489. SVal TotalSize = svalBuilder.evalBinOp(state, BO_Mul, count, elementSize,
  490. svalBuilder.getContext().getSizeType());
  491. SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
  492. C.addTransition(MallocMemAux(C, CE, TotalSize, zeroVal, state));
  493. }
  494. void MallocChecker::checkDeadSymbols(SymbolReaper &SymReaper,
  495. CheckerContext &C) const
  496. {
  497. if (!SymReaper.hasDeadSymbols())
  498. return;
  499. ProgramStateRef state = C.getState();
  500. RegionStateTy RS = state->get<RegionState>();
  501. RegionStateTy::Factory &F = state->get_context<RegionState>();
  502. bool generateReport = false;
  503. for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
  504. if (SymReaper.isDead(I->first)) {
  505. if (I->second.isAllocated())
  506. generateReport = true;
  507. // Remove the dead symbol from the map.
  508. RS = F.remove(RS, I->first);
  509. }
  510. }
  511. ExplodedNode *N = C.addTransition(state->set<RegionState>(RS));
  512. // FIXME: This does not handle when we have multiple leaks at a single
  513. // place.
  514. if (N && generateReport) {
  515. if (!BT_Leak)
  516. BT_Leak.reset(new BuiltinBug("Memory leak",
  517. "Allocated memory never released. Potential memory leak."));
  518. // FIXME: where it is allocated.
  519. BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
  520. C.EmitReport(R);
  521. }
  522. }
  523. void MallocChecker::checkEndPath(CheckerContext &Ctx) const {
  524. ProgramStateRef state = Ctx.getState();
  525. RegionStateTy M = state->get<RegionState>();
  526. for (RegionStateTy::iterator I = M.begin(), E = M.end(); I != E; ++I) {
  527. RefState RS = I->second;
  528. if (RS.isAllocated()) {
  529. ExplodedNode *N = Ctx.addTransition(state);
  530. if (N) {
  531. if (!BT_Leak)
  532. BT_Leak.reset(new BuiltinBug("Memory leak",
  533. "Allocated memory never released. Potential memory leak."));
  534. BugReport *R = new BugReport(*BT_Leak, BT_Leak->getDescription(), N);
  535. Ctx.EmitReport(R);
  536. }
  537. }
  538. }
  539. }
  540. void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
  541. const Expr *retExpr = S->getRetValue();
  542. if (!retExpr)
  543. return;
  544. ProgramStateRef state = C.getState();
  545. SymbolRef Sym = state->getSVal(retExpr, C.getLocationContext()).getAsSymbol();
  546. if (!Sym)
  547. return;
  548. const RefState *RS = state->get<RegionState>(Sym);
  549. if (!RS)
  550. return;
  551. // FIXME: check other cases.
  552. if (RS->isAllocated())
  553. state = state->set<RegionState>(Sym, RefState::getEscaped(S));
  554. C.addTransition(state);
  555. }
  556. ProgramStateRef MallocChecker::evalAssume(ProgramStateRef state,
  557. SVal Cond,
  558. bool Assumption) const {
  559. // If a symblic region is assumed to NULL, set its state to AllocateFailed.
  560. // FIXME: should also check symbols assumed to non-null.
  561. RegionStateTy RS = state->get<RegionState>();
  562. for (RegionStateTy::iterator I = RS.begin(), E = RS.end(); I != E; ++I) {
  563. // If the symbol is assumed to NULL, this will return an APSInt*.
  564. if (state->getSymVal(I.getKey()))
  565. state = state->set<RegionState>(I.getKey(),RefState::getAllocateFailed());
  566. }
  567. return state;
  568. }
  569. // Check if the location is a freed symbolic region.
  570. void MallocChecker::checkLocation(SVal l, bool isLoad, const Stmt *S,
  571. CheckerContext &C) const {
  572. SymbolRef Sym = l.getLocSymbolInBase();
  573. if (Sym) {
  574. const RefState *RS = C.getState()->get<RegionState>(Sym);
  575. if (RS && RS->isReleased()) {
  576. if (ExplodedNode *N = C.addTransition()) {
  577. if (!BT_UseFree)
  578. BT_UseFree.reset(new BuiltinBug("Use dynamically allocated memory "
  579. "after it is freed."));
  580. BugReport *R = new BugReport(*BT_UseFree, BT_UseFree->getDescription(),
  581. N);
  582. C.EmitReport(R);
  583. }
  584. }
  585. }
  586. }
  587. void MallocChecker::checkBind(SVal location, SVal val,
  588. const Stmt *BindS, CheckerContext &C) const {
  589. // The PreVisitBind implements the same algorithm as already used by the
  590. // Objective C ownership checker: if the pointer escaped from this scope by
  591. // assignment, let it go. However, assigning to fields of a stack-storage
  592. // structure does not transfer ownership.
  593. ProgramStateRef state = C.getState();
  594. DefinedOrUnknownSVal l = cast<DefinedOrUnknownSVal>(location);
  595. // Check for null dereferences.
  596. if (!isa<Loc>(l))
  597. return;
  598. // Before checking if the state is null, check if 'val' has a RefState.
  599. // Only then should we check for null and bifurcate the state.
  600. SymbolRef Sym = val.getLocSymbolInBase();
  601. if (Sym) {
  602. if (const RefState *RS = state->get<RegionState>(Sym)) {
  603. // If ptr is NULL, no operation is performed.
  604. ProgramStateRef notNullState, nullState;
  605. llvm::tie(notNullState, nullState) = state->assume(l);
  606. // Generate a transition for 'nullState' to record the assumption
  607. // that the state was null.
  608. if (nullState)
  609. C.addTransition(nullState);
  610. if (!notNullState)
  611. return;
  612. if (RS->isAllocated()) {
  613. // Something we presently own is being assigned somewhere.
  614. const MemRegion *AR = location.getAsRegion();
  615. if (!AR)
  616. return;
  617. AR = AR->StripCasts()->getBaseRegion();
  618. do {
  619. // If it is on the stack, we still own it.
  620. if (AR->hasStackNonParametersStorage())
  621. break;
  622. // If the state can't represent this binding, we still own it.
  623. if (notNullState == (notNullState->bindLoc(cast<Loc>(location),
  624. UnknownVal())))
  625. break;
  626. // We no longer own this pointer.
  627. notNullState =
  628. notNullState->set<RegionState>(Sym,
  629. RefState::getRelinquished(BindS));
  630. }
  631. while (false);
  632. }
  633. C.addTransition(notNullState);
  634. }
  635. }
  636. }
  637. void ento::registerMallocChecker(CheckerManager &mgr) {
  638. mgr.registerChecker<MallocChecker>();
  639. }