diff options
| author | Anna Zaks <ganna@apple.com> | 2011-12-14 00:56:02 +0000 |
|---|---|---|
| committer | Anna Zaks <ganna@apple.com> | 2011-12-14 00:56:02 +0000 |
| commit | eefc0e9342df1896be36f4552c15ce37e23c0c46 (patch) | |
| tree | 1d3d8af70a6d57a6487c5a4f4c06511d600909d9 /clang/lib | |
| parent | d6bb3227de1af821261b631b63812369f789b675 (diff) | |
| download | bcm5719-llvm-eefc0e9342df1896be36f4552c15ce37e23c0c46.tar.gz bcm5719-llvm-eefc0e9342df1896be36f4552c15ce37e23c0c46.zip | |
[analyzer] Mark output of fscanf and fopen as tainted.
llvm-svn: 146533
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp index dcf7694464e..890a592c17c 100644 --- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp @@ -39,6 +39,7 @@ class GenericTaintChecker : public Checker< check::PostStmt<CallExpr> > { typedef void (GenericTaintChecker::*FnCheck)(const CallExpr *, CheckerContext &C) const; void processScanf(const CallExpr *CE, CheckerContext &C) const; + void processFscanf(const CallExpr *CE, CheckerContext &C) const; void processRetTaint(const CallExpr *CE, CheckerContext &C) const; public: @@ -62,8 +63,14 @@ void GenericTaintChecker::checkPostStmt(const CallExpr *CE, // Set the evaluation function by switching on the callee name. FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name) .Case("scanf", &GenericTaintChecker::processScanf) + .Case("fscanf", &GenericTaintChecker::processFscanf) + .Case("sscanf", &GenericTaintChecker::processFscanf) + // TODO: Add support for vfscanf & family. .Case("getchar", &GenericTaintChecker::processRetTaint) .Case("getenv", &GenericTaintChecker::processRetTaint) + .Case("fopen", &GenericTaintChecker::processRetTaint) + .Case("fdopen", &GenericTaintChecker::processRetTaint) + .Case("freopen", &GenericTaintChecker::processRetTaint) .Default(NULL); // If the callee isn't defined, it is not of security concern. @@ -108,7 +115,7 @@ SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C, void GenericTaintChecker::processScanf(const CallExpr *CE, CheckerContext &C) const { const ProgramState *State = C.getState(); - assert(CE->getNumArgs() == 2); + assert(CE->getNumArgs() >= 2); SVal x = State->getSVal(CE->getArg(1)); // All arguments except for the very first one should get taint. for (unsigned int i = 1; i < CE->getNumArgs(); ++i) { @@ -120,7 +127,29 @@ void GenericTaintChecker::processScanf(const CallExpr *CE, State = State->addTaint(Sym); } C.addTransition(State); +} + +/// If argument 0 (file descriptor) is tainted, all arguments except for arg 0 +/// and arg 1 should get taint. +void GenericTaintChecker::processFscanf(const CallExpr *CE, + CheckerContext &C) const { + const ProgramState *State = C.getState(); + assert(CE->getNumArgs() >= 2); + // Check is the file descriptor is tainted. + if (!State->isTainted(CE->getArg(0))) + return; + + // All arguments except for the first two should get taint. + for (unsigned int i = 2; i < CE->getNumArgs(); ++i) { + // The arguments are pointer arguments. The data they are pointing at is + // tainted after the call. + const Expr* Arg = CE->getArg(i); + SymbolRef Sym = getPointedToSymbol(C, Arg); + if (Sym) + State = State->addTaint(Sym); + } + C.addTransition(State); } void GenericTaintChecker::processRetTaint(const CallExpr *CE, |

