17330f729Sjoerg //=== Taint.h - Taint tracking and basic propagation rules. --------*- C++ -*-// 27330f729Sjoerg // 37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information. 57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 67330f729Sjoerg // 77330f729Sjoerg //===----------------------------------------------------------------------===// 87330f729Sjoerg // 97330f729Sjoerg // Defines basic, non-domain-specific mechanisms for tracking tainted values. 107330f729Sjoerg // 117330f729Sjoerg //===----------------------------------------------------------------------===// 127330f729Sjoerg 137330f729Sjoerg #ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAINT_H 147330f729Sjoerg #define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_TAINT_H 157330f729Sjoerg 167330f729Sjoerg #include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h" 177330f729Sjoerg #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 187330f729Sjoerg 197330f729Sjoerg namespace clang { 207330f729Sjoerg namespace ento { 217330f729Sjoerg namespace taint { 227330f729Sjoerg 237330f729Sjoerg /// The type of taint, which helps to differentiate between different types of 247330f729Sjoerg /// taint. 257330f729Sjoerg using TaintTagType = unsigned; 267330f729Sjoerg 277330f729Sjoerg static constexpr TaintTagType TaintTagGeneric = 0; 287330f729Sjoerg 297330f729Sjoerg /// Create a new state in which the value of the statement is marked as tainted. 30*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, const Stmt *S, 31*e038c9c4Sjoerg const LocationContext *LCtx, 327330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 337330f729Sjoerg 347330f729Sjoerg /// Create a new state in which the value is marked as tainted. 35*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, SVal V, 367330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 377330f729Sjoerg 387330f729Sjoerg /// Create a new state in which the symbol is marked as tainted. 39*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, SymbolRef Sym, 407330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 417330f729Sjoerg 427330f729Sjoerg /// Create a new state in which the pointer represented by the region 437330f729Sjoerg /// is marked as tainted. 44*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef addTaint(ProgramStateRef State, 45*e038c9c4Sjoerg const MemRegion *R, 467330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 477330f729Sjoerg 48*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State, SVal V); 49*e038c9c4Sjoerg 50*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State, 51*e038c9c4Sjoerg const MemRegion *R); 52*e038c9c4Sjoerg 53*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef removeTaint(ProgramStateRef State, 54*e038c9c4Sjoerg SymbolRef Sym); 55*e038c9c4Sjoerg 567330f729Sjoerg /// Create a new state in a which a sub-region of a given symbol is tainted. 577330f729Sjoerg /// This might be necessary when referring to regions that can not have an 587330f729Sjoerg /// individual symbol, e.g. if they are represented by the default binding of 597330f729Sjoerg /// a LazyCompoundVal. 60*e038c9c4Sjoerg LLVM_NODISCARD ProgramStateRef addPartialTaint( 61*e038c9c4Sjoerg ProgramStateRef State, SymbolRef ParentSym, const SubRegion *SubRegion, 627330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 637330f729Sjoerg 647330f729Sjoerg /// Check if the statement has a tainted value in the given state. 657330f729Sjoerg bool isTainted(ProgramStateRef State, const Stmt *S, 667330f729Sjoerg const LocationContext *LCtx, 677330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 687330f729Sjoerg 697330f729Sjoerg /// Check if the value is tainted in the given state. 707330f729Sjoerg bool isTainted(ProgramStateRef State, SVal V, 717330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 727330f729Sjoerg 737330f729Sjoerg /// Check if the symbol is tainted in the given state. 747330f729Sjoerg bool isTainted(ProgramStateRef State, SymbolRef Sym, 757330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 767330f729Sjoerg 777330f729Sjoerg /// Check if the pointer represented by the region is tainted in the given 787330f729Sjoerg /// state. 797330f729Sjoerg bool isTainted(ProgramStateRef State, const MemRegion *Reg, 807330f729Sjoerg TaintTagType Kind = TaintTagGeneric); 817330f729Sjoerg 827330f729Sjoerg void printTaint(ProgramStateRef State, raw_ostream &Out, const char *nl = "\n", 837330f729Sjoerg const char *sep = ""); 847330f729Sjoerg 857330f729Sjoerg LLVM_DUMP_METHOD void dumpTaint(ProgramStateRef State); 867330f729Sjoerg 877330f729Sjoerg /// The bug visitor prints a diagnostic message at the location where a given 887330f729Sjoerg /// variable was tainted. 897330f729Sjoerg class TaintBugVisitor final : public BugReporterVisitor { 907330f729Sjoerg private: 917330f729Sjoerg const SVal V; 927330f729Sjoerg 937330f729Sjoerg public: TaintBugVisitor(const SVal V)947330f729Sjoerg TaintBugVisitor(const SVal V) : V(V) {} Profile(llvm::FoldingSetNodeID & ID)957330f729Sjoerg void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); } 967330f729Sjoerg 977330f729Sjoerg PathDiagnosticPieceRef VisitNode(const ExplodedNode *N, 987330f729Sjoerg BugReporterContext &BRC, 997330f729Sjoerg PathSensitiveBugReport &BR) override; 1007330f729Sjoerg }; 1017330f729Sjoerg 1027330f729Sjoerg } // namespace taint 1037330f729Sjoerg } // namespace ento 1047330f729Sjoerg } // namespace clang 1057330f729Sjoerg 1067330f729Sjoerg #endif 107