Skip to content

Commit 6359388

Browse files
authored
Merge pull request #16915 from MathiasVP/fix-iterator-to-expired-container-fp-4
C++: Fix `cpp/iterator-to-expired-container` FPs
2 parents 39ad4d4 + 0e6b2f0 commit 6359388

File tree

6 files changed

+79
-12
lines changed

6 files changed

+79
-12
lines changed

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

+22-10
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
104104

105105
cached
106106
private newtype TDefImpl =
107-
TDefAddressImpl(BaseIRVariable v) or
107+
TDefAddressImpl(BaseSourceVariable v) or
108108
TDirectDefImpl(Operand address, int indirectionIndex) {
109109
isDef(_, _, address, _, _, indirectionIndex)
110110
} or
@@ -325,9 +325,9 @@ private Instruction getInitializationTargetAddress(IRVariable v) {
325325
)
326326
}
327327

328-
/** An initial definition of an `IRVariable`'s address. */
329-
private class DefAddressImpl extends DefImpl, TDefAddressImpl {
330-
BaseIRVariable v;
328+
/** An initial definition of an SSA variable address. */
329+
abstract private class DefAddressImpl extends DefImpl, TDefAddressImpl {
330+
BaseSourceVariable v;
331331

332332
DefAddressImpl() {
333333
this = TDefAddressImpl(v) and
@@ -342,6 +342,19 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl {
342342

343343
final override Node0Impl getValue() { none() }
344344

345+
override Cpp::Location getLocation() { result = v.getLocation() }
346+
347+
final override SourceVariable getSourceVariable() {
348+
result.getBaseVariable() = v and
349+
result.getIndirection() = 0
350+
}
351+
352+
final override BaseSourceVariable getBaseSourceVariable() { result = v }
353+
}
354+
355+
private class DefVariableAddressImpl extends DefAddressImpl {
356+
override BaseIRVariable v;
357+
345358
final override predicate hasIndexInBlock(IRBlock block, int index) {
346359
exists(IRVariable var | var = v.getIRVariable() |
347360
block.getInstruction(index) = getInitializationTargetAddress(var)
@@ -353,15 +366,14 @@ private class DefAddressImpl extends DefImpl, TDefAddressImpl {
353366
index = 0
354367
)
355368
}
369+
}
356370

357-
override Cpp::Location getLocation() { result = v.getIRVariable().getLocation() }
371+
private class DefCallAddressImpl extends DefAddressImpl {
372+
override BaseCallVariable v;
358373

359-
final override SourceVariable getSourceVariable() {
360-
result.getBaseVariable() = v and
361-
result.getIndirection() = 0
374+
final override predicate hasIndexInBlock(IRBlock block, int index) {
375+
block.getInstruction(index) = v.getCallInstruction()
362376
}
363-
364-
final override BaseSourceVariable getBaseSourceVariable() { result = v }
365377
}
366378

367379
private class DirectDef extends DefImpl, TDirectDefImpl {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace std
2+
{
3+
struct ptrdiff_t;
4+
struct input_iterator_tag
5+
{
6+
};
7+
struct forward_iterator_tag : public input_iterator_tag
8+
{
9+
};
10+
}
11+
12+
struct A
13+
{
14+
using value_type = int;
15+
using difference_type = std::ptrdiff_t;
16+
using pointer = int*;
17+
using reference = int&;
18+
using iterator_category = std::forward_iterator_tag;
19+
};
20+
21+
A get();
22+
23+
void test()
24+
{
25+
while (true)
26+
{
27+
auto &&x = get();
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
edges
2+
nodes
3+
subpaths
4+
#select
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @kind path-problem
3+
*/
4+
5+
import semmle.code.cpp.ir.IR
6+
import semmle.code.cpp.dataflow.new.DataFlow
7+
import Flow::PathGraph
8+
9+
module Config implements DataFlow::ConfigSig {
10+
predicate isSource(DataFlow::Node source) {
11+
source.asInstruction().(VariableAddressInstruction).getIRVariable() instanceof IRTempVariable
12+
}
13+
14+
predicate isSink(DataFlow::Node sink) {
15+
sink.asInstruction().(CallInstruction).getStaticCallTarget().hasName("get")
16+
}
17+
}
18+
19+
module Flow = DataFlow::Global<Config>;
20+
21+
from Flow::PathNode source, Flow::PathNode sink
22+
where Flow::flowPath(source, sink)
23+
select sink.getNode(), source, sink, ""

cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/IteratorToExpiredContainer.expected

-1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,3 @@
33
| test.cpp:702:27:702:27 | call to operator[] | This object is destroyed at the end of the full-expression. |
44
| test.cpp:727:23:727:23 | call to operator[] | This object is destroyed at the end of the full-expression. |
55
| test.cpp:735:23:735:23 | call to operator[] | This object is destroyed at the end of the full-expression. |
6-
| test.cpp:826:25:826:43 | pointer to ~HasBeginAndEnd output argument | This object is destroyed at the end of the full-expression. |

cpp/ql/test/query-tests/Security/CWE/CWE-416/semmle/tests/IteratorToExpiredContainer/test.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ void test6()
823823
{
824824
while(getBool())
825825
{
826-
for (const int& x : getHasBeginAndEnd()) // GOOD [FALSE POSITIVE]
826+
for (const int& x : getHasBeginAndEnd()) // GOOD
827827
{
828828
}
829829
}

0 commit comments

Comments
 (0)