-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathUseValidIteratorRanges.ql
More file actions
75 lines (71 loc) · 2.94 KB
/
UseValidIteratorRanges.ql
File metadata and controls
75 lines (71 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
/**
* @id cpp/cert/use-valid-iterator-ranges
* @name CTR53-CPP: Use valid iterator ranges
* @description Relying on the incorrect bounds of iterators can lead to inconsistent program
* behavior.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/cert/id/ctr53-cpp
* correctness
* external/cert/severity/high
* external/cert/likelihood/probable
* external/cert/remediation-cost/high
* external/cert/priority/p6
* external/cert/level/l2
* external/cert/obligation/rule
*/
import cpp
import codingstandards.cpp.cert
import codingstandards.cpp.standardlibrary.Iterators
import semmle.code.cpp.dataflow.DataFlow
predicate startEndArgumentsDoNotPointToTheSameContainer(
IteratorRangeFunctionCall fc, Expr arg, string reason
) {
arg = fc.getAStartRangeFunctionCallArgument() and
not exists(STLContainer stl |
DataFlow::localFlow(DataFlow::exprNode(stl.getAnIteratorBeginFunctionCall()),
DataFlow::exprNode(arg))
) and
reason = "The $@ of iterator range function does not point to the start of an iterator."
or
arg = fc.getAEndRangeFunctionCallArgument() and
not exists(STLContainer stl |
DataFlow::localFlow(DataFlow::exprNode(stl.getAnIteratorEndFunctionCall()),
DataFlow::exprNode(arg))
) and
reason = "The $@ of iterator range function does not point to the end of an iterator."
}
predicate startEndArgumentsDoNotPointToSameIterator(
IteratorRangeFunctionCall fc, Expr arg, string reason
) {
exists(Expr start, Expr end, IteratorSource startSource, IteratorSource endSource |
// Start with the actual parameters to the range function (pairwise)
fc.getAStartEndRangeFunctionCallArgumentPair(start, end) and
// get the possible sources that create iterators
startSource = any(STLContainer c).getAnIteratorFunctionCall() and
endSource = any(STLContainer c).getAnIteratorFunctionCall() and
// and get those that flow into this argument
startSource.sourceFor(start) and
endSource.sourceFor(end) and
// and flag ones where the owner is not the same
not startSource.getOwner() = endSource.getOwner() and
arg = start and
reason =
"The start range $@ of iterator range function does not point to the same container as its corresponding end argument."
)
}
from IteratorRangeFunctionCall fc, string reason, Expr arg
where
not isExcluded(fc, IteratorsPackage::useValidIteratorRangesQuery()) and
(
// 1) Require iterators in the range are pointing to the same container.
startEndArgumentsDoNotPointToSameIterator(fc, arg, reason)
or
// 2) That there exists flows into the start/end arguments that are not in fact
// start/end iterators.
startEndArgumentsDoNotPointToTheSameContainer(fc, arg, reason)
// 3) And the iterators are not invalidated. This functionality is a requirement
// of CTR51-CPP and A23-0-2 and it is addressed by those queries.
)
select fc, reason, arg, "argument"