[cfe-commits] r136930 - /cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
Anna Zaks
ganna at apple.com
Thu Aug 4 14:53:01 PDT 2011
Author: zaks
Date: Thu Aug 4 16:53:01 2011
New Revision: 136930
URL: http://llvm.org/viewvc/llvm-project?rev=136930&view=rev
Log:
KeychainAPI checker: Track additional pair of SecKeychain APIs. Also, keep exploring the transition on which a call to allocator function failed (to be able to find errors in examples like ErrorCodesFromDifferentAPISDoNotInterfere).
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp?rev=136930&r1=136929&r2=136930&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp Thu Aug 4 16:53:01 2011
@@ -46,7 +46,7 @@
unsigned int DeallocatorIdx;
};
static const unsigned InvalidIdx = 100000;
- static const unsigned FunctionsToTrackSize = 4;
+ static const unsigned FunctionsToTrackSize = 6;
static const ADFunctionInfo FunctionsToTrack[FunctionsToTrackSize];
/// Given the function name, returns the index of the allocator/deallocator
@@ -105,6 +105,8 @@
{"SecKeychainFindGenericPassword", 6, 3}, // 1
{"SecKeychainFindInternetPassword", 13, 3}, // 2
{"SecKeychainItemFreeContent", 1, InvalidIdx}, // 3
+ {"SecKeychainItemCopyAttributesAndData", 5, 5}, // 4
+ {"SecKeychainItemFreeAttributesAndData", 1, InvalidIdx}, // 5
};
unsigned MacOSKeychainAPIChecker::getTrackedFunctionIndex(StringRef Name,
@@ -168,9 +170,25 @@
return;
}
+ // Check if the proper deallocator is used.
+ unsigned int PDeallocIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
+ if (PDeallocIdx != idx) {
+ ExplodedNode *N = C.generateSink(State);
+ if (!N)
+ return;
+ initBugType();
+
+ std::string sbuf;
+ llvm::raw_string_ostream os(sbuf);
+ os << "Allocator doesn't match the deallocator: '"
+ << FunctionsToTrack[PDeallocIdx].Name << "' should be used.";
+ RangedBugReport *Report = new RangedBugReport(*BT, os.str(), N);
+ Report->addRange(ArgExpr->getSourceRange());
+ C.EmitReport(Report);
+ return;
+ }
+
// Continue exploring from the new state.
- assert(FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx == idx &&
- "Allocator should match the deallocator");
State = State->remove<AllocatedData>(Arg);
C.addTransition(State);
}
@@ -210,17 +228,25 @@
if (!V)
return;
- State = State->set<AllocatedData>(V, AllocationState(ArgExpr, idx));
-
// We only need to track the value if the function returned noErr(0), so
- // bind the return value of the function to 0.
+ // bind the return value of the function to 0 and proceed from the no error
+ // state.
SValBuilder &Builder = C.getSValBuilder();
- SVal ZeroVal = Builder.makeZeroVal(Builder.getContext().CharTy);
- State = State->BindExpr(CE, ZeroVal);
- assert(State);
-
- // Proceed from the new state.
- C.addTransition(State);
+ SVal ZeroVal = Builder.makeIntVal(0, CE->getCallReturnType());
+ const GRState *NoErr = State->BindExpr(CE, ZeroVal);
+ NoErr = NoErr->set<AllocatedData>(V, AllocationState(ArgExpr, idx));
+ assert(NoErr);
+ C.addTransition(NoErr);
+
+ // Generate a transition to explore the state space when there is an error.
+ // In this case, we do not track the allocated data.
+ SVal ReturnedError = Builder.evalBinOpNN(State, BO_NE,
+ cast<NonLoc>(ZeroVal),
+ cast<NonLoc>(State->getSVal(CE)),
+ CE->getCallReturnType());
+ const GRState *Err = State->assume(cast<NonLoc>(ReturnedError), true);
+ assert(Err);
+ C.addTransition(Err);
}
}
@@ -253,8 +279,13 @@
// Anything which has been allocated but not freed (nor escaped) will be
// found here, so report it.
for (AllocatedSetTy::iterator I = AS.begin(), E = AS.end(); I != E; ++I ) {
- RangedBugReport *Report = new RangedBugReport(*BT,
- "Missing a call to SecKeychainItemFreeContent.", N);
+ const ADFunctionInfo &FI = FunctionsToTrack[I->second.AllocatorIdx];
+
+ std::string sbuf;
+ llvm::raw_string_ostream os(sbuf);
+ os << "Allocated data is not released: missing a call to '"
+ << FunctionsToTrack[FI.DeallocatorIdx].Name << "'.";
+ RangedBugReport *Report = new RangedBugReport(*BT, os.str(), N);
// TODO: The report has to mention the expression which contains the
// allocated content as well as the point at which it has been allocated.
// Currently, the next line is useless.
More information about the cfe-commits
mailing list