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. bool Tainted = false; for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end(); SI != SE; ++SI) { if (!isa<SymbolData>(*SI)) continue; const TaintTagType *Tag = get<TaintMap>(*SI); Tainted = (Tag && *Tag == Kind); // If this is a SymbolDerived with a tainted parent, it's also tainted. if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) Tainted = Tainted || isTainted(SD->getParentSymbol(), Kind); // If memory region is tainted, data is also tainted. if (const SymbolRegionValue *SRV = dyn_cast<SymbolRegionValue>(*SI)) Tainted = Tainted || isTainted(SRV->getRegion(), Kind); // If If this is a SymbolCast from a tainted value, it's also tainted. if (const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) Tainted = Tainted || isTainted(SC->getOperand(), Kind); if (Tainted) return true; } return Tainted; }
bool DoubleFetchChecker::ifTainted(ProgramStateRef state, SymbolRef Sym) const { if (!Sym) return false; // Traverse all the symbols this symbol depends on to see if any are tainted. bool Tainted = false; for (SymExpr::symbol_iterator SI = Sym->symbol_begin(), SE =Sym->symbol_end(); SI != SE; ++SI) { if (!isa<SymbolData>(*SI)) continue; const TaintList *TL = state->get<TaintsMap>(*SI); Tainted = (TL && !TL->isEmpty()); // If this is a SymbolDerived with a tainted parent, it's also tainted. if (const SymbolDerived *SD = dyn_cast<SymbolDerived>(*SI)) Tainted = Tainted || ifTainted(state, SD->getParentSymbol()); // If memory region is tainted, data is also tainted. if (const SymbolRegionValue *SRV = dyn_cast<SymbolRegionValue>(*SI)) Tainted = Tainted || ifTainted(state, SRV->getRegion()); // If this is a SymbolCast from a tainted value, it's also tainted. if (const SymbolCast *SC = dyn_cast<SymbolCast>(*SI)) Tainted = Tainted || ifTainted(state, SC->getOperand()); if (Tainted) return true; } return Tainted; }
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; }