Skip to content

Commit 24a63ae

Browse files
committed
C++: Block flow by default.
1 parent 625c47f commit 24a63ae

File tree

9 files changed

+97
-59
lines changed

9 files changed

+97
-59
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ private import DataFlowUtil
44
private import DataFlowImplCommon as DataFlowImplCommon
55
private import semmle.code.cpp.models.interfaces.Allocation as Alloc
66
private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow
7+
private import semmle.code.cpp.models.interfaces.Taint as Taint
8+
private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO
79
private import semmle.code.cpp.ir.internal.IRCppLanguage
10+
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
811
private import DataFlowPrivate
912
private import ssa0.SsaInternals as SsaInternals0
1013
import SsaInternalsCommon
@@ -796,10 +799,47 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) {
796799
)
797800
}
798801

802+
private predicate inOut(FIO::FunctionInput input, FIO::FunctionOutput output) {
803+
exists(int indirectionIndex |
804+
input.isQualifierObject(indirectionIndex) and
805+
output.isQualifierObject(indirectionIndex)
806+
or
807+
exists(int i |
808+
input.isParameterDeref(i, indirectionIndex) and
809+
output.isParameterDeref(i, indirectionIndex)
810+
)
811+
)
812+
}
813+
814+
/**
815+
* Holds if there should not be use-use flow out of `n` (or a conversion that
816+
* flows to `n`).
817+
*/
818+
private predicate modeledFlowBarrier(Node n) {
819+
exists(FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call |
820+
n = callInput(call, input) and
821+
inOut(input, output) and
822+
exists(callOutput(call, output))
823+
|
824+
call.getStaticCallTarget().(DataFlow::DataFlowFunction).hasDataFlow(_, output)
825+
or
826+
call.getStaticCallTarget().(Taint::TaintFunction).hasTaintFlow(_, output)
827+
)
828+
or
829+
exists(Operand operand, Instruction instr, Node n0, int indirectionIndex |
830+
modeledFlowBarrier(n0) and
831+
nodeHasInstruction(n0, instr, indirectionIndex) and
832+
conversionFlow(operand, instr, false, _) and
833+
nodeHasOperand(n, operand, indirectionIndex)
834+
)
835+
}
836+
799837
/** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */
800838
predicate ssaFlow(Node nodeFrom, Node nodeTo) {
801839
exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse |
802-
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and nodeFrom != nodeTo
840+
ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and
841+
not modeledFlowBarrier(nFrom) and
842+
nodeFrom != nodeTo
803843
|
804844
if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom
805845
)

cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,6 @@ irFlow
238238
| test.cpp:382:48:382:54 | source1 | test.cpp:385:8:385:10 | tmp |
239239
| test.cpp:388:53:388:59 | source1 | test.cpp:392:8:392:10 | tmp |
240240
| test.cpp:388:53:388:59 | source1 | test.cpp:394:10:394:12 | tmp |
241-
| test.cpp:399:7:399:9 | definition of tmp | test.cpp:401:8:401:10 | tmp |
242-
| test.cpp:405:7:405:9 | definition of tmp | test.cpp:408:8:408:10 | tmp |
243241
| test.cpp:416:7:416:11 | definition of local | test.cpp:418:8:418:12 | local |
244242
| test.cpp:417:16:417:20 | intRefSource output argument | test.cpp:418:8:418:12 | local |
245243
| test.cpp:422:7:422:11 | definition of local | test.cpp:424:8:424:12 | local |

cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,14 +398,14 @@ void flowThroughMemcpy_blockvar_with_local_flow(int source1, int b) {
398398
void cleanedByMemcpy_ssa(int clean1) { // currently modeled with BlockVar, not SSA
399399
int tmp;
400400
memcpy(&tmp, &clean1, sizeof tmp);
401-
sink(tmp); // $ SPURIOUS: ast,ir
401+
sink(tmp); // $ SPURIOUS: ast
402402
}
403403

404404
void cleanedByMemcpy_blockvar(int clean1) {
405405
int tmp;
406406
int *capture = &tmp;
407407
memcpy(&tmp, &clean1, sizeof tmp);
408-
sink(tmp); // $ SPURIOUS: ast,ir
408+
sink(tmp); // $ SPURIOUS: ast
409409
}
410410

411411
void intRefSource(int &ref_source);

cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,11 @@ void test_pair()
7171
sink(i.second); // $ MISSING: ast,ir
7272
sink(i); // $ ast,ir
7373
sink(j.first);
74-
sink(j.second); // $ SPURIOUS: ast,ir
75-
sink(j); // $ SPURIOUS: ast,ir
74+
sink(j.second); // $ SPURIOUS: ast
75+
sink(j); // $ SPURIOUS: ast
7676
sink(k.first);
77-
sink(k.second); // $ SPURIOUS: ast,ir
78-
sink(k); // $ SPURIOUS: ast,ir
77+
sink(k.second); // $ SPURIOUS: ast
78+
sink(k); // $ SPURIOUS: ast
7979
sink(l.first);
8080
sink(l.second); // $ MISSING: ast,ir
8181
sink(l); // $ ast,ir
@@ -179,11 +179,11 @@ void test_map()
179179
m14.insert(std::make_pair("b", source()));
180180
m14.insert(std::make_pair("c", source()));
181181
m14.insert(std::make_pair("d", "d"));
182-
sink(m14.lower_bound("b")); // $ ast,ir=179:33 ast,ir=180:33
183-
sink(m14.upper_bound("b")); // $ ast,ir=179:33 ast,ir=180:33
182+
sink(m14.lower_bound("b")); // $ ast=179:33 ast=180:33 MISSING: ir=179:33 ir=180:33
183+
sink(m14.upper_bound("b")); // $ ast=179:33 ast=180:33 MISSING: ir=179:33 ir=180:33
184184
sink(m14.equal_range("b").first); // $ MISSING: ast,ir
185185
sink(m14.equal_range("b").second); // $ MISSING: ast,ir
186-
sink(m14.upper_bound("c")); // $ SPURIOUS: ast,ir=179:33 ast,ir=180:33
186+
sink(m14.upper_bound("c")); // $ SPURIOUS: ast=179:33 ast=180:33
187187
sink(m14.equal_range("c").second);
188188

189189
// swap
@@ -196,10 +196,10 @@ void test_map()
196196
sink(m18); // $ ast,ir
197197
m15.swap(m16);
198198
m17.swap(m18);
199-
sink(m15); // $ SPURIOUS: ast,ir
199+
sink(m15); // $ SPURIOUS: ast
200200
sink(m16); // $ ast,ir
201201
sink(m17); // $ ast,ir
202-
sink(m18); // $ SPURIOUS: ast,ir
202+
sink(m18); // $ SPURIOUS: ast
203203

204204
// merge
205205
std::map<char *, char *> m19, m20, m21, m22;
@@ -213,7 +213,7 @@ void test_map()
213213
sink(m22); // $ ast,ir
214214
m19.merge(m20);
215215
m21.merge(m22);
216-
sink(m19); // $ ast,ir
216+
sink(m19); // $ ast
217217
sink(m20);
218218
sink(m21); // $ ast,ir
219219
sink(m22); // $ ast,ir
@@ -222,11 +222,11 @@ void test_map()
222222
std::map<char *, char *> m23;
223223
m23.insert(std::pair<char *, char *>(source(), source()));
224224
m23.insert(std::pair<char *, char *>(source(), source()));
225-
sink(m23); // $ ast,ir=223:49 ast,ir=224:49
226-
sink(m23.erase(m23.begin())); // $ ast,ir=223:49 ast,ir=224:49
227-
sink(m23); // $ ast,ir=223:49 ast,ir=224:49
225+
sink(m23); // $ ast=223:49 ast=224:49 ir MISSING: ir=223:49 ir=224:49
226+
sink(m23.erase(m23.begin())); // $ ast=223:49 ast=224:49 ir MISSING: ir=223:49 ir=224:49
227+
sink(m23); // $ ast=223:49 ast=224:49 ir MISSING: ir=223:49 ir=224:49
228228
m23.clear();
229-
sink(m23); // $ SPURIOUS: ast,ir=223:49 ast,ir=224:49
229+
sink(m23); // $ SPURIOUS: ast=223:49 ast=224:49 ir
230230

231231
// emplace, emplace_hint
232232
std::map<char *, char *> m24, m25;
@@ -345,10 +345,10 @@ void test_unordered_map()
345345
sink(m18); // $ ast,ir
346346
m15.swap(m16);
347347
m17.swap(m18);
348-
sink(m15); // $ SPURIOUS: ast,ir
348+
sink(m15); // $ SPURIOUS: ast
349349
sink(m16); // $ ast,ir
350350
sink(m17); // $ ast,ir
351-
sink(m18); // $ SPURIOUS: ast,ir
351+
sink(m18); // $ SPURIOUS: ast
352352

353353
// merge
354354
std::unordered_map<char *, char *> m19, m20, m21, m22;
@@ -362,7 +362,7 @@ void test_unordered_map()
362362
sink(m22); // $ ast,ir
363363
m19.merge(m20);
364364
m21.merge(m22);
365-
sink(m19); // $ ast,ir
365+
sink(m19); // $ ast MISSING: ir
366366
sink(m20);
367367
sink(m21); // $ ast,ir
368368
sink(m22); // $ ast,ir
@@ -371,11 +371,11 @@ void test_unordered_map()
371371
std::unordered_map<char *, char *> m23;
372372
m23.insert(std::pair<char *, char *>(source(), source()));
373373
m23.insert(std::pair<char *, char *>(source(), source()));
374-
sink(m23); // $ ast,ir=372:49 ast,ir=373:49
375-
sink(m23.erase(m23.begin())); // $ ast,ir=372:49 ast,ir=373:49
376-
sink(m23); // $ ast,ir=372:49 ast,ir=373:49
374+
sink(m23); // $ ast=372:49 ast=373:49 ir MISSING: ir=372:49 ir=373:49
375+
sink(m23.erase(m23.begin())); // $ ast=372:49 ast=373:49 ir MISSING: ir=372:49 ir=373:49
376+
sink(m23); // $ ast=372:49 ast=373:49 ir MISSING: ir=372:49 ir=373:49
377377
m23.clear();
378-
sink(m23); // $ SPURIOUS: ast,ir=372:49 ast,ir=373:49
378+
sink(m23); // $ SPURIOUS: ast=372:49 ast=373:49 ir
379379

380380
// emplace, emplace_hint
381381
std::unordered_map<char *, char *> m24, m25;
@@ -395,7 +395,7 @@ void test_unordered_map()
395395
sink(m26);
396396
sink(m26.try_emplace("abc", source()).first);
397397
sink(m26.try_emplace("abc", source()).second); // $ MISSING: ast,ir=396:30
398-
sink(m26); // $ ast,ir=396:30 SPURIOUS: ast,ir=397:30
398+
sink(m26); // $ ast=396:30 ir MISSING: ir=396:30 SPURIOUS: ast=397:30
399399
sink(m27.try_emplace(m27.begin(), "abc", "def"));
400400
sink(m27);
401401
sink(m27.try_emplace(m27.begin(), "abc", source())); // $ ast,ir

cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ void test_set()
6666
s11.insert("a");
6767
s11.insert(source());
6868
s11.insert("c");
69-
sink(s11.lower_bound("b")); // $ ast,ir
70-
sink(s11.upper_bound("b")); // $ ast,ir
69+
sink(s11.lower_bound("b")); // $ ast MISSING: ir
70+
sink(s11.upper_bound("b")); // $ ast MISSING: ir
7171
sink(s11.equal_range("b").first); // $ MISSING: ast,ir
7272
sink(s11.equal_range("b").second); // $ MISSING: ast,ir
7373

@@ -81,10 +81,10 @@ void test_set()
8181
sink(s15); // $ ast,ir
8282
s12.swap(s13);
8383
s14.swap(s15);
84-
sink(s12); // $ SPURIOUS: ast,ir
84+
sink(s12); // $ SPURIOUS: ast
8585
sink(s13); // $ ast,ir
8686
sink(s14); // $ ast,ir
87-
sink(s15); // $ SPURIOUS: ast,ir
87+
sink(s15); // $ SPURIOUS: ast
8888

8989
// merge
9090
std::set<char *> s16, s17, s18, s19;
@@ -98,7 +98,7 @@ void test_set()
9898
sink(s19); // $ ast,ir
9999
s16.merge(s17);
100100
s18.merge(s19);
101-
sink(s16); // $ ast,ir
101+
sink(s16); // $ ast MISSING: ir
102102
sink(s17);
103103
sink(s18); // $ ast,ir
104104
sink(s19); // $ ast,ir
@@ -107,11 +107,11 @@ void test_set()
107107
std::set<char *> s20;
108108
s20.insert(source());
109109
s20.insert(source());
110-
sink(s20); // $ ast,ir=108:13 ast,ir=109:13
111-
sink(s20.erase(s20.begin())); // $ ast,ir=108:13 ast,ir=109:13
112-
sink(s20); // $ ast,ir=108:13 ast,ir=109:13
110+
sink(s20); // $ ast=108:13 ast=109:13 ir MISSING: ir=108:13 ir=109:13
111+
sink(s20.erase(s20.begin())); // $ ast=108:13 ast=109:13 ir MISSING: ir=108:13 ir=109:13
112+
sink(s20); // $ ir ast=108:13 ast=109:13 MISSING: ir=108:13 ir=109:13
113113
s20.clear();
114-
sink(s20); // $ SPURIOUS: ast,ir=108:13 ast,ir=109:13
114+
sink(s20); // $ SPURIOUS: ir ast=108:13 ast=109:13
115115

116116
// emplace, emplace_hint
117117
std::set<char *> s21, s22;
@@ -193,10 +193,10 @@ void test_unordered_set()
193193
sink(s15); // $ ast,ir
194194
s12.swap(s13);
195195
s14.swap(s15);
196-
sink(s12); // $ SPURIOUS: ast,ir
196+
sink(s12); // $ SPURIOUS: ast
197197
sink(s13); // $ ast,ir
198198
sink(s14); // $ ast,ir
199-
sink(s15); // $ SPURIOUS: ast,ir
199+
sink(s15); // $ SPURIOUS: ast
200200

201201
// merge
202202
std::unordered_set<char *> s16, s17, s18, s19;
@@ -210,7 +210,7 @@ void test_unordered_set()
210210
sink(s19); // $ ast,ir
211211
s16.merge(s17);
212212
s18.merge(s19);
213-
sink(s16); // $ ast,ir
213+
sink(s16); // $ ast MISSING: ir
214214
sink(s17);
215215
sink(s18); // $ ast,ir
216216
sink(s19); // $ ast,ir
@@ -219,11 +219,11 @@ void test_unordered_set()
219219
std::unordered_set<char *> s20;
220220
s20.insert(source());
221221
s20.insert(source());
222-
sink(s20); // $ ast,ir=220:13 ast,ir=221:13
223-
sink(s20.erase(s20.begin())); // $ ast,ir=220:13 ast,ir=221:13
224-
sink(s20); // $ ast,ir=220:13 ast,ir=221:13
222+
sink(s20); // $ ir ast=220:13 ast=221:13 MISSING: ir=220:13 ir=221:13
223+
sink(s20.erase(s20.begin())); // $ ast=220:13 ast=221:13 ir MISSING: ir=220:13 ir=221:13
224+
sink(s20); // $ ast=220:13 ast=221:13 ir MISSING: ir=220:13 ir=221:13
225225
s20.clear();
226-
sink(s20); // $ SPURIOUS: ast,ir=220:13 ast,ir=221:13
226+
sink(s20); // $ SPURIOUS: ast=220:13 ast=221:13 ir
227227

228228
// emplace, emplace_hint
229229
std::unordered_set<char *> s21, s22;

cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ void test_string_assign() {
203203
sink(s5); // $ ast,ir
204204

205205
sink(s6.assign(s1));
206-
sink(s6); // $ SPURIOUS: ast,ir
206+
sink(s6); // $ SPURIOUS: ast
207207
}
208208

209209
void test_string_insert() {
@@ -280,9 +280,9 @@ void test_string_swap() {
280280
s4.swap(s3);
281281

282282
sink(s1); // $ ast,ir
283-
sink(s2); // $ SPURIOUS: ast,ir
283+
sink(s2); // $ SPURIOUS: ast
284284
sink(s3); // $ ast,ir
285-
sink(s4); // $ SPURIOUS: ast,ir
285+
sink(s4); // $ SPURIOUS: ast
286286
}
287287

288288
void test_string_clear() {
@@ -495,7 +495,7 @@ void test_string_iterator_methods()
495495
sink(h); // $ ast,ir
496496

497497
sink(s6.assign(s5.cbegin(), s5.cend()));
498-
sink(s6); // $ SPURIOUS: ast,ir
498+
sink(s6); // $ SPURIOUS: ast
499499
}
500500
}
501501

cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void test_stringstream_string(int amount)
5050
ss7.str(source());
5151
ss7.str("abc"); // (overwrites)
5252
sink(ss6); // $ ast,ir
53-
sink(ss7); // $ SPURIOUS: ast,ir
53+
sink(ss7); // $ SPURIOUS: ast
5454

5555
sink(ss8.put('a'));
5656
sink(ss9.put(ns_char::source())); // $ ast,ir
@@ -118,9 +118,9 @@ void test_stringstream_swap()
118118
ss4.swap(ss3);
119119

120120
sink(ss1); // $ ast,ir
121-
sink(ss2); // $ SPURIOUS: ast,ir
121+
sink(ss2); // $ SPURIOUS: ast
122122
sink(ss3); // $ ast,ir
123-
sink(ss4); // $ SPURIOUS: ast,ir
123+
sink(ss4); // $ SPURIOUS: ast
124124
}
125125

