Skip to content

Commit e5ac914

Browse files
authored
[analyzer][taint] Recognize tainted LazyCompoundVals (4/4) (llvm#115919)
returned by-value from opaque function calls. If a struct is returned by-value from an opaque call, the "value" of the whole struct is represented by a Conjured symbol. Later fields may slice off smaller subregions by creating Derived symbols of that Conjured symbol, but those are handled well, and "isTainted" returns true as expected. However, passing the whole struct to "isTainted" would be false, because LazyCompoundVals and CompoundVals are not handled. This patch addresses this. Fixes llvm#114270 Split from llvm#114835
1 parent 0dfae06 commit e5ac914

File tree

2 files changed

+35
-2
lines changed

2 files changed

+35
-2
lines changed

clang/lib/StaticAnalyzer/Checkers/Taint.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,14 @@ std::vector<SymbolRef> taint::getTaintedSymbolsImpl(ProgramStateRef State,
207207
return getTaintedSymbolsImpl(State, Sym, Kind, returnFirstOnly);
208208
if (const MemRegion *Reg = V.getAsRegion())
209209
return getTaintedSymbolsImpl(State, Reg, Kind, returnFirstOnly);
210+
211+
if (auto LCV = V.getAs<nonloc::LazyCompoundVal>()) {
212+
StoreManager &StoreMgr = State->getStateManager().getStoreManager();
213+
if (auto DefaultVal = StoreMgr.getDefaultBinding(*LCV)) {
214+
return getTaintedSymbolsImpl(State, *DefaultVal, Kind, returnFirstOnly);
215+
}
216+
}
217+
210218
return {};
211219
}
212220

clang/test/Analysis/taint-generic.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
// RUN: %clang_analyze_cc1 -analyzer-checker=optin.taint,core,alpha.security.ArrayBoundV2 -analyzer-config optin.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml -Wno-format-security -verify -std=c++11 %s
1+
// RUN: %clang_analyze_cc1 -std=c++11 -Wno-format-security \
2+
// RUN: -analyzer-checker=core,optin.taint,alpha.security.ArrayBoundV2,debug.ExprInspection \
3+
// RUN: -analyzer-config optin.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml \
4+
// RUN: -verify %s
5+
6+
template <typename T> void clang_analyzer_isTainted(T);
27

38
#define BUFSIZE 10
49
int Buffer[BUFSIZE];
510

611
int scanf(const char*, ...);
7-
int mySource1();
12+
template <typename T = int> T mySource1();
813
int mySource3();
914

1015
typedef struct _FILE FILE;
@@ -136,3 +141,23 @@ void testReadingFromStdin(char **p) {
136141
fscanf(stdin, "%d", &n);
137142
Buffer[n] = 1; // expected-warning {{Potential out of bound access }}
138143
}
144+
145+
namespace gh114270 {
146+
class Empty {};
147+
class Aggr {
148+
public:
149+
int data;
150+
};
151+
152+
void top() {
153+
int Int = mySource1<int>();
154+
clang_analyzer_isTainted(Int); // expected-warning {{YES}}
155+
156+
Empty E = mySource1<Empty>();
157+
clang_analyzer_isTainted(E); // expected-warning {{YES}}
158+
159+
Aggr A = mySource1<Aggr>();
160+
clang_analyzer_isTainted(A); // expected-warning {{YES}}
161+
clang_analyzer_isTainted(A.data); // expected-warning {{YES}}
162+
}
163+
} // namespace gh114270

0 commit comments

Comments
 (0)