003 File Manager
Current Path:
/usr/src/contrib/llvm-project/clang/lib/StaticAnalyzer/Checkers
usr
/
src
/
contrib
/
llvm-project
/
clang
/
lib
/
StaticAnalyzer
/
Checkers
/
📁
..
📄
AllocationState.h
(1.41 KB)
📄
AnalysisOrderChecker.cpp
(8.62 KB)
📄
AnalyzerStatsChecker.cpp
(5.04 KB)
📄
ArrayBoundChecker.cpp
(3.22 KB)
📄
ArrayBoundCheckerV2.cpp
(13.07 KB)
📄
BasicObjCFoundationChecks.cpp
(43.82 KB)
📄
BlockInCriticalSectionChecker.cpp
(6.69 KB)
📄
BoolAssignmentChecker.cpp
(3.45 KB)
📄
BuiltinFunctionChecker.cpp
(5 KB)
📄
CStringChecker.cpp
(93.24 KB)
📄
CStringSyntaxChecker.cpp
(9.8 KB)
📄
CXXSelfAssignmentChecker.cpp
(3.08 KB)
📄
CallAndMessageChecker.cpp
(26.57 KB)
📄
CastSizeChecker.cpp
(4.96 KB)
📄
CastToStructChecker.cpp
(4.43 KB)
📄
CastValueChecker.cpp
(19.65 KB)
📄
CheckObjCDealloc.cpp
(37.83 KB)
📄
CheckObjCInstMethSignature.cpp
(4.8 KB)
📄
CheckPlacementNew.cpp
(11.91 KB)
📄
CheckSecuritySyntaxOnly.cpp
(38.79 KB)
📄
CheckSizeofPointer.cpp
(3.16 KB)
📄
CheckerDocumentation.cpp
(14.64 KB)
📄
ChrootChecker.cpp
(4.88 KB)
📄
CloneChecker.cpp
(8.28 KB)
📄
ContainerModeling.cpp
(39.85 KB)
📄
ConversionChecker.cpp
(7.11 KB)
📄
DeadStoresChecker.cpp
(17.82 KB)
📄
DebugCheckers.cpp
(10.41 KB)
📄
DebugContainerModeling.cpp
(4.94 KB)
📄
DebugIteratorModeling.cpp
(5.15 KB)
📄
DeleteWithNonVirtualDtorChecker.cpp
(5.35 KB)
📄
DereferenceChecker.cpp
(10.54 KB)
📄
DirectIvarAssignment.cpp
(8.02 KB)
📄
DivZeroChecker.cpp
(3.42 KB)
📄
DynamicTypeChecker.cpp
(7.31 KB)
📄
DynamicTypePropagation.cpp
(42.11 KB)
📄
EnumCastOutOfRangeChecker.cpp
(5.75 KB)
📄
ExprInspectionChecker.cpp
(15.6 KB)
📄
FixedAddressChecker.cpp
(2.33 KB)
📄
FuchsiaHandleChecker.cpp
(23.1 KB)
📄
GCDAntipatternChecker.cpp
(7.85 KB)
📄
GTestChecker.cpp
(10.52 KB)
📄
GenericTaintChecker.cpp
(34.31 KB)
📄
IdenticalExprChecker.cpp
(18.88 KB)
📄
InnerPointerChecker.cpp
(11.54 KB)
📄
InterCheckerAPI.h
(1.09 KB)
📄
InvalidatedIteratorChecker.cpp
(4.93 KB)
📄
Iterator.cpp
(10.62 KB)
📄
Iterator.h
(6.32 KB)
📄
IteratorModeling.cpp
(31.33 KB)
📄
IteratorRangeChecker.cpp
(12.64 KB)
📄
IvarInvalidationChecker.cpp
(27.63 KB)
📄
LLVMConventionsChecker.cpp
(9.9 KB)
📄
LocalizationChecker.cpp
(52.38 KB)
📄
MIGChecker.cpp
(11.3 KB)
📁
MPI-Checker
📄
MacOSKeychainAPIChecker.cpp
(25.21 KB)
📄
MacOSXAPIChecker.cpp
(6.61 KB)
📄
MallocChecker.cpp
(127.38 KB)
📄
MallocOverflowSecurityChecker.cpp
(11.91 KB)
📄
MallocSizeofChecker.cpp
(8.03 KB)
📄
MismatchedIteratorChecker.cpp
(11.01 KB)
📄
MmapWriteExecChecker.cpp
(3.22 KB)
📄
Move.h
(1.07 KB)
📄
MoveChecker.cpp
(27 KB)
📄
NSAutoreleasePoolChecker.cpp
(2.93 KB)
📄
NSErrorChecker.cpp
(10.6 KB)
📄
NoReturnFunctionChecker.cpp
(5.48 KB)
📄
NonNullParamChecker.cpp
(11.22 KB)
📄
NonnullGlobalConstantsChecker.cpp
(5.09 KB)
📄
NullabilityChecker.cpp
(46.95 KB)
📄
NumberObjectConversionChecker.cpp
(13.69 KB)
📄
OSObjectCStyleCast.cpp
(3.14 KB)
📄
ObjCAtSyncChecker.cpp
(3.34 KB)
📄
ObjCAutoreleaseWriteChecker.cpp
(8.62 KB)
📄
ObjCContainersASTChecker.cpp
(5.5 KB)
📄
ObjCContainersChecker.cpp
(6.71 KB)
📄
ObjCMissingSuperCallChecker.cpp
(9.23 KB)
📄
ObjCPropertyChecker.cpp
(3.03 KB)
📄
ObjCSelfInitChecker.cpp
(16.21 KB)
📄
ObjCSuperDeallocChecker.cpp
(9.33 KB)
📄
ObjCUnusedIVarsChecker.cpp
(6.01 KB)
📄
PaddingChecker.cpp
(14.26 KB)
📄
PointerArithChecker.cpp
(12.18 KB)
📄
PointerIterationChecker.cpp
(3.79 KB)
📄
PointerSortingChecker.cpp
(4.5 KB)
📄
PointerSubChecker.cpp
(2.56 KB)
📄
PthreadLockChecker.cpp
(28.42 KB)
📁
RetainCountChecker
📄
ReturnPointerRangeChecker.cpp
(3.39 KB)
📄
ReturnUndefChecker.cpp
(4.1 KB)
📄
ReturnValueChecker.cpp
(5.79 KB)
📄
RunLoopAutoreleaseLeakChecker.cpp
(7.2 KB)
📄
STLAlgorithmModeling.cpp
(7 KB)
📄
SimpleStreamChecker.cpp
(9.43 KB)
📄
SmartPtr.h
(1.17 KB)
📄
SmartPtrChecker.cpp
(2.68 KB)
📄
SmartPtrModeling.cpp
(8.05 KB)
📄
StackAddrEscapeChecker.cpp
(15 KB)
📄
StdLibraryFunctionsChecker.cpp
(74.86 KB)
📄
StreamChecker.cpp
(37.36 KB)
📄
Taint.cpp
(9.04 KB)
📄
Taint.h
(4.19 KB)
📄
TaintTesterChecker.cpp
(2.17 KB)
📄
TestAfterDivZeroChecker.cpp
(8.19 KB)
📄
TraversalChecker.cpp
(4.38 KB)
📄
TrustNonnullChecker.cpp
(9.12 KB)
📄
UndefBranchChecker.cpp
(3.82 KB)
📄
UndefCapturedBlockVarChecker.cpp
(3.64 KB)
📄
UndefResultChecker.cpp
(7.19 KB)
📄
UndefinedArraySubscriptChecker.cpp
(2.36 KB)
📄
UndefinedAssignmentChecker.cpp
(3.74 KB)
📁
UninitializedObject
📄
UnixAPIChecker.cpp
(18.05 KB)
📄
UnreachableCodeChecker.cpp
(9.59 KB)
📄
VLASizeChecker.cpp
(10.95 KB)
📄
ValistChecker.cpp
(15.65 KB)
📄
VforkChecker.cpp
(7.67 KB)
📄
VirtualCallChecker.cpp
(8.11 KB)
📁
WebKit
📄
Yaml.h
(2.06 KB)
📁
cert
Editing: Taint.cpp
//=== Taint.cpp - Taint tracking and basic propagation rules. ------*- C++ -*-// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Defines basic, non-domain-specific mechanisms for tracking tainted values. // //===----------------------------------------------------------------------===// #include "Taint.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" using namespace clang; using namespace ento; using namespace taint; // Fully tainted symbols. REGISTER_MAP_WITH_PROGRAMSTATE(TaintMap, SymbolRef, TaintTagType) // Partially tainted symbols. REGISTER_MAP_FACTORY_WITH_PROGRAMSTATE(TaintedSubRegions, const SubRegion *, TaintTagType) REGISTER_MAP_WITH_PROGRAMSTATE(DerivedSymTaint, SymbolRef, TaintedSubRegions) void taint::printTaint(ProgramStateRef State, raw_ostream &Out, const char *NL, const char *Sep) { TaintMapTy TM = State->get<TaintMap>(); if (!TM.isEmpty()) Out << "Tainted symbols:" << NL; for (const auto &I : TM) Out << I.first << " : " << I.second << NL; } void dumpTaint(ProgramStateRef State) { printTaint(State, llvm::errs()); } ProgramStateRef taint::addTaint(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind) { return addTaint(State, State->getSVal(S, LCtx), Kind); } ProgramStateRef taint::addTaint(ProgramStateRef State, SVal V, TaintTagType Kind) { SymbolRef Sym = V.getAsSymbol(); if (Sym) return addTaint(State, Sym, Kind); // If the SVal represents a structure, try to mass-taint all values within the // structure. For now it only works efficiently on lazy compound values that // were conjured during a conservative evaluation of a function - either as // return values of functions that return structures or arrays by value, or as // values of structures or arrays passed into the function by reference, // directly or through pointer aliasing. Such lazy compound values are // characterized by having exactly one binding in their captured store within // their parent region, which is a conjured symbol default-bound to the base // region of the parent region. if (auto LCV = V.getAs<nonloc::LazyCompoundVal>()) { if (Optional<SVal> binding = State->getStateManager().getStoreManager().getDefaultBinding( *LCV)) { if (SymbolRef Sym = binding->getAsSymbol()) return addPartialTaint(State, Sym, LCV->getRegion(), Kind); } } const MemRegion *R = V.getAsRegion(); return addTaint(State, R, Kind); } ProgramStateRef taint::addTaint(ProgramStateRef State, const MemRegion *R, TaintTagType Kind) { if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R)) return addTaint(State, SR->getSymbol(), Kind); return State; } ProgramStateRef taint::addTaint(ProgramStateRef State, SymbolRef Sym, TaintTagType Kind) { // If this is a symbol cast, remove the cast before adding the taint. Taint // is cast agnostic. while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) Sym = SC->getOperand(); ProgramStateRef NewState = State->set<TaintMap>(Sym, Kind); assert(NewState); return NewState; } ProgramStateRef taint::removeTaint(ProgramStateRef State, SVal V) { SymbolRef Sym = V.getAsSymbol(); if (Sym) return removeTaint(State, Sym); const MemRegion *R = V.getAsRegion(); return removeTaint(State, R); } ProgramStateRef taint::removeTaint(ProgramStateRef State, const MemRegion *R) { if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R)) return removeTaint(State, SR->getSymbol()); return State; } ProgramStateRef taint::removeTaint(ProgramStateRef State, SymbolRef Sym) { // If this is a symbol cast, remove the cast before adding the taint. Taint // is cast agnostic. while (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) Sym = SC->getOperand(); ProgramStateRef NewState = State->remove<TaintMap>(Sym); assert(NewState); return NewState; } ProgramStateRef taint::addPartialTaint(ProgramStateRef State, SymbolRef ParentSym, const SubRegion *SubRegion, TaintTagType Kind) { // Ignore partial taint if the entire parent symbol is already tainted. if (const TaintTagType *T = State->get<TaintMap>(ParentSym)) if (*T == Kind) return State; // Partial taint applies if only a portion of the symbol is tainted. if (SubRegion == SubRegion->getBaseRegion()) return addTaint(State, ParentSym, Kind); const TaintedSubRegions *SavedRegs = State->get<DerivedSymTaint>(ParentSym); TaintedSubRegions::Factory &F = State->get_context<TaintedSubRegions>(); TaintedSubRegions Regs = SavedRegs ? *SavedRegs : F.getEmptyMap(); Regs = F.add(Regs, SubRegion, Kind); ProgramStateRef NewState = State->set<DerivedSymTaint>(ParentSym, Regs); assert(NewState); return NewState; } bool taint::isTainted(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind) { SVal val = State->getSVal(S, LCtx); return isTainted(State, val, Kind); } bool taint::isTainted(ProgramStateRef State, SVal V, TaintTagType Kind) { if (const SymExpr *Sym = V.getAsSymExpr()) return isTainted(State, Sym, Kind); if (const MemRegion *Reg = V.getAsRegion()) return isTainted(State, Reg, Kind); return false; } bool taint::isTainted(ProgramStateRef State, const MemRegion *Reg, TaintTagType K) { if (!Reg) return false; // Element region (array element) is tainted if either the base or the offset // are tainted. if (const ElementRegion *ER = dyn_cast<ElementRegion>(Reg)) return isTainted(State, ER->getSuperRegion(), K) || isTainted(State, ER->getIndex(), K); if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) return isTainted(State, SR->getSymbol(), K); if (const SubRegion *ER = dyn_cast<SubRegion>(Reg)) return isTainted(State, ER->getSuperRegion(), K); return false; } bool taint::isTainted(ProgramStateRef State, SymbolRef Sym, TaintTagType Kind) { if (!Sym) return false; // Traverse all the symbols this symbol depends on to see if any are tainted. for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE = Sym->symbol_end(); SI != SE; ++SI) { if (!isa<SymbolData>(*SI)) continue; if (const TaintTagType *Tag = State->get<TaintMap>(*SI)) { if (*Tag == Kind) return true; } if (const auto *SD = dyn_cast<SymbolDerived>(*SI)) { // If this is a SymbolDerived with a tainted parent, it's also tainted. if (isTainted(State, SD->getParentSymbol(), Kind)) return true; // If this is a SymbolDerived with the same parent symbol as another // tainted SymbolDerived and a region that's a sub-region of that tainted // symbol, it's also tainted. if (const TaintedSubRegions *Regs = State->get<DerivedSymTaint>(SD->getParentSymbol())) { const TypedValueRegion *R = SD->getRegion(); for (auto I : *Regs) { // FIXME: The logic to identify tainted regions could be more // complete. For example, this would not currently identify // overlapping fields in a union as tainted. To identify this we can // check for overlapping/nested byte offsets. if (Kind == I.second && R->isSubRegionOf(I.first)) return true; } } } // If memory region is tainted, data is also tainted. if (const auto *SRV = dyn_cast<SymbolRegionValue>(*SI)) { if (isTainted(State, SRV->getRegion(), Kind)) return true; } // If this is a SymbolCast from a tainted value, it's also tainted. if (const auto *SC = dyn_cast<SymbolCast>(*SI)) { if (isTainted(State, SC->getOperand(), Kind)) return true; } } return false; } PathDiagnosticPieceRef TaintBugVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &BR) { // Find the ExplodedNode where the taint was first introduced if (!isTainted(N->getState(), V) || isTainted(N->getFirstPred()->getState(), V)) return nullptr; const Stmt *S = N->getStmtForDiagnostics(); if (!S) return nullptr; const LocationContext *NCtx = N->getLocationContext(); PathDiagnosticLocation L = PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx); if (!L.isValid() || !L.asLocation().isValid()) return nullptr; return std::make_shared<PathDiagnosticEventPiece>(L, "Taint originated here"); }
Upload File
Create Folder