Skip to content

Commit c7fa112

Browse files
authored
Merge pull request github#3532 from MathiasVP/remove-field-conflation-from-ir-fieldflow
C++: Remove field conflation caused by IR field flow
2 parents 674c184 + bd97fe6 commit c7fa112

File tree

7 files changed

+9
-36
lines changed

7 files changed

+9
-36
lines changed

cpp/ql/src/semmle/code/cpp/ir/dataflow/DefaultTaintTracking.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import cpp
22
import semmle.code.cpp.security.Security
33
private import semmle.code.cpp.ir.dataflow.DataFlow
4+
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
45
private import semmle.code.cpp.ir.dataflow.DataFlow2
56
private import semmle.code.cpp.ir.dataflow.DataFlow3
67
private import semmle.code.cpp.ir.IR

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,9 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
458458
// for now.
459459
iTo.getAnOperand().(ChiTotalOperand).getDef() = iFrom
460460
or
461-
// The next two rules allow flow from partial definitions in setters to succeeding loads in the caller.
462-
// First, we add flow from write side-effects to non-conflated chi instructions through their
463-
// partial operands. Consider the following example:
461+
// Add flow from write side-effects to non-conflated chi instructions through their
462+
// partial operands. From there, a `readStep` will find subsequent reads of that field.
463+
// Consider the following example:
464464
// ```
465465
// void setX(Point* p, int new_x) {
466466
// p->x = new_x;
@@ -470,14 +470,9 @@ private predicate simpleInstructionLocalFlowStep(Instruction iFrom, Instruction
470470
// ```
471471
// Here, a `WriteSideEffectInstruction` will provide a new definition for `p->x` after the call to
472472
// `setX`, which will be melded into `p` through a chi instruction.
473-
iTo.getAnOperand().(ChiPartialOperand).getDef() = iFrom.(WriteSideEffectInstruction) and
474-
not iTo.isResultConflated()
475-
or
476-
// Next, we add flow from non-conflated chi instructions to loads (even when they are not precise).
477-
// This ensures that loads of `p->x` gets data flow from the `WriteSideEffectInstruction` above.
478-
exists(ChiInstruction chi | iFrom = chi |
479-
not chi.isResultConflated() and
480-
iTo.(LoadInstruction).getSourceValueOperand().getAnyDef() = chi
473+
exists(ChiInstruction chi | chi = iTo |
474+
chi.getPartialOperand().getDef() = iFrom.(WriteSideEffectInstruction) and
475+
not chi.isResultConflated()
481476
)
482477
or
483478
// Flow from stores to structs with a single field to a load of that field.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,5 +115,5 @@ void test_conflated_fields3() {
115115
XY xy;
116116
xy.x = 0;
117117
taint_y(&xy);
118-
sink(xy.x); // not tainted [FALSE POSITIVE]
118+
sink(xy.x); // not tainted
119119
}

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,6 @@
103103
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:32 | (int)... |
104104
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:110:17:110:32 | access to array |
105105
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:12:111:18 | tainted |
106-
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:118:11:118:11 | x |
107-
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | shared.h:6:15:6:23 | sinkparam |
108106
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:24:28:27 | call to atoi |
109107
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:34 | call to getenv |
110108
| dispatch.cpp:28:29:28:34 | call to getenv | dispatch.cpp:28:29:28:45 | (const char *)... |

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/test_diff.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@
2121
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | defaulttainttracking.cpp:98:10:98:11 | p2 | IR only |
2222
| defaulttainttracking.cpp:97:27:97:32 | call to getenv | shared.h:5:23:5:31 | sinkparam | IR only |
2323
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:111:8:111:8 | y | AST only |
24-
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | defaulttainttracking.cpp:118:11:118:11 | x | IR only |
25-
| defaulttainttracking.cpp:110:17:110:22 | call to getenv | shared.h:6:15:6:23 | sinkparam | IR only |
2624
| globals.cpp:13:15:13:20 | call to getenv | globals.cpp:13:5:13:11 | global1 | AST only |
2725
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:5:23:11 | global2 | AST only |
2826
| test_diff.cpp:104:12:104:15 | argv | test_diff.cpp:104:11:104:20 | (...) | IR only |

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/TaintedAllocationSize.expected

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,4 @@
11
edges
2-
| field_conflation.c:12:22:12:27 | call to getenv | field_conflation.c:13:3:13:18 | Chi |
3-
| field_conflation.c:12:22:12:34 | (const char *)... | field_conflation.c:13:3:13:18 | Chi |
4-
| field_conflation.c:13:3:13:18 | Chi | field_conflation.c:19:15:19:17 | taint_array output argument |
5-
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:10:20:13 | (unsigned long)... |
6-
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
7-
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
8-
| field_conflation.c:19:15:19:17 | taint_array output argument | field_conflation.c:20:13:20:13 | x |
9-
| field_conflation.c:20:13:20:13 | x | field_conflation.c:20:10:20:13 | (unsigned long)... |
10-
| field_conflation.c:20:13:20:13 | x | field_conflation.c:20:13:20:13 | x |
112
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
123
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | (size_t)... |
134
| test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted |
@@ -89,15 +80,6 @@ edges
8980
| test.cpp:309:19:309:32 | (const char *)... | test.cpp:314:10:314:27 | ... * ... |
9081
| test.cpp:309:19:309:32 | (const char *)... | test.cpp:314:10:314:27 | ... * ... |
9182
nodes
92-
| field_conflation.c:12:22:12:27 | call to getenv | semmle.label | call to getenv |
93-
| field_conflation.c:12:22:12:34 | (const char *)... | semmle.label | (const char *)... |
94-
| field_conflation.c:13:3:13:18 | Chi | semmle.label | Chi |
95-
| field_conflation.c:19:15:19:17 | taint_array output argument | semmle.label | taint_array output argument |
96-
| field_conflation.c:20:10:20:13 | (unsigned long)... | semmle.label | (unsigned long)... |
97-
| field_conflation.c:20:10:20:13 | (unsigned long)... | semmle.label | (unsigned long)... |
98-
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
99-
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
100-
| field_conflation.c:20:13:20:13 | x | semmle.label | x |
10183
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
10284
| test.cpp:39:21:39:24 | argv | semmle.label | argv |
10385
| test.cpp:42:38:42:44 | (size_t)... | semmle.label | (size_t)... |
@@ -187,7 +169,6 @@ nodes
187169
| test.cpp:314:10:314:27 | ... * ... | semmle.label | ... * ... |
188170
| test.cpp:314:10:314:27 | ... * ... | semmle.label | ... * ... |
189171
#select
190-
| field_conflation.c:20:3:20:8 | call to malloc | field_conflation.c:12:22:12:27 | call to getenv | field_conflation.c:20:13:20:13 | x | This allocation size is derived from $@ and might overflow | field_conflation.c:12:22:12:27 | call to getenv | user input (getenv) |
191172
| test.cpp:42:31:42:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:42:38:42:44 | tainted | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
192173
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:43:38:43:63 | ... * ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |
193174
| test.cpp:45:31:45:36 | call to malloc | test.cpp:39:21:39:24 | argv | test.cpp:45:38:45:63 | ... + ... | This allocation size is derived from $@ and might overflow | test.cpp:39:21:39:24 | argv | user input (argv) |

cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/TaintedAllocationSize/field_conflation.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ void test_conflated_fields3(void) {
1717
struct XY xy;
1818
xy.x = 4;
1919
taint_array(&xy);
20-
malloc(xy.x); // not tainted [FALSE POSITIVE]
20+
malloc(xy.x); // not tainted
2121
}

0 commit comments

Comments
 (0)