mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
C++: Let data flow past definition by reference
This commit changes how data flow works in the following code.
MyType x = source();
defineByReference(&x);
sink(x);
The question here is whether there should be flow from `source` to
`sink`. Such flow is desirable if `defineByReference` doesn't write to
all of `x`, but it's undesirable if `defineByReference` is a typical
init function in `C` that writes to every field or if
`defineByReference` is `memcpy` or `memset` on the full range.
Before 1.20.0, there would be flow from `source` to `sink` in case `x`
happened to be modeled with `BlockVar` but not in case `x` happened to
be modelled with SSA. The choice of modelling depends on an analysis of
how `x` is used elsewhere in the function, and it's supposed to be an
internal implementation detail that there are two ways to model
variables. In 1.20.0, I changed the `BlockVar` behavior so it worked the
same as SSA, never allowing that flow. It turns out that this change
broke a customer's query.
This commit reverts `BlockVar` to its old behavior of letting flow
propagate past the `defineByReference` call and then regains consistency
by changing all variables that are ever defined by reference to be
modelled with `BlockVar` instead of SSA. This means we now get too much
flow in certain cases, but that appears to be better overall than
getting too little flow. See also the discussion in CPP-336.
This commit is contained in:
@@ -1,11 +1,16 @@
|
||||
| example.c:15:37:15:37 | b | example.c:19:6:19:6 | b |
|
||||
| example.c:15:44:15:46 | pos | example.c:24:24:24:26 | pos |
|
||||
| example.c:15:44:15:46 | pos | example.c:28:23:28:25 | pos |
|
||||
| example.c:17:19:17:22 | {...} | example.c:24:2:24:7 | coords |
|
||||
| example.c:17:19:17:22 | {...} | example.c:24:13:24:18 | coords |
|
||||
| example.c:17:19:17:22 | {...} | example.c:26:2:26:7 | coords |
|
||||
| example.c:17:19:17:22 | {...} | example.c:26:19:26:24 | coords |
|
||||
| example.c:24:13:24:30 | ... = ... | example.c:24:2:24:30 | ... = ... |
|
||||
| example.c:24:24:24:30 | ... + ... | example.c:24:13:24:30 | ... = ... |
|
||||
| example.c:26:13:26:16 | call to getX | example.c:26:2:26:25 | ... = ... |
|
||||
| example.c:26:18:26:24 | ref arg & ... | example.c:26:2:26:7 | coords |
|
||||
| example.c:26:18:26:24 | ref arg & ... | example.c:26:19:26:24 | coords |
|
||||
| example.c:28:22:28:25 | ref arg & ... | example.c:28:23:28:25 | pos |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:8:8:8:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:9:8:9:9 | t1 |
|
||||
@@ -31,14 +36,22 @@
|
||||
| test.cpp:24:10:24:11 | t2 | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:430:48:430:54 | source1 | test.cpp:432:17:432:23 | source1 |
|
||||
| test.cpp:431:12:431:13 | 0 | test.cpp:432:11:432:13 | tmp |
|
||||
| test.cpp:431:12:431:13 | 0 | test.cpp:432:33:432:35 | tmp |
|
||||
| test.cpp:431:12:431:13 | 0 | test.cpp:433:8:433:10 | tmp |
|
||||
| test.cpp:432:10:432:13 | & ... | test.cpp:432:3:432:8 | call to memcpy |
|
||||
| test.cpp:432:10:432:13 | ref arg & ... | test.cpp:432:11:432:13 | tmp |
|
||||
| test.cpp:432:10:432:13 | ref arg & ... | test.cpp:432:33:432:35 | tmp |
|
||||
| test.cpp:432:10:432:13 | ref arg & ... | test.cpp:433:8:433:10 | tmp |
|
||||
| test.cpp:432:17:432:23 | source1 | test.cpp:432:10:432:13 | ref arg & ... |
|
||||
| test.cpp:436:53:436:59 | source1 | test.cpp:439:17:439:23 | source1 |
|
||||
| test.cpp:436:66:436:66 | b | test.cpp:441:7:441:7 | b |
|
||||
| test.cpp:437:12:437:13 | 0 | test.cpp:438:19:438:21 | tmp |
|
||||
| test.cpp:437:12:437:13 | 0 | test.cpp:439:11:439:13 | tmp |
|
||||
| test.cpp:437:12:437:13 | 0 | test.cpp:439:33:439:35 | tmp |
|
||||
| test.cpp:437:12:437:13 | 0 | test.cpp:440:8:440:10 | tmp |
|
||||
| test.cpp:437:12:437:13 | 0 | test.cpp:442:10:442:12 | tmp |
|
||||
| test.cpp:439:10:439:13 | & ... | test.cpp:439:3:439:8 | call to memcpy |
|
||||
| test.cpp:439:10:439:13 | ref arg & ... | test.cpp:439:11:439:13 | tmp |
|
||||
| test.cpp:439:10:439:13 | ref arg & ... | test.cpp:439:33:439:35 | tmp |
|
||||
| test.cpp:439:10:439:13 | ref arg & ... | test.cpp:440:8:440:10 | tmp |
|
||||
| test.cpp:439:10:439:13 | ref arg & ... | test.cpp:442:10:442:12 | tmp |
|
||||
|
||||
@@ -443,17 +443,17 @@ void flowThroughMemcpy_blockvar_with_local_flow(int source1, int b) {
|
||||
}
|
||||
}
|
||||
|
||||
void cleanedByMemcpy_ssa(int clean1) {
|
||||
void cleanedByMemcpy_ssa(int clean1) { // currently modeled with BlockVar, not SSA
|
||||
int tmp;
|
||||
memcpy(&tmp, &clean1, sizeof tmp);
|
||||
sink(tmp); // clean
|
||||
sink(tmp); // clean [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void cleanedByMemcpy_blockvar(int clean1) {
|
||||
int tmp;
|
||||
int *capture = &tmp;
|
||||
memcpy(&tmp, &clean1, sizeof tmp);
|
||||
sink(tmp); // clean
|
||||
sink(tmp); // clean [FALSE POSITIVE]
|
||||
}
|
||||
|
||||
void intRefSource(int &ref_source);
|
||||
|
||||
@@ -30,10 +30,17 @@
|
||||
| test.cpp:433:8:433:10 | tmp | test.cpp:430:48:430:54 | source1 |
|
||||
| test.cpp:440:8:440:10 | tmp | test.cpp:436:53:436:59 | source1 |
|
||||
| test.cpp:442:10:442:12 | tmp | test.cpp:436:53:436:59 | source1 |
|
||||
| test.cpp:449:8:449:10 | tmp | test.cpp:447:7:447:9 | tmp |
|
||||
| test.cpp:456:8:456:10 | tmp | test.cpp:453:7:453:9 | tmp |
|
||||
| test.cpp:466:8:466:12 | local | test.cpp:464:7:464:11 | local |
|
||||
| test.cpp:466:8:466:12 | local | test.cpp:465:16:465:20 | ref arg local |
|
||||
| test.cpp:472:8:472:12 | local | test.cpp:470:7:470:11 | local |
|
||||
| test.cpp:472:8:472:12 | local | test.cpp:471:20:471:25 | ref arg & ... |
|
||||
| test.cpp:478:8:478:12 | local | test.cpp:476:7:476:11 | local |
|
||||
| test.cpp:478:8:478:12 | local | test.cpp:477:20:477:24 | ref arg local |
|
||||
| test.cpp:485:8:485:12 | local | test.cpp:483:7:483:11 | local |
|
||||
| test.cpp:485:8:485:12 | local | test.cpp:484:18:484:23 | ref arg & ... |
|
||||
| test.cpp:491:8:491:12 | local | test.cpp:489:7:489:11 | local |
|
||||
| test.cpp:491:8:491:12 | local | test.cpp:490:18:490:22 | ref arg local |
|
||||
| true_upon_entry.cpp:21:8:21:8 | x | true_upon_entry.cpp:17:11:17:16 | call to source |
|
||||
| true_upon_entry.cpp:29:8:29:8 | x | true_upon_entry.cpp:27:9:27:14 | call to source |
|
||||
|
||||
@@ -11,10 +11,17 @@
|
||||
| test.cpp:430:48:430:54 | test.cpp:433:8:433:10 | AST only |
|
||||
| test.cpp:436:53:436:59 | test.cpp:440:8:440:10 | AST only |
|
||||
| test.cpp:436:53:436:59 | test.cpp:442:10:442:12 | AST only |
|
||||
| test.cpp:447:7:447:9 | test.cpp:449:8:449:10 | AST only |
|
||||
| test.cpp:453:7:453:9 | test.cpp:456:8:456:10 | AST only |
|
||||
| test.cpp:464:7:464:11 | test.cpp:466:8:466:12 | AST only |
|
||||
| test.cpp:465:16:465:20 | test.cpp:466:8:466:12 | AST only |
|
||||
| test.cpp:470:7:470:11 | test.cpp:472:8:472:12 | AST only |
|
||||
| test.cpp:471:20:471:25 | test.cpp:472:8:472:12 | AST only |
|
||||
| test.cpp:476:7:476:11 | test.cpp:478:8:478:12 | AST only |
|
||||
| test.cpp:477:20:477:24 | test.cpp:478:8:478:12 | AST only |
|
||||
| test.cpp:483:7:483:11 | test.cpp:485:8:485:12 | AST only |
|
||||
| test.cpp:484:18:484:23 | test.cpp:485:8:485:12 | AST only |
|
||||
| test.cpp:489:7:489:11 | test.cpp:491:8:491:12 | AST only |
|
||||
| test.cpp:490:18:490:22 | test.cpp:491:8:491:12 | AST only |
|
||||
| true_upon_entry.cpp:9:11:9:16 | true_upon_entry.cpp:13:8:13:8 | IR only |
|
||||
| true_upon_entry.cpp:62:11:62:16 | true_upon_entry.cpp:66:8:66:8 | IR only |
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
| test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:84:13:84:14 | u2 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:85:8:85:9 | u2 |
|
||||
| test.cpp:447:7:447:9 | tmp | test.cpp:448:11:448:13 | tmp |
|
||||
| test.cpp:447:7:447:9 | tmp | test.cpp:449:8:449:10 | tmp |
|
||||
| test.cpp:453:7:453:9 | tmp | test.cpp:454:19:454:21 | tmp |
|
||||
| test.cpp:453:7:453:9 | tmp | test.cpp:455:11:455:13 | tmp |
|
||||
| test.cpp:453:7:453:9 | tmp | test.cpp:456:8:456:10 | tmp |
|
||||
| test.cpp:464:7:464:11 | local | test.cpp:465:16:465:20 | local |
|
||||
| test.cpp:464:7:464:11 | local | test.cpp:466:8:466:12 | local |
|
||||
| test.cpp:470:7:470:11 | local | test.cpp:471:21:471:25 | local |
|
||||
| test.cpp:470:7:470:11 | local | test.cpp:472:8:472:12 | local |
|
||||
| test.cpp:476:7:476:11 | local | test.cpp:477:20:477:24 | local |
|
||||
| test.cpp:476:7:476:11 | local | test.cpp:478:8:478:12 | local |
|
||||
| test.cpp:476:7:476:11 | local | test.cpp:479:9:479:13 | local |
|
||||
| test.cpp:483:7:483:11 | local | test.cpp:484:19:484:23 | local |
|
||||
| test.cpp:483:7:483:11 | local | test.cpp:485:8:485:12 | local |
|
||||
| test.cpp:489:7:489:11 | local | test.cpp:490:18:490:22 | local |
|
||||
| test.cpp:489:7:489:11 | local | test.cpp:491:8:491:12 | local |
|
||||
| test.cpp:489:7:489:11 | local | test.cpp:492:9:492:13 | local |
|
||||
|
||||
@@ -128,13 +128,24 @@
|
||||
| taint.cpp:164:19:164:24 | call to source | taint.cpp:168:8:168:14 | tainted | |
|
||||
| taint.cpp:164:19:164:24 | call to source | taint.cpp:172:18:172:24 | tainted | |
|
||||
| taint.cpp:165:22:165:25 | {...} | taint.cpp:170:10:170:15 | buffer | |
|
||||
| taint.cpp:165:22:165:25 | {...} | taint.cpp:171:8:171:13 | buffer | |
|
||||
| taint.cpp:165:22:165:25 | {...} | taint.cpp:172:10:172:15 | buffer | |
|
||||
| taint.cpp:165:22:165:25 | {...} | taint.cpp:173:8:173:13 | buffer | |
|
||||
| taint.cpp:165:24:165:24 | 0 | taint.cpp:165:22:165:25 | {...} | TAINT |
|
||||
| taint.cpp:170:10:170:15 | buffer | taint.cpp:170:3:170:8 | call to strcpy | |
|
||||
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:170:10:170:15 | buffer | |
|
||||
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:171:8:171:13 | buffer | |
|
||||
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:172:10:172:15 | buffer | |
|
||||
| taint.cpp:170:10:170:15 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
|
||||
| taint.cpp:171:8:171:13 | ref arg buffer | taint.cpp:171:8:171:13 | buffer | |
|
||||
| taint.cpp:171:8:171:13 | ref arg buffer | taint.cpp:172:10:172:15 | buffer | |
|
||||
| taint.cpp:171:8:171:13 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
|
||||
| taint.cpp:172:10:172:15 | buffer | taint.cpp:172:3:172:8 | call to strcat | |
|
||||
| taint.cpp:172:10:172:15 | ref arg buffer | taint.cpp:172:10:172:15 | buffer | |
|
||||
| taint.cpp:172:10:172:15 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
|
||||
| taint.cpp:173:8:173:13 | ref arg buffer | taint.cpp:173:8:173:13 | buffer | |
|
||||
| taint.cpp:180:19:180:19 | p | taint.cpp:181:9:181:9 | p | |
|
||||
| taint.cpp:181:9:181:9 | p | taint.cpp:181:8:181:9 | * ... | TAINT |
|
||||
| taint.cpp:185:11:185:16 | call to source | taint.cpp:186:11:186:11 | x | |
|
||||
| taint.cpp:186:10:186:11 | ref arg & ... | taint.cpp:186:11:186:11 | x | |
|
||||
| taint.cpp:186:11:186:11 | x | taint.cpp:186:10:186:11 | & ... | TAINT |
|
||||
|
||||
Reference in New Issue
Block a user