diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/ProgramState.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/ProgramState.cpp | 190 |
1 files changed, 3 insertions, 187 deletions
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp index 2e2e2ec94f..04ed507055 100644 --- a/lib/StaticAnalyzer/Core/ProgramState.cpp +++ b/lib/StaticAnalyzer/Core/ProgramState.cpp @@ -1,9 +1,8 @@ //= ProgramState.cpp - Path-Sensitive "State" for tracking values --*- C++ -*--= // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,7 +16,6 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h" #include "llvm/Support/raw_ostream.h" @@ -459,9 +457,6 @@ void ProgramState::print(raw_ostream &Out, // Print out the tracked dynamic types. printDynamicTypeInfo(this, Out, NL, Sep); - // Print out tainted symbols. - printTaint(Out, NL); - // Print checker-specific data. Mgr.getOwningEngine().printState(Out, this, NL, Sep, LC); } @@ -475,22 +470,6 @@ LLVM_DUMP_METHOD void ProgramState::dump() const { print(llvm::errs()); } -void ProgramState::printTaint(raw_ostream &Out, - const char *NL) const { - TaintMapImpl TM = get<TaintMap>(); - - if (!TM.isEmpty()) - Out <<"Tainted symbols:" << NL; - - for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) { - Out << I->first << " : " << I->second << NL; - } -} - -void ProgramState::dumpTaint() const { - printTaint(llvm::errs()); -} - AnalysisManager& ProgramState::getAnalysisManager() const { return stateMgr->getOwningEngine().getAnalysisManager(); } @@ -658,166 +637,3 @@ bool ProgramState::scanReachableSymbols( } return true; } - -ProgramStateRef ProgramState::addTaint(const Stmt *S, - const LocationContext *LCtx, - TaintTagType Kind) const { - if (const Expr *E = dyn_cast_or_null<Expr>(S)) - S = E->IgnoreParens(); - - return addTaint(getSVal(S, LCtx), Kind); -} - -ProgramStateRef ProgramState::addTaint(SVal V, - TaintTagType Kind) const { - SymbolRef Sym = V.getAsSymbol(); - if (Sym) - return addTaint(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 = getStateManager().StoreMgr->getDefaultBinding(*LCV)) { - if (SymbolRef Sym = binding->getAsSymbol()) - return addPartialTaint(Sym, LCV->getRegion(), Kind); - } - } - - const MemRegion *R = V.getAsRegion(); - return addTaint(R, Kind); -} - -ProgramStateRef ProgramState::addTaint(const MemRegion *R, - TaintTagType Kind) const { - if (const SymbolicRegion *SR = dyn_cast_or_null<SymbolicRegion>(R)) - return addTaint(SR->getSymbol(), Kind); - return this; -} - -ProgramStateRef ProgramState::addTaint(SymbolRef Sym, - TaintTagType Kind) const { - // 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 = set<TaintMap>(Sym, Kind); - assert(NewState); - return NewState; -} - -ProgramStateRef ProgramState::addPartialTaint(SymbolRef ParentSym, - const SubRegion *SubRegion, - TaintTagType Kind) const { - // Ignore partial taint if the entire parent symbol is already tainted. - if (contains<TaintMap>(ParentSym) && *get<TaintMap>(ParentSym) == Kind) - return this; - - // Partial taint applies if only a portion of the symbol is tainted. - if (SubRegion == SubRegion->getBaseRegion()) - return addTaint(ParentSym, Kind); - - const TaintedSubRegions *SavedRegs = get<DerivedSymTaint>(ParentSym); - TaintedSubRegions Regs = - SavedRegs ? *SavedRegs : stateMgr->TSRFactory.getEmptyMap(); - - Regs = stateMgr->TSRFactory.add(Regs, SubRegion, Kind); - ProgramStateRef NewState = set<DerivedSymTaint>(ParentSym, Regs); - assert(NewState); - return NewState; -} - -bool ProgramState::isTainted(const Stmt *S, const LocationContext *LCtx, - TaintTagType Kind) const { - if (const Expr *E = dyn_cast_or_null<Expr>(S)) - S = E->IgnoreParens(); - - SVal val = getSVal(S, LCtx); - return isTainted(val, Kind); -} - -bool ProgramState::isTainted(SVal V, TaintTagType Kind) const { - if (const SymExpr *Sym = V.getAsSymExpr()) - return isTainted(Sym, Kind); - if (const MemRegion *Reg = V.getAsRegion()) - return isTainted(Reg, Kind); - return false; -} - -bool ProgramState::isTainted(const MemRegion *Reg, TaintTagType K) const { - 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(ER->getSuperRegion(), K) || isTainted(ER->getIndex(), K); - - if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(Reg)) - return isTainted(SR->getSymbol(), K); - - if (const SubRegion *ER = dyn_cast<SubRegion>(Reg)) - return isTainted(ER->getSuperRegion(), K); - - return false; -} - -bool ProgramState::isTainted(SymbolRef Sym, TaintTagType Kind) const { - 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 = get<TaintMap>(*SI)) { - if (*Tag == Kind) - return true; - } - - if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) { - // If this is a SymbolDerived with a tainted parent, it's also tainted. - if (isTainted(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 = - 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 SymbolRegionValue *SRV = dyn_cast<SymbolRegionValue>(*SI)) { - if (isTainted(SRV->getRegion(), Kind)) - return true; - } - - // If this is a SymbolCast from a tainted value, it's also tainted. - if (const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) { - if (isTainted(SC->getOperand(), Kind)) - return true; - } - } - - return false; -} |