Skip to content

Commit 4efbc6e

Browse files
committed
C++: Handle allowInterproceduralFlow correctly in case of recursive functions
1 parent 366ebca commit 4efbc6e

File tree

3 files changed

+8
-29
lines changed

3 files changed

+8
-29
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/MustFlow.qll

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -87,24 +87,12 @@ module MustFlow {
8787
)
8888
}
8989

90-
/**
91-
* Gets the enclosing callable of `n`. Unlike `n.getEnclosingCallable()`, this
92-
* predicate ensures that joins go from `n` to the result instead of the other
93-
* way around.
94-
*/
95-
pragma[inline]
96-
private IRFunction getEnclosingCallable(Instruction n) {
97-
pragma[only_bind_into](result) = pragma[only_bind_out](n).getEnclosingIRFunction()
98-
}
99-
10090
/** Holds if `nodeFrom` flows to `nodeTo`. */
10191
private predicate step(Instruction nodeFrom, Instruction nodeTo) {
102-
Cached::step(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo)) and
103-
(
104-
allowInterproceduralFlow()
105-
or
106-
getEnclosingCallable(nodeFrom) = getEnclosingCallable(nodeTo)
107-
)
92+
Cached::localStep(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo))
93+
or
94+
allowInterproceduralFlow() and
95+
Cached::flowThroughCallable(pragma[only_bind_into](nodeFrom), pragma[only_bind_into](nodeTo))
10896
or
10997
isAdditionalFlowStep(nodeFrom.getAUse(), nodeTo)
11098
}
@@ -230,7 +218,8 @@ module MustFlow {
230218
* Holds if `argument` is an argument (or argument indirection) to a call, and
231219
* `parameter` is the corresponding initialization instruction in the call target.
232220
*/
233-
private predicate flowThroughCallable(Instruction argument, Instruction parameter) {
221+
cached
222+
predicate flowThroughCallable(Instruction argument, Instruction parameter) {
234223
// Flow from an argument to a parameter
235224
exists(CallInstruction call, InitializeParameterInstruction init | init = parameter |
236225
isPositionalArgumentInitParam(call, argument, init, call.getStaticCallTarget())
@@ -279,13 +268,11 @@ module MustFlow {
279268
}
280269

281270
cached
282-
predicate step(Instruction nodeFrom, Instruction nodeTo) {
271+
predicate localStep(Instruction nodeFrom, Instruction nodeTo) {
283272
exists(Operand mid |
284273
instructionToOperandStep(nodeFrom, mid) and
285274
operandToInstructionStep(mid, nodeTo)
286275
)
287-
or
288-
flowThroughCallable(nodeFrom, nodeTo)
289276
}
290277
}
291278
}

cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/ReturnStackAllocatedMemory.expected

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@ edges
4848
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:249:13:249:20 | call to strndupa |
4949
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | s2 |
5050
| test.cpp:250:9:250:10 | s2 | test.cpp:250:9:250:10 | (void *)... |
51-
| test.cpp:253:17:253:17 | p | test.cpp:256:10:256:10 | p |
52-
| test.cpp:255:19:255:20 | & ... | test.cpp:253:17:253:17 | p |
53-
| test.cpp:255:20:255:20 | x | test.cpp:255:19:255:20 | & ... |
5451
nodes
5552
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
5653
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
@@ -117,10 +114,6 @@ nodes
117114
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
118115
| test.cpp:250:9:250:10 | (void *)... | semmle.label | (void *)... |
119116
| test.cpp:250:9:250:10 | s2 | semmle.label | s2 |
120-
| test.cpp:253:17:253:17 | p | semmle.label | p |
121-
| test.cpp:255:19:255:20 | & ... | semmle.label | & ... |
122-
| test.cpp:255:20:255:20 | x | semmle.label | x |
123-
| test.cpp:256:10:256:10 | p | semmle.label | p |
124117
#select
125118
| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
126119
| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
@@ -138,4 +131,3 @@ nodes
138131
| test.cpp:238:9:238:9 | Load: p | test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p | May return stack-allocated memory from $@. | test.cpp:237:12:237:17 | call to alloca | call to alloca |
139132
| test.cpp:245:9:245:15 | Call: call to strdupa | test.cpp:245:9:245:15 | call to strdupa | test.cpp:245:9:245:15 | call to strdupa | May return stack-allocated memory from $@. | test.cpp:245:9:245:15 | call to strdupa | call to strdupa |
140133
| test.cpp:250:9:250:10 | Convert: (void *)... | test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | (void *)... | May return stack-allocated memory from $@. | test.cpp:249:13:249:20 | call to strndupa | call to strndupa |
141-
| test.cpp:256:10:256:10 | Load: p | test.cpp:255:20:255:20 | x | test.cpp:256:10:256:10 | p | May return stack-allocated memory from $@. | test.cpp:255:20:255:20 | x | x |

cpp/ql/test/query-tests/Likely Bugs/Memory Management/ReturnStackAllocatedMemory/test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,6 @@ void* test_strndupa(const char* s, size_t size) {
252252

253253
int* f_rec(int *p, bool b) {
254254
int x;
255-
int* px = f_rec(&x, b); // GOOD [FALSE POSITIVE]
255+
int* px = f_rec(&x, b); // GOOD
256256
return p;
257257
}

0 commit comments

Comments
 (0)