C++: Add support for 'Element' content in dataflow.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-06-19 13:39:39 +01:00
parent c158f8054e
commit 013ee9c15e
3 changed files with 44 additions and 3 deletions

View File

@@ -1325,7 +1325,7 @@ import IsUnreachableInCall
* Holds if access paths with `c` at their head always should be tracked at high * Holds if access paths with `c` at their head always should be tracked at high
* precision. This disables adaptive access path precision for such access paths. * precision. This disables adaptive access path precision for such access paths.
*/ */
predicate forceHighPrecision(Content c) { none() } predicate forceHighPrecision(Content c) { c instanceof ElementContent }
/** Holds if `n` should be hidden from path explanations. */ /** Holds if `n` should be hidden from path explanations. */
predicate nodeIsHidden(Node n) { predicate nodeIsHidden(Node n) {
@@ -1396,7 +1396,8 @@ private predicate unionHasApproxName(Cpp::Union u, string s) { s = u.getName().c
cached cached
private newtype TContentApprox = private newtype TContentApprox =
TFieldApproxContent(string s) { fieldHasApproxName(_, s) } or TFieldApproxContent(string s) { fieldHasApproxName(_, s) } or
TUnionApproxContent(string s) { unionHasApproxName(_, s) } TUnionApproxContent(string s) { unionHasApproxName(_, s) } or
TElementApproxContent()
/** An approximated `Content`. */ /** An approximated `Content`. */
class ContentApprox extends TContentApprox { class ContentApprox extends TContentApprox {
@@ -1427,6 +1428,10 @@ private class UnionApproxContent extends ContentApprox, TUnionApproxContent {
final override string toString() { result = s } final override string toString() { result = s }
} }
private class ElementApproxContent extends ContentApprox, TElementApproxContent {
final override string toString() { result = "ElementApprox" }
}
/** Gets an approximated value for content `c`. */ /** Gets an approximated value for content `c`. */
pragma[inline] pragma[inline]
ContentApprox getContentApprox(Content c) { ContentApprox getContentApprox(Content c) {
@@ -1441,6 +1446,9 @@ ContentApprox getContentApprox(Content c) {
u = c.(UnionContent).getUnion() and u = c.(UnionContent).getUnion() and
unionHasApproxName(u, prefix) unionHasApproxName(u, prefix)
) )
or
c instanceof ElementContent and
result instanceof ElementApproxContent
} }
/** /**
@@ -1700,6 +1708,14 @@ class DataFlowSecondLevelScope extends TDataFlowSecondLevelScope {
/** Gets the second-level scope containing the node `n`, if any. */ /** Gets the second-level scope containing the node `n`, if any. */
DataFlowSecondLevelScope getSecondLevelScope(Node n) { result.getANode() = n } DataFlowSecondLevelScope getSecondLevelScope(Node n) { result.getANode() = n }
/**
* Gets the maximum number of indirections to use for `ElementContent`.
*
* This should be equal to the largest number of stars (i.e., `*`s) in any
* `Element` content across all of our MaD summaries, sources, and sinks.
*/
int getMaxElementContentIndirectionIndex() { result = 5 }
/** /**
* Module that defines flow through iterators. * Module that defines flow through iterators.
* For example, * For example,

View File

@@ -2083,6 +2083,9 @@ private newtype TContent =
indirectionIndex = indirectionIndex =
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))] [1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
) )
} or
TElementContent(int indirectionIndex) {
indirectionIndex = [1 .. getMaxElementContentIndirectionIndex()]
} }
/** /**
@@ -2193,6 +2196,25 @@ class UnionContent extends Content, TUnionContent {
} }
} }
/**
* A `Content` that represents one of the elements of a
* container (e.g., `std::vector`).
*/
class ElementContent extends Content, TElementContent {
int indirectionIndex;
ElementContent() { this = TElementContent(indirectionIndex) }
pragma[inline]
override int getIndirectionIndex() {
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
}
override predicate impliesClearOf(Content c) { none() }
override string toString() { result = contentStars(this) + "element" }
}
/** /**
* An entity that represents a set of `Content`s. * An entity that represents a set of `Content`s.
* *

View File

@@ -147,7 +147,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink, st
* of `c` at sinks and inputs to additional taint steps. * of `c` at sinks and inputs to additional taint steps.
*/ */
bindingset[node] bindingset[node]
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() } predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) {
node instanceof ArgumentNode and
c.isSingleton(any(ElementContent ec))
}
/** /**
* Holds if `node` should be a sanitizer in all global taint flow configurations * Holds if `node` should be a sanitizer in all global taint flow configurations