1df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//== GenericTaintChecker.cpp ----------------------------------- -*- C++ -*--=//
2df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//
3df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//                     The LLVM Compiler Infrastructure
4df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//
5df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks// This file is distributed under the University of Illinois Open Source
6df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks// License. See LICENSE.TXT for details.
7df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//
8df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//===----------------------------------------------------------------------===//
9df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//
10df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks// This checker defines the attack surface for generic taint propagation.
11df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//
12df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks// The taint information produced by it might be useful to other checkers. For
13df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks// example, checkers should report errors which involve tainted data more
14df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks// aggressively, even if the involved symbols are under constrained.
15df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//
16df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks//===----------------------------------------------------------------------===//
17df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks#include "ClangSACheckers.h"
1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/Attr.h"
1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Basic/Builtins.h"
2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
21df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks#include "clang/StaticAnalyzer/Core/Checker.h"
22df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks#include "clang/StaticAnalyzer/Core/CheckerManager.h"
23df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
249ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
251fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks#include <climits>
26df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
27df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaksusing namespace clang;
28df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaksusing namespace ento;
29df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
30df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaksnamespace {
31efd6989f4644c8460854606e085fc69535054058Anna Zaksclass GenericTaintChecker : public Checker< check::PostStmt<CallExpr>,
329ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks                                            check::PreStmt<CallExpr> > {
339ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zakspublic:
348568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  static void *getTag() { static int Tag; return &Tag; }
358568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
368568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
378568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
388568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;
39df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
409ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaksprivate:
41b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  static const unsigned InvalidArgIndex = UINT_MAX;
42b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  /// Denotes the return vale.
43b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  static const unsigned ReturnValueIndex = UINT_MAX - 1;
448568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  mutable std::unique_ptr<BugType> BT;
469b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  inline void initBugType() const {
479b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    if (!BT)
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      BT.reset(new BugType(this, "Use of Untrusted Data", "Untrusted Data"));
499b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  }
508f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna Zaks
511fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  /// \brief Catch taint related bugs. Check if tainted data is passed to a
521fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  /// system call etc.
539f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  bool checkPre(const CallExpr *CE, CheckerContext &C) const;
549f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
551fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  /// \brief Add taint sources on a pre-visit.
561fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  void addSourcesPre(const CallExpr *CE, CheckerContext &C) const;
571fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
581fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  /// \brief Propagate taint generated at pre-visit.
591fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  bool propagateFromPre(const CallExpr *CE, CheckerContext &C) const;
601fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
611fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  /// \brief Add taint sources on a post visit.
621fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  void addSourcesPost(const CallExpr *CE, CheckerContext &C) const;
631fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
64b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  /// Check if the region the expression evaluates to is the standard input,
65b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  /// and thus, is tainted.
66b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  static bool isStdin(const Expr *E, CheckerContext &C);
67b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
681fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  /// \brief Given a pointer argument, get the symbol of the value it contains
698f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna Zaks  /// (points to).
707cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks  static SymbolRef getPointedToSymbol(CheckerContext &C, const Expr *Arg);
71df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
729ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  /// Functions defining the attack surface.
738bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  typedef ProgramStateRef (GenericTaintChecker::*FnCheck)(const CallExpr *,
749ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks                                                       CheckerContext &C) const;
758bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef postScanf(const CallExpr *CE, CheckerContext &C) const;
768bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef postSocket(const CallExpr *CE, CheckerContext &C) const;
778bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef postRetTaint(const CallExpr *CE, CheckerContext &C) const;
789ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
799ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  /// Taint the scanned input if the file is tainted.
808bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef preFscanf(const CallExpr *CE, CheckerContext &C) const;
81df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
829f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  /// Check for CWE-134: Uncontrolled Format String.
838568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  static const char MsgUncontrolledFormatString[];
849f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  bool checkUncontrolledFormatString(const CallExpr *CE,
859f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks                                     CheckerContext &C) const;
869f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
878568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  /// Check for:
888568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  /// CERT/STR02-C. "Sanitize data passed to complex subsystems"
898568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  /// CWE-78, "Failure to Sanitize Data into an OS Command"
908568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  static const char MsgSanitizeSystemArgs[];
918568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  bool checkSystemCall(const CallExpr *CE, StringRef Name,
928568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                       CheckerContext &C) const;
939ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
944e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  /// Check if tainted data is used as a buffer size ins strn.. functions,
954e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  /// and allocators.
964e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  static const char MsgTaintedBufferSize[];
974e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  bool checkTaintedBufferSize(const CallExpr *CE, const FunctionDecl *FDecl,
984e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks                              CheckerContext &C) const;
994e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
1008568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  /// Generate a report if the expression is tainted or points to tainted data.
1018568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  bool generateReportIfTainted(const Expr *E, const char Msg[],
1028568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                               CheckerContext &C) const;
103022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
104022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
105cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko  typedef SmallVector<unsigned, 2> ArgVector;
106022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
107022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// \brief A struct used to specify taint propagation rules for a function.
108022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  ///
109022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// If any of the possible taint source arguments is tainted, all of the
110022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// destination arguments should also be tainted. Use InvalidArgIndex in the
111022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// src list to specify that all of the arguments can introduce taint. Use
112022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// InvalidArgIndex in the dst arguments to signify that all the non-const
113022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// pointer and reference arguments might be tainted on return. If
114022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// ReturnValueIndex is added to the dst list, the return value will be
115022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  /// tainted.
116022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  struct TaintPropagationRule {
117022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    /// List of arguments which can be taint sources and should be checked.
118022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    ArgVector SrcArgs;
119022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    /// List of arguments which should be tainted on function return.
120022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    ArgVector DstArgs;
1219b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    // TODO: Check if using other data structures would be more optimal.
122022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
123022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    TaintPropagationRule() {}
124022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
1259b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    TaintPropagationRule(unsigned SArg,
1269b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                         unsigned DArg, bool TaintRet = false) {
127022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      SrcArgs.push_back(SArg);
128022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      DstArgs.push_back(DArg);
1299b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      if (TaintRet)
1309b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks        DstArgs.push_back(ReturnValueIndex);
1319b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    }
1329b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
1339b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    TaintPropagationRule(unsigned SArg1, unsigned SArg2,
1349b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                         unsigned DArg, bool TaintRet = false) {
1359b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      SrcArgs.push_back(SArg1);
1369b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      SrcArgs.push_back(SArg2);
1379b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      DstArgs.push_back(DArg);
1389b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      if (TaintRet)
1399b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks        DstArgs.push_back(ReturnValueIndex);
140022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    }
1419ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
1429b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    /// Get the propagation rule for a given function.
1439b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    static TaintPropagationRule
1449b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      getTaintPropagationRule(const FunctionDecl *FDecl,
1459b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                              StringRef Name,
1469b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                              CheckerContext &C);
1479b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
148022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    inline void addSrcArg(unsigned A) { SrcArgs.push_back(A); }
149022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    inline void addDstArg(unsigned A)  { DstArgs.push_back(A); }
150022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
1519b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    inline bool isNull() const { return SrcArgs.empty(); }
1529b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
1539b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    inline bool isDestinationArgument(unsigned ArgNum) const {
1549b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return (std::find(DstArgs.begin(),
1559b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                        DstArgs.end(), ArgNum) != DstArgs.end());
1569b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    }
157022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
158b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    static inline bool isTaintedOrPointsToTainted(const Expr *E,
1598bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek                                                  ProgramStateRef State,
160b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks                                                  CheckerContext &C) {
161b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks      return (State->isTainted(E, C.getLocationContext()) || isStdin(E, C) ||
162b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks              (E->getType().getTypePtr()->isPointerType() &&
163b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks               State->isTainted(getPointedToSymbol(C, E))));
164b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    }
165b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
1667cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks    /// \brief Pre-process a function which propagates taint according to the
1677cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks    /// taint rule.
1688bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef process(const CallExpr *CE, CheckerContext &C) const;
1697cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks
1707cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks  };
171df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks};
1729b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
1739b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaksconst unsigned GenericTaintChecker::ReturnValueIndex;
1749b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaksconst unsigned GenericTaintChecker::InvalidArgIndex;
1759b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
1768568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaksconst char GenericTaintChecker::MsgUncontrolledFormatString[] =
1775fdadf4b643dd2f7a467244946dc1587b2f9ed1fAnna Zaks  "Untrusted data is used as a format string "
1785fdadf4b643dd2f7a467244946dc1587b2f9ed1fAnna Zaks  "(CWE-134: Uncontrolled Format String)";
1798568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
1808568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaksconst char GenericTaintChecker::MsgSanitizeSystemArgs[] =
1815fdadf4b643dd2f7a467244946dc1587b2f9ed1fAnna Zaks  "Untrusted data is passed to a system call "
1828568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  "(CERT/STR02-C. Sanitize data passed to complex subsystems)";
1834e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
1844e46221e38b7d434fbecb1cd56b259437206d246Anna Zaksconst char GenericTaintChecker::MsgTaintedBufferSize[] =
1855fdadf4b643dd2f7a467244946dc1587b2f9ed1fAnna Zaks  "Untrusted data is used to specify the buffer size "
1864e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  "(CERT/STR31-C. Guarantee that storage for strings has sufficient space for "
1874e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  "character data and the null terminator)";
1884e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
1894e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks} // end of anonymous namespace
190df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
1911fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks/// A set which is used to pass information from call pre-visit instruction
1921fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks/// to the call post-visit. The values are unsigned integers, which are either
1931fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks/// ReturnValueIndex, or indexes of the pointer/reference argument, which
1941fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks/// points to data, which should be tainted on return.
195166d502d5367ceacd1313a33cac43b1048b8524dJordan RoseREGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned)
1969ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
1979b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna ZaksGenericTaintChecker::TaintPropagationRule
1989b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna ZaksGenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
1999b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                                                     const FunctionDecl *FDecl,
2009b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                                                     StringRef Name,
2019b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks                                                     CheckerContext &C) {
202b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  // TODO: Currently, we might loose precision here: we always mark a return
203b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  // value as tainted even if it's just a pointer, pointing to tainted data.
204b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
2059b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // Check for exact name match for functions without builtin substitutes.
2069b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  TaintPropagationRule Rule = llvm::StringSwitch<TaintPropagationRule>(Name)
2079b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    .Case("atoi", TaintPropagationRule(0, ReturnValueIndex))
2089b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    .Case("atol", TaintPropagationRule(0, ReturnValueIndex))
2099b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    .Case("atoll", TaintPropagationRule(0, ReturnValueIndex))
210b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getc", TaintPropagationRule(0, ReturnValueIndex))
211b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("fgetc", TaintPropagationRule(0, ReturnValueIndex))
212b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getc_unlocked", TaintPropagationRule(0, ReturnValueIndex))
213b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getw", TaintPropagationRule(0, ReturnValueIndex))
214b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("toupper", TaintPropagationRule(0, ReturnValueIndex))
215b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("tolower", TaintPropagationRule(0, ReturnValueIndex))
216b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("strchr", TaintPropagationRule(0, ReturnValueIndex))
217b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("strrchr", TaintPropagationRule(0, ReturnValueIndex))
2182bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("read", TaintPropagationRule(0, 2, 1, true))
2192bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("pread", TaintPropagationRule(InvalidArgIndex, 1, true))
220b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("gets", TaintPropagationRule(InvalidArgIndex, 0, true))
221b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("fgets", TaintPropagationRule(2, 0, true))
222b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getline", TaintPropagationRule(2, 0))
223b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getdelim", TaintPropagationRule(3, 0))
224b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("fgetln", TaintPropagationRule(0, ReturnValueIndex))
2259b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    .Default(TaintPropagationRule());
2269b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2279b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  if (!Rule.isNull())
2289b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    return Rule;
2299b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2309b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // Check if it's one of the memory setting/copying functions.
2319b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // This check is specialized but faster then calling isCLibraryFunction.
2329b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  unsigned BId = 0;
2339b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  if ( (BId = FDecl->getMemoryFunctionKind()) )
2349b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    switch(BId) {
2359b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BImemcpy:
2369b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BImemmove:
2379b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BIstrncpy:
2389b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BIstrncat:
2399b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(1, 2, 0, true);
2409b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BIstrlcpy:
2419b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BIstrlcat:
2429b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(1, 2, 0, false);
2439b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    case Builtin::BIstrndup:
2449b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(0, 1, ReturnValueIndex);
2459b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2469b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    default:
2479b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      break;
2489b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    };
2499b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2509b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // Process all other functions which could be defined as builtins.
2519b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  if (Rule.isNull()) {
2529b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    if (C.isCLibraryFunction(FDecl, "snprintf") ||
2539b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks        C.isCLibraryFunction(FDecl, "sprintf"))
2549b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(InvalidArgIndex, 0, true);
2559b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    else if (C.isCLibraryFunction(FDecl, "strcpy") ||
2569b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks             C.isCLibraryFunction(FDecl, "stpcpy") ||
2579b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks             C.isCLibraryFunction(FDecl, "strcat"))
2589b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(1, 0, true);
2599b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    else if (C.isCLibraryFunction(FDecl, "bcopy"))
2609b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(0, 2, 1, false);
2619b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    else if (C.isCLibraryFunction(FDecl, "strdup") ||
2629b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks             C.isCLibraryFunction(FDecl, "strdupa"))
2639b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      return TaintPropagationRule(0, ReturnValueIndex);
2644e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    else if (C.isCLibraryFunction(FDecl, "wcsdup"))
2654e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      return TaintPropagationRule(0, ReturnValueIndex);
2669b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  }
2679b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2689b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // Skipping the following functions, since they might be used for cleansing
2699b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // or smart memory copy:
27048d798ce32447607144db70a484cdb99c1180663Benjamin Kramer  // - memccpy - copying until hitting a special character.
2719b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
2729b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  return TaintPropagationRule();
2738f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna Zaks}
2748f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna Zaks
2759ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaksvoid GenericTaintChecker::checkPreStmt(const CallExpr *CE,
2769ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks                                       CheckerContext &C) const {
2779f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // Check for errors first.
2789f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  if (checkPre(CE, C))
2799f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    return;
280df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
2819f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // Add taint second.
2821fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  addSourcesPre(CE, C);
2839f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks}
2849f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
2859f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaksvoid GenericTaintChecker::checkPostStmt(const CallExpr *CE,
2869f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks                                        CheckerContext &C) const {
2871fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  if (propagateFromPre(CE, C))
2881fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    return;
2891fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  addSourcesPost(CE, C);
2909f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks}
2919f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
2921fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaksvoid GenericTaintChecker::addSourcesPre(const CallExpr *CE,
2931fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks                                        CheckerContext &C) const {
2946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ProgramStateRef State = nullptr;
2959b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
2965ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose  if (!FDecl || FDecl->getKind() != Decl::Function)
2975ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose    return;
2985ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose
2999b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  StringRef Name = C.getCalleeName(FDecl);
3001fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  if (Name.empty())
3011fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    return;
302022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
3039b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // First, try generating a propagation rule for this function.
3049b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  TaintPropagationRule Rule =
3059b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    TaintPropagationRule::getTaintPropagationRule(FDecl, Name, C);
306022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  if (!Rule.isNull()) {
3077cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks    State = Rule.process(CE, C);
308022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    if (!State)
309022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      return;
310022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    C.addTransition(State);
3119b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks    return;
312022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  }
313022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
3149b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks  // Otherwise, check if we have custom pre-processing implemented.
3159ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
3161fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    .Case("fscanf", &GenericTaintChecker::preFscanf)
3176bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    .Default(nullptr);
3189ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  // Check and evaluate the call.
3199ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  if (evalFunction)
3209ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    State = (this->*evalFunction)(CE, C);
3219ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  if (!State)
3229ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    return;
3239ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  C.addTransition(State);
3249b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks
3259ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks}
3269ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
3271fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaksbool GenericTaintChecker::propagateFromPre(const CallExpr *CE,
3281fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks                                           CheckerContext &C) const {
3298bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
3301fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
3311fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  // Depending on what was tainted at pre-visit, we determined a set of
3321fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  // arguments which should be tainted after the function returns. These are
3331fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  // stored in the state as TaintArgsOnPostVisit set.
334166d502d5367ceacd1313a33cac43b1048b8524dJordan Rose  TaintArgsOnPostVisitTy TaintArgs = State->get<TaintArgsOnPostVisit>();
335b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  if (TaintArgs.isEmpty())
336b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    return false;
337b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks
3381fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  for (llvm::ImmutableSet<unsigned>::iterator
3391fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks         I = TaintArgs.begin(), E = TaintArgs.end(); I != E; ++I) {
3401fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    unsigned ArgNum  = *I;
3411fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
3421fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    // Special handling for the tainted return value.
3431fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    if (ArgNum == ReturnValueIndex) {
3441fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks      State = State->addTaint(CE, C.getLocationContext());
3451fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks      continue;
3461fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    }
3471fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
3481fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    // The arguments are pointer arguments. The data they are pointing at is
3491fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    // tainted after the call.
350259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks    if (CE->getNumArgs() < (ArgNum + 1))
351259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks      return false;
3521fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    const Expr* Arg = CE->getArg(ArgNum);
3537cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks    SymbolRef Sym = getPointedToSymbol(C, Arg);
3541fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    if (Sym)
3551fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks      State = State->addTaint(Sym);
3561fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  }
3571fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
3581fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  // Clear up the taint info from the state.
3591fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  State = State->remove<TaintArgsOnPostVisit>();
3601fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
3611fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  if (State != C.getState()) {
3621fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    C.addTransition(State);
3631fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    return true;
3641fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  }
3651fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  return false;
3661fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks}
3671fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
3681fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaksvoid GenericTaintChecker::addSourcesPost(const CallExpr *CE,
3691fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks                                         CheckerContext &C) const {
370df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  // Define the attack surface.
371df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  // Set the evaluation function by switching on the callee name.
3725ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
3735ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose  if (!FDecl || FDecl->getKind() != Decl::Function)
3745ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose    return;
3755ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose
3765ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose  StringRef Name = C.getCalleeName(FDecl);
3771fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  if (Name.empty())
3781fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    return;
379df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  FnCheck evalFunction = llvm::StringSwitch<FnCheck>(Name)
3809ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    .Case("scanf", &GenericTaintChecker::postScanf)
3811009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks    // TODO: Add support for vfscanf & family.
3829ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    .Case("getchar", &GenericTaintChecker::postRetTaint)
383b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getchar_unlocked", &GenericTaintChecker::postRetTaint)
3849ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    .Case("getenv", &GenericTaintChecker::postRetTaint)
3859ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    .Case("fopen", &GenericTaintChecker::postRetTaint)
3869ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    .Case("fdopen", &GenericTaintChecker::postRetTaint)
3879ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    .Case("freopen", &GenericTaintChecker::postRetTaint)
388b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("getch", &GenericTaintChecker::postRetTaint)
389b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("wgetch", &GenericTaintChecker::postRetTaint)
3902bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("socket", &GenericTaintChecker::postSocket)
3916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    .Default(nullptr);
392df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
393df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  // If the callee isn't defined, it is not of security concern.
394df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  // Check and evaluate the call.
3956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  ProgramStateRef State = nullptr;
396df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  if (evalFunction)
3979ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    State = (this->*evalFunction)(CE, C);
3989ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  if (!State)
3999ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks    return;
400df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
4019ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  C.addTransition(State);
402df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks}
4038f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna Zaks
4049f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaksbool GenericTaintChecker::checkPre(const CallExpr *CE, CheckerContext &C) const{
4059f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
4069f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  if (checkUncontrolledFormatString(CE, C))
4079f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    return true;
4089f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
4094e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
4105ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose  if (!FDecl || FDecl->getKind() != Decl::Function)
4115ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose    return false;
4125ef6e94b294cc47750d8ab220858a36726caba59Jordan Rose
4134e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  StringRef Name = C.getCalleeName(FDecl);
4148568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  if (Name.empty())
4158568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return false;
4168568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
4178568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  if (checkSystemCall(CE, Name, C))
4188568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return true;
4198568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
4204e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  if (checkTaintedBufferSize(CE, FDecl, C))
4214e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    return true;
4224e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
4239f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  return false;
4249f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks}
4259f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
4268f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna ZaksSymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
4277cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks                                                  const Expr* Arg) {
4288bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
4295eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal AddrVal = State->getSVal(Arg->IgnoreParens(), C.getLocationContext());
430d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  if (AddrVal.isUnknownOrUndef())
4316bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
432e3d250e488241cbfe71a592df4d07d03ad89434aAnna Zaks
433dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie  Optional<Loc> AddrLoc = AddrVal.getAs<Loc>();
4347cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks  if (!AddrLoc)
4356bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
4368f4caf5fec2de9b18f9c5fc69696d9f6cf66bcc5Anna Zaks
43771d29095d27e94b00083259c06a45f5294501697Anna Zaks  const PointerType *ArgTy =
43871d29095d27e94b00083259c06a45f5294501697Anna Zaks    dyn_cast<PointerType>(Arg->getType().getCanonicalType().getTypePtr());
439665b00265858a47f3ccd80b2f27b250c54f5fd5dAnna Zaks  SVal Val = State->getSVal(*AddrLoc,
440665b00265858a47f3ccd80b2f27b250c54f5fd5dAnna Zaks                            ArgTy ? ArgTy->getPointeeType(): QualType());
441df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  return Val.getAsSymbol();
442df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks}
443df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
4448bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef
4457cdfe298ae49e381f6d78fc93855c372e5173dd0Anna ZaksGenericTaintChecker::TaintPropagationRule::process(const CallExpr *CE,
4467cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks                                                   CheckerContext &C) const {
4478bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
448022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
449022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  // Check for taint in arguments.
450022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  bool IsTainted = false;
4517cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks  for (ArgVector::const_iterator I = SrcArgs.begin(),
4527cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks                                 E = SrcArgs.end(); I != E; ++I) {
453022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    unsigned ArgNum = *I;
454022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
455022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    if (ArgNum == InvalidArgIndex) {
4569b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      // Check if any of the arguments is tainted, but skip the
4579b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      // destination arguments.
4589b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      for (unsigned int i = 0; i < CE->getNumArgs(); ++i) {
4597cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks        if (isDestinationArgument(i))
4609b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks          continue;
461b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks        if ((IsTainted = isTaintedOrPointsToTainted(CE->getArg(i), State, C)))
462022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks          break;
4639b0c749a20d0f7d0e63441d76baa15def3f37fdbAnna Zaks      }
464022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      break;
465022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    }
466022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
467259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks    if (CE->getNumArgs() < (ArgNum + 1))
468259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks      return State;
469b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    if ((IsTainted = isTaintedOrPointsToTainted(CE->getArg(ArgNum), State, C)))
470022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      break;
471022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  }
472022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  if (!IsTainted)
473022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    return State;
474022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
475022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  // Mark the arguments which should be tainted after the function returns.
4767cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks  for (ArgVector::const_iterator I = DstArgs.begin(),
4777cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks                                 E = DstArgs.end(); I != E; ++I) {
478022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    unsigned ArgNum = *I;
479022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
480022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    // Should we mark all arguments as tainted?
481022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    if (ArgNum == InvalidArgIndex) {
482022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      // For all pointer and references that were passed in:
483022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      //   If they are not pointing to const data, mark data as tainted.
484022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      //   TODO: So far we are just going one level down; ideally we'd need to
485022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      //         recurse here.
486022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      for (unsigned int i = 0; i < CE->getNumArgs(); ++i) {
487022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks        const Expr *Arg = CE->getArg(i);
488022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks        // Process pointer argument.
489022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks        const Type *ArgTy = Arg->getType().getTypePtr();
490022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks        QualType PType = ArgTy->getPointeeType();
491022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks        if ((!PType.isNull() && !PType.isConstQualified())
492022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks            || (ArgTy->isReferenceType() && !Arg->getType().isConstQualified()))
493022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks          State = State->add<TaintArgsOnPostVisit>(i);
494022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      }
495022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      continue;
496022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    }
497022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
498022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    // Should mark the return value?
499022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    if (ArgNum == ReturnValueIndex) {
500022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      State = State->add<TaintArgsOnPostVisit>(ReturnValueIndex);
501022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks      continue;
502022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    }
503022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
504022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    // Mark the given argument.
505022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    assert(ArgNum < CE->getNumArgs());
506022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks    State = State->add<TaintArgsOnPostVisit>(ArgNum);
507022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  }
508022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
509022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks  return State;
510022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks}
511022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
512022b3f4490bbdcde7b3f18ce0498f9a73b6cbf53Anna Zaks
5131fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks// If argument 0 (file descriptor) is tainted, all arguments except for arg 0
5141fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks// and arg 1 should get taint.
5158bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef GenericTaintChecker::preFscanf(const CallExpr *CE,
5169ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks                                                   CheckerContext &C) const {
5179ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  assert(CE->getNumArgs() >= 2);
5188bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
5199ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
5209ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  // Check is the file descriptor is tainted.
5215eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  if (State->isTainted(CE->getArg(0), C.getLocationContext()) ||
5221fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks      isStdin(CE->getArg(0), C)) {
5231fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    // All arguments except for the first two should get taint.
5241fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    for (unsigned int i = 2; i < CE->getNumArgs(); ++i)
5251fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks        State = State->add<TaintArgsOnPostVisit>(i);
5261fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks    return State;
5271fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks  }
5281fb826a6fd893234f32b0b91bb92ea4d127788adAnna Zaks
5296bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
5309ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks}
5319ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks
5322bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks
5332bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks// If argument 0(protocol domain) is network, the return value should get taint.
5348bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef GenericTaintChecker::postSocket(const CallExpr *CE,
535259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks                                                CheckerContext &C) const {
5368bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
537259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks  if (CE->getNumArgs() < 3)
538259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks    return State;
5392bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks
5402bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks  SourceLocation DomLoc = CE->getArg(0)->getExprLoc();
5412bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks  StringRef DomName = C.getMacroNameOrSpelling(DomLoc);
5422bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks  // White list the internal communication protocols.
5432bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks  if (DomName.equals("AF_SYSTEM") || DomName.equals("AF_LOCAL") ||
5442bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks      DomName.equals("AF_UNIX") || DomName.equals("AF_RESERVED_36"))
5452bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    return State;
5462bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks  State = State->addTaint(CE, C.getLocationContext());
5472bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks  return State;
5482bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks}
5492bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks
5508bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef GenericTaintChecker::postScanf(const CallExpr *CE,
5519ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks                                                   CheckerContext &C) const {
5528bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
553259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks  if (CE->getNumArgs() < 2)
554259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks    return State;
555259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks
556df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  // All arguments except for the very first one should get taint.
557df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  for (unsigned int i = 1; i < CE->getNumArgs(); ++i) {
558df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks    // The arguments are pointer arguments. The data they are pointing at is
559df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks    // tainted after the call.
560df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks    const Expr* Arg = CE->getArg(i);
5617cdfe298ae49e381f6d78fc93855c372e5173dd0Anna Zaks        SymbolRef Sym = getPointedToSymbol(C, Arg);
5621009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks    if (Sym)
5631009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks      State = State->addTaint(Sym);
5641009ac715501a4fa1951d94722dcbe6ab30068f8Anna Zaks  }
5659ffbe243cca46082b4a59b5c3be454ab0c455378Anna Zaks  return State;
566df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks}
567df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
5688bef8238181a30e52dea380789a7e2d760eac532Ted KremenekProgramStateRef GenericTaintChecker::postRetTaint(const CallExpr *CE,
569259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks                                                  CheckerContext &C) const {
5705eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  return C.getState()->addTaint(CE, C.getLocationContext());
571df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks}
572df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks
573b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaksbool GenericTaintChecker::isStdin(const Expr *E, CheckerContext &C) {
5748bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
5755eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal Val = State->getSVal(E, C.getLocationContext());
576efd6989f4644c8460854606e085fc69535054058Anna Zaks
577d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  // stdin is a pointer, so it would be a region.
578d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  const MemRegion *MemReg = Val.getAsRegion();
579d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks
580d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  // The region should be symbolic, we do not know it's value.
581d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  const SymbolicRegion *SymReg = dyn_cast_or_null<SymbolicRegion>(MemReg);
582d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  if (!SymReg)
583efd6989f4644c8460854606e085fc69535054058Anna Zaks    return false;
584efd6989f4644c8460854606e085fc69535054058Anna Zaks
585d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  // Get it's symbol and find the declaration region it's pointing to.
586d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  const SymbolRegionValue *Sm =dyn_cast<SymbolRegionValue>(SymReg->getSymbol());
587d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  if (!Sm)
588d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks    return false;
589d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  const DeclRegion *DeclReg = dyn_cast_or_null<DeclRegion>(Sm->getRegion());
590d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  if (!DeclReg)
591d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks    return false;
592efd6989f4644c8460854606e085fc69535054058Anna Zaks
593d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  // This region corresponds to a declaration, find out if it's a global/extern
594d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  // variable named stdin with the proper type.
595d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  if (const VarDecl *D = dyn_cast_or_null<VarDecl>(DeclReg->getDecl())) {
596d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks    D = D->getCanonicalDecl();
597d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks    if ((D->getName().find("stdin") != StringRef::npos) && D->isExternC())
598d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks        if (const PointerType * PtrTy =
599d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks              dyn_cast<PointerType>(D->getType().getTypePtr()))
600d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks          if (PtrTy->getPointeeType() == C.getASTContext().getFILEType())
601d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks            return true;
602d3d8548e75f3fb6db53ed0927c1df30d78f4ce1dAnna Zaks  }
603efd6989f4644c8460854606e085fc69535054058Anna Zaks  return false;
604efd6989f4644c8460854606e085fc69535054058Anna Zaks}
605efd6989f4644c8460854606e085fc69535054058Anna Zaks
6069f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaksstatic bool getPrintfFormatArgumentNum(const CallExpr *CE,
6079f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks                                       const CheckerContext &C,
6089f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks                                       unsigned int &ArgNum) {
6099f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // Find if the function contains a format string argument.
6109f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // Handles: fprintf, printf, sprintf, snprintf, vfprintf, vprintf, vsprintf,
6119f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // vsnprintf, syslog, custom annotated functions.
6129f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
6139f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  if (!FDecl)
6149f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    return false;
615651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  for (const auto *Format : FDecl->specific_attrs<FormatAttr>()) {
6169f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    ArgNum = Format->getFormatIdx() - 1;
617caa5ab264ddea332e8423af1ebcea50d0cb37206Aaron Ballman    if ((Format->getType()->getName() == "printf") &&
618caa5ab264ddea332e8423af1ebcea50d0cb37206Aaron Ballman         CE->getNumArgs() > ArgNum)
6199f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks      return true;
6209f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  }
6219f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
6229f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // Or if a function is named setproctitle (this is a heuristic).
6239f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  if (C.getCalleeName(CE).find("setproctitle") != StringRef::npos) {
6249f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    ArgNum = 0;
6259f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    return true;
6269f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  }
6279f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
6289f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  return false;
6299f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks}
6309f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
6318568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaksbool GenericTaintChecker::generateReportIfTainted(const Expr *E,
6328568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                                                  const char Msg[],
6338568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                                                  CheckerContext &C) const {
6348568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  assert(E);
6358568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
6368568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  // Check for taint.
6378bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef State = C.getState();
6388568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  if (!State->isTainted(getPointedToSymbol(C, E)) &&
6398568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks      !State->isTainted(E, C.getLocationContext()))
6408568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return false;
6418568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
6428568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  // Generate diagnostic.
6438568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  if (ExplodedNode *N = C.addTransition()) {
6448568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    initBugType();
6458568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    BugReport *report = new BugReport(*BT, Msg, N);
6468568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    report->addRange(E->getSourceRange());
647785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose    C.emitReport(report);
6488568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return true;
6498568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  }
6508568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  return false;
6518568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks}
6528568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
6539f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaksbool GenericTaintChecker::checkUncontrolledFormatString(const CallExpr *CE,
6549f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks                                                        CheckerContext &C) const{
6559f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // Check if the function contains a format string argument.
6569f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  unsigned int ArgNum = 0;
6579f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  if (!getPrintfFormatArgumentNum(CE, C, ArgNum))
6589f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks    return false;
6599f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
6609f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  // If either the format string content or the pointer itself are tainted, warn.
6618568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  if (generateReportIfTainted(CE->getArg(ArgNum),
6628568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                              MsgUncontrolledFormatString, C))
6638568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return true;
6648568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  return false;
6658568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks}
6668568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
6678568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaksbool GenericTaintChecker::checkSystemCall(const CallExpr *CE,
6688568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                                          StringRef Name,
6698568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                                          CheckerContext &C) const {
670b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  // TODO: It might make sense to run this check on demand. In some cases,
671b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  // we should check if the environment has been cleansed here. We also might
672b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks  // need to know if the user was reset before these calls(seteuid).
6738568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  unsigned ArgNum = llvm::StringSwitch<unsigned>(Name)
6748568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    .Case("system", 0)
6758568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    .Case("popen", 0)
6762bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("execl", 0)
6772bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("execle", 0)
6782bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("execlp", 0)
6792bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("execv", 0)
6802bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("execvp", 0)
6812bf8fd84087231fd92dfdebe18895e01a6ae405cAnna Zaks    .Case("execvP", 0)
682b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("execve", 0)
683b9ac30cf9ec001fd0d63ffc44289a333a21e691dAnna Zaks    .Case("dlopen", 0)
6848568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    .Default(UINT_MAX);
6858568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
686259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks  if (ArgNum == UINT_MAX || CE->getNumArgs() < (ArgNum + 1))
6878568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return false;
6888568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
6898568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks  if (generateReportIfTainted(CE->getArg(ArgNum),
6908568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks                              MsgSanitizeSystemArgs, C))
6918568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks    return true;
6928568ee743406ac4bb23c9768a0dffd627fdbc579Anna Zaks
6939f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks  return false;
6949f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks}
6959f03b62036a7abc0a227b17f4a49b9eefced9450Anna Zaks
6964e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks// TODO: Should this check be a part of the CString checker?
6974e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks// If yes, should taint be a global setting?
6984e46221e38b7d434fbecb1cd56b259437206d246Anna Zaksbool GenericTaintChecker::checkTaintedBufferSize(const CallExpr *CE,
6994e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks                                                 const FunctionDecl *FDecl,
7004e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks                                                 CheckerContext &C) const {
7014e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  // If the function has a buffer size argument, set ArgNum.
7024e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  unsigned ArgNum = InvalidArgIndex;
7034e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  unsigned BId = 0;
7044e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  if ( (BId = FDecl->getMemoryFunctionKind()) )
7054e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    switch(BId) {
7064e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    case Builtin::BImemcpy:
7074e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    case Builtin::BImemmove:
7084e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    case Builtin::BIstrncpy:
7094e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      ArgNum = 2;
7104e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      break;
7114e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    case Builtin::BIstrndup:
7124e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      ArgNum = 1;
7134e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      break;
7144e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    default:
7154e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      break;
7164e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    };
7174e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
7184e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  if (ArgNum == InvalidArgIndex) {
7194e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    if (C.isCLibraryFunction(FDecl, "malloc") ||
7204e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks        C.isCLibraryFunction(FDecl, "calloc") ||
7214e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks        C.isCLibraryFunction(FDecl, "alloca"))
7224e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      ArgNum = 0;
7234e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    else if (C.isCLibraryFunction(FDecl, "memccpy"))
7244e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      ArgNum = 3;
7254e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    else if (C.isCLibraryFunction(FDecl, "realloc"))
7264e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      ArgNum = 1;
7274e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    else if (C.isCLibraryFunction(FDecl, "bcopy"))
7284e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      ArgNum = 2;
7294e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  }
7304e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
731259052d8c819d101f6f627f960f56e582ecbcebcAnna Zaks  if (ArgNum != InvalidArgIndex && CE->getNumArgs() > ArgNum &&
7324e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks      generateReportIfTainted(CE->getArg(ArgNum), MsgTaintedBufferSize, C))
7334e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks    return true;
7344e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
7354e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks  return false;
7364e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks}
7374e46221e38b7d434fbecb1cd56b259437206d246Anna Zaks
738df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaksvoid ento::registerGenericTaintChecker(CheckerManager &mgr) {
739df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks  mgr.registerChecker<GenericTaintChecker>();
740df18c5ae6c48d3b56f7f9550875c53dc46eb8d78Anna Zaks}
741