Skip to content

Commit 013ee9c

Browse files
committed
C++: Add support for 'Element' content in dataflow.
1 parent c158f80 commit 013ee9c

3 files changed

Lines changed: 44 additions & 3 deletions

File tree

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,7 +1325,7 @@ import IsUnreachableInCall
13251325
* Holds if access paths with `c` at their head always should be tracked at high
13261326
* precision. This disables adaptive access path precision for such access paths.
13271327
*/
1328-
predicate forceHighPrecision(Content c) { none() }
1328+
predicate forceHighPrecision(Content c) { c instanceof ElementContent }
13291329

13301330
/** Holds if `n` should be hidden from path explanations. */
13311331
predicate nodeIsHidden(Node n) {
@@ -1396,7 +1396,8 @@ private predicate unionHasApproxName(Cpp::Union u, string s) { s = u.getName().c
13961396
cached
13971397
private newtype TContentApprox =
13981398
TFieldApproxContent(string s) { fieldHasApproxName(_, s) } or
1399-
TUnionApproxContent(string s) { unionHasApproxName(_, s) }
1399+
TUnionApproxContent(string s) { unionHasApproxName(_, s) } or
1400+
TElementApproxContent()
14001401

14011402
/** An approximated `Content`. */
14021403
class ContentApprox extends TContentApprox {
@@ -1427,6 +1428,10 @@ private class UnionApproxContent extends ContentApprox, TUnionApproxContent {
14271428
final override string toString() { result = s }
14281429
}
14291430

1431+
private class ElementApproxContent extends ContentApprox, TElementApproxContent {
1432+
final override string toString() { result = "ElementApprox" }
1433+
}
1434+
14301435
/** Gets an approximated value for content `c`. */
14311436
pragma[inline]
14321437
ContentApprox getContentApprox(Content c) {
@@ -1441,6 +1446,9 @@ ContentApprox getContentApprox(Content c) {
14411446
u = c.(UnionContent).getUnion() and
14421447
unionHasApproxName(u, prefix)
14431448
)
1449+
or
1450+
c instanceof ElementContent and
1451+
result instanceof ElementApproxContent
14441452
}
14451453

14461454
/**
@@ -1700,6 +1708,14 @@ class DataFlowSecondLevelScope extends TDataFlowSecondLevelScope {
17001708
/** Gets the second-level scope containing the node `n`, if any. */
17011709
DataFlowSecondLevelScope getSecondLevelScope(Node n) { result.getANode() = n }
17021710

1711+
/**
1712+
* Gets the maximum number of indirections to use for `ElementContent`.
1713+
*
1714+
* This should be equal to the largest number of stars (i.e., `*`s) in any
1715+
* `Element` content across all of our MaD summaries, sources, and sinks.
1716+
*/
1717+
int getMaxElementContentIndirectionIndex() { result = 5 }
1718+
17031719
/**
17041720
* Module that defines flow through iterators.
17051721
* For example,

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,9 @@ private newtype TContent =
20832083
indirectionIndex =
20842084
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
20852085
)
2086+
} or
2087+
TElementContent(int indirectionIndex) {
2088+
indirectionIndex = [1 .. getMaxElementContentIndirectionIndex()]
20862089
}
20872090

20882091
/**
@@ -2193,6 +2196,25 @@ class UnionContent extends Content, TUnionContent {
21932196
}
21942197
}
21952198

2199+
/**
2200+
* A `Content` that represents one of the elements of a
2201+
* container (e.g., `std::vector`).
2202+
*/
2203+
class ElementContent extends Content, TElementContent {
2204+
int indirectionIndex;
2205+
2206+
ElementContent() { this = TElementContent(indirectionIndex) }
2207+
2208+
pragma[inline]
2209+
override int getIndirectionIndex() {
2210+
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
2211+
}
2212+
2213+
override predicate impliesClearOf(Content c) { none() }
2214+
2215+
override string toString() { result = contentStars(this) + "element" }
2216+
}
2217+
21962218
/**
21972219
* An entity that represents a set of `Content`s.
21982220
*

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink, st
147147
* of `c` at sinks and inputs to additional taint steps.
148148
*/
149149
bindingset[node]
150-
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
150+
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) {
151+
node instanceof ArgumentNode and
152+
c.isSingleton(any(ElementContent ec))
153+
}
151154

152155
/**
153156
* Holds if `node` should be a sanitizer in all global taint flow configurations

0 commit comments

Comments
 (0)