clang: lib/StaticAnalyzer/Checkers/Taint.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
17#include
18
19using namespace clang;
20using namespace ento;
21using namespace taint;
22
23
25
26
30
32 const char *Sep) {
33 TaintMapTy TM = State->get();
34
35 if (!TM.isEmpty())
36 Out << "Tainted symbols:" << NL;
37
38 for (const auto &I : TM)
39 Out << I.first << " : " << I.second << NL;
40}
41
44}
45
49 return addTaint(State, State->getSVal(S, LCtx), Kind);
50}
51
55 if (Sym)
56 return addTaint(State, Sym, Kind);
57
58
59
60
61
62
63
64
65
66
68 if (std::optional binding =
69 State->getStateManager().getStoreManager().getDefaultBinding(
70 *LCV)) {
71 if (SymbolRef Sym = binding->getAsSymbol())
72 return addPartialTaint(State, Sym, LCV->getRegion(), Kind);
73 }
74 }
75
77 return addTaint(State, R, Kind);
78}
79
82 if (const SymbolicRegion *SR = dyn_cast_or_null(R))
83 return addTaint(State, SR->getSymbol(), Kind);
84 return State;
85}
86
89
90
91 while (const SymbolCast *SC = dyn_cast(Sym))
92 Sym = SC->getOperand();
93
94 ProgramStateRef NewState = State->set(Sym, Kind);
95 assert(NewState);
96 return NewState;
97}
98
101 if (Sym)
103
104 const MemRegion *R = V.getAsRegion();
106}
107
109 if (const SymbolicRegion *SR = dyn_cast_or_null(R))
110 return removeTaint(State, SR->getSymbol());
111 return State;
112}
113
115
116
117 while (const SymbolCast *SC = dyn_cast(Sym))
118 Sym = SC->getOperand();
119
121 assert(NewState);
122 return NewState;
123}
124
129
130 if (const TaintTagType *T = State->get(ParentSym))
131 if (*T == Kind)
132 return State;
133
134
136 return addTaint(State, ParentSym, Kind);
137
138 const TaintedSubRegions *SavedRegs = State->get(ParentSym);
139 TaintedSubRegions::Factory &F = State->get_context();
140 TaintedSubRegions Regs = SavedRegs ? *SavedRegs : F.getEmptyMap();
141
142 Regs = F.add(Regs, SubRegion, Kind);
143 ProgramStateRef NewState = State->set(ParentSym, Regs);
144 assert(NewState);
145 return NewState;
146}
147
151 .empty();
152}
153
156 .empty();
157}
158
162 .empty();
163}
164
167 .empty();
168}
169
171 const Stmt *S,
175}
176
180}
181
186}
187
192}
193
195 const Stmt *S,
198 bool returnFirstOnly) {
199 SVal val = State->getSVal(S, LCtx);
201}
202
205 bool returnFirstOnly) {
208 if (const MemRegion *Reg = V.getAsRegion())
210
212 StoreManager &StoreMgr = State->getStateManager().getStoreManager();
215 }
216 }
217
218 return {};
219}
220
224 bool returnFirstOnly) {
225 std::vector TaintedSymbols;
226 if (!Reg)
227 return TaintedSymbols;
228
229
230 if (const ElementRegion *ER = dyn_cast(Reg)) {
231 std::vector TaintedIndex =
233 llvm::append_range(TaintedSymbols, TaintedIndex);
234 if (returnFirstOnly && !TaintedSymbols.empty())
235 return TaintedSymbols;
236 }
237
238
239 if (const SymbolicRegion *SR = dyn_cast(Reg)) {
240 std::vector TaintedRegions =
242 llvm::append_range(TaintedSymbols, TaintedRegions);
243 if (returnFirstOnly && !TaintedSymbols.empty())
244 return TaintedSymbols;
245 }
246
247
248
249 if (const SubRegion *ER = dyn_cast(Reg)) {
250 std::vector TaintedSubRegions =
252 llvm::append_range(TaintedSymbols, TaintedSubRegions);
253 if (returnFirstOnly && !TaintedSymbols.empty())
254 return TaintedSymbols;
255 }
256
257 return TaintedSymbols;
258}
259
263 bool returnFirstOnly) {
264 std::vector TaintedSymbols;
265 if (!Sym)
266 return TaintedSymbols;
267
268
269 if (const auto &Opts = State->getAnalysisManager().getAnalyzerOptions();
271 return {};
272 }
273
274
276 if (!isa(SubSym))
277 continue;
278
279 if (const TaintTagType *Tag = State->get(SubSym)) {
280 if (*Tag == Kind) {
281 TaintedSymbols.push_back(SubSym);
282 if (returnFirstOnly)
283 return TaintedSymbols;
284 }
285 }
286
287 if (const auto *SD = dyn_cast(SubSym)) {
288
290 State, SD->getParentSymbol(), Kind, returnFirstOnly);
291 llvm::append_range(TaintedSymbols, TaintedParents);
292 if (returnFirstOnly && !TaintedSymbols.empty())
293 return TaintedSymbols;
294
295
296
297
298 if (const TaintedSubRegions *Regs =
299 State->get(SD->getParentSymbol())) {
301 for (auto I : *Regs) {
302
303
304
305
306 if (Kind == I.second && R->isSubRegionOf(I.first)) {
307 TaintedSymbols.push_back(SD->getParentSymbol());
308 if (returnFirstOnly && !TaintedSymbols.empty())
309 return TaintedSymbols;
310 }
311 }
312 }
313 }
314
315
316 if (const auto *SRV = dyn_cast(SubSym)) {
317 std::vector TaintedRegions =
319 llvm::append_range(TaintedSymbols, TaintedRegions);
320 if (returnFirstOnly && !TaintedSymbols.empty())
321 return TaintedSymbols;
322 }
323
324
325 if (const auto *SC = dyn_cast(SubSym)) {
326 std::vector TaintedCasts =
328 llvm::append_range(TaintedSymbols, TaintedCasts);
329 if (returnFirstOnly && !TaintedSymbols.empty())
330 return TaintedSymbols;
331 }
332 }
333 return TaintedSymbols;
334}
#define REGISTER_MAP_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map of type NameTy, suitable for placement into the ProgramState.
#define REGISTER_MAP_FACTORY_WITH_PROGRAMSTATE(Name, Key, Value)
Declares an immutable map type Name and registers the factory for such maps in the program state,...
It wraps the AnalysisDeclContext to represent both the call stack with the help of StackFrameContext ...
Stmt - This represents one statement.
ElementRegion is used to represent both array elements and casts.
MemRegion - The root abstract class for all memory regions.
LLVM_ATTRIBUTE_RETURNS_NONNULL const MemRegion * getBaseRegion() const
SVal - This represents a symbolic expression, which can be either an L-value or an R-value.
virtual std::optional< SVal > getDefaultBinding(Store store, const MemRegion *R)=0
Return the default value bound to a region in a given store.
SubRegion - A region that subsets another larger region.
bool isSubRegionOf(const MemRegion *R) const override
Check if the region is a subregion of the given region.
llvm::iterator_range< symbol_iterator > symbols() const
virtual unsigned computeComplexity() const =0
Represents a cast expression.
SymbolicRegion - A special, "non-concrete" region.
TypedValueRegion - An abstract class representing regions having a typed value.
While nonloc::CompoundVal covers a few simple use cases, nonloc::LazyCompoundVal is a more performant...
std::vector< SymbolRef > getTaintedSymbolsImpl(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind, bool returnFirstOnly)
ProgramStateRef addTaint(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Create a new state in which the value of the statement is marked as tainted.
std::vector< SymbolRef > getTaintedSymbols(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Returns the tainted Symbols for a given Statement and state.
bool isTainted(ProgramStateRef State, const Stmt *S, const LocationContext *LCtx, TaintTagType Kind=TaintTagGeneric)
Check if the statement has a tainted value in the given state.
ProgramStateRef removeTaint(ProgramStateRef State, SVal V)
void printTaint(ProgramStateRef State, raw_ostream &Out, const char *nl="\n", const char *sep="")
ProgramStateRef addPartialTaint(ProgramStateRef State, SymbolRef ParentSym, const SubRegion *SubRegion, TaintTagType Kind=TaintTagGeneric)
Create a new state in a which a sub-region of a given symbol is tainted.
LLVM_DUMP_METHOD void dumpTaint(ProgramStateRef State)
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T