126126
void test_stringstream_in()
@@ -217,15 +217,15 @@ void test_getline()
217217
sink(ss1.getline(b3, 1000));
218218
sink(b1);
219219
sink(b2); // $ ast,ir
220-
sink(b3); // $ SPURIOUS: ast,ir
220+
sink(b3); // $ SPURIOUS: ast
221221

222222
sink(ss1.getline(b4, 1000, ' '));
223223
sink(ss2.getline(b5, 1000, ' ')); // $ ast,ir
224224
sink(ss2.getline(b6, 1000, ' ')); // $ ast,ir
225225
sink(ss1.getline(b6, 1000, ' '));
226226
sink(b4);
227227
sink(b5); // $ ast,ir
228-
sink(b6); // $ SPURIOUS: ast,ir
228+
sink(b6); // $ SPURIOUS: ast
229229

230230
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir
231231
sink(b7); // $ ast,ir
@@ -237,15 +237,15 @@ void test_getline()
237237
sink(getline(ss1, s3));
238238
sink(s1);
239239
sink(s2); // $ ast,ir
240-
sink(s3); // $ SPURIOUS: ast,ir
240+
sink(s3); // $ SPURIOUS: ast
241241

242242
sink(getline(ss1, s4, ' '));
243243
sink(getline(ss2, s5, ' ')); // $ ast,ir
244244
sink(getline(ss2, s6, ' ')); // $ ast,ir
245245
sink(getline(ss1, s6, ' '));
246246
sink(s4);
247247
sink(s5); // $ ast,ir
248-
sink(s6); // $ SPURIOUS: ast,ir
248+
sink(s6); // $ SPURIOUS: ast
249249

250250
sink(getline(getline(ss2, s7), s8)); // $ ast,ir
251251
sink(s7); // $ ast,ir

cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ void test_swap() {
212212

213213
std::swap(x, y);
214214

215-
sink(x); // $ SPURIOUS: ast,ir
215+
sink(x); // $ SPURIOUS: ast
216216
sink(y); // $ ast,ir
217217
}
218218

@@ -756,5 +756,5 @@ void call_sprintf_twice(char* path, char* data) {
756756
void test_call_sprintf() {
757757
char path[10];
758758
call_sprintf_twice(path, indirect_source());
759-
sink(*path); // $ ir ast
759+
sink(*path); // $ ast MISSING: ir
760760
}

0 commit comments

Comments
 (0)