From: Anna Zaks Date: Mon, 5 Dec 2011 18:58:01 +0000 (+0000) Subject: [analyzer] Add a debug checker to test for tainted data. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a50b7ab5af79690855af68f1fff7897291ba9535;p=clang [analyzer] Add a debug checker to test for tainted data. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145827 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 293e01ba4b..75f57ace88 100644 --- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -52,6 +52,7 @@ add_clang_library(clangStaticAnalyzerCheckers ReturnUndefChecker.cpp StackAddrEscapeChecker.cpp StreamChecker.cpp + TaintTesterChecker.cpp UndefBranchChecker.cpp UndefCapturedBlockVarChecker.cpp UndefResultChecker.cpp diff --git a/lib/StaticAnalyzer/Checkers/Checkers.td b/lib/StaticAnalyzer/Checkers/Checkers.td index 786bcb052a..2e763f6032 100644 --- a/lib/StaticAnalyzer/Checkers/Checkers.td +++ b/lib/StaticAnalyzer/Checkers/Checkers.td @@ -392,5 +392,9 @@ def AnalyzerStatsChecker : Checker<"Stats">, HelpText<"Emit warnings with analyzer statistics">, DescFile<"AnalyzerStatsChecker.cpp">; +def TaintTesterChecker : Checker<"TaintTest">, + HelpText<"Mark tainted symbols as such.">, + DescFile<"TaintTesterChecker.cpp">; + } // end "debug" diff --git a/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp new file mode 100644 index 0000000000..0819e86253 --- /dev/null +++ b/lib/StaticAnalyzer/Checkers/TaintTesterChecker.cpp @@ -0,0 +1,62 @@ +//== TaintTesterChecker.cpp ----------------------------------- -*- C++ -*--=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This checker can be used for testing how taint data is propagated. +// +//===----------------------------------------------------------------------===// +#include "ClangSACheckers.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" + +using namespace clang; +using namespace ento; + +namespace { +class TaintTesterChecker : public Checker< check::PostStmt > { + + mutable llvm::OwningPtr BT; + void initBugType() const; + + /// Given a pointer argument, get the symbol of the value it contains + /// (points to). + SymbolRef getPointedToSymbol(CheckerContext &C, + const Expr* Arg, + bool IssueWarning = true) const; + +public: + void checkPostStmt(const Expr *E, CheckerContext &C) const; +}; +} + +inline void TaintTesterChecker::initBugType() const { + if (!BT) + BT.reset(new BugType("Tainted data", "General")); +} + +void TaintTesterChecker::checkPostStmt(const Expr *E, + CheckerContext &C) const { + const ProgramState *State = C.getState(); + if (!State) + return; + + if (E && State->isTainted(E)) { + if (ExplodedNode *N = C.addTransition()) { + initBugType(); + BugReport *report = new BugReport(*BT, "tainted",N); + report->addRange(E->getSourceRange()); + C.EmitReport(report); + } + } +} + +void ento::registerTaintTesterChecker(CheckerManager &mgr) { + mgr.registerChecker(); +} diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c new file mode 100644 index 0000000000..54480beabc --- /dev/null +++ b/test/Analysis/taint-tester.c @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.security.taint,debug.TaintTest -verify %s + +int scanf(const char *restrict format, ...); +int getchar(void); + +#define BUFSIZE 10 +int Buffer[BUFSIZE]; + +void bufferScanfAssignment(int x) { + int n; + int *addr = &Buffer[0]; + scanf("%d", &n); + addr += n;// expected-warning {{tainted}} + *addr = n; // expected-warning {{tainted}} +}