C++: Properly handle setter-related flow in IPA injector.

This commit is contained in:
Mathias Vorreiter Pedersen
2023-05-04 13:59:24 +01:00
parent d3d706d9ab
commit 26206a85dc

View File

@@ -355,51 +355,70 @@ module ProductFlow {
pragma[only_bind_out](succ.getNode().getEnclosingCallable())
}
newtype TKind =
private newtype TKind =
TInto(DataFlowCall call) {
[any(Flow1::PathNode n).getNode(), any(Flow2::PathNode n).getNode()]
.(ArgumentNode)
.getCall() = call
intoImpl1(_, _, call) or
intoImpl2(_, _, call)
} or
TOutOf(DataFlowCall call) {
[any(Flow1::PathNode n).getNode(), any(Flow2::PathNode n).getNode()].(OutNode).getCall() =
call
outImpl1(_, _, call) or
outImpl2(_, _, call)
} or
TJump()
private predicate into1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) {
private predicate intoImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1) and
pred1.getNode().(ArgumentNode).getCall() = call and
succ1.getNode() instanceof ParameterNode
}
private predicate into1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) {
exists(DataFlowCall call |
kind = TInto(call) and
pred1.getNode().(ArgumentNode).getCall() = call and
succ1.getNode() instanceof ParameterNode
intoImpl1(pred1, succ1, call)
)
}
private predicate out1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) {
private predicate outImpl1(Flow1::PathNode pred1, Flow1::PathNode succ1, DataFlowCall call) {
Flow1::PathGraph::edges(pred1, succ1) and
exists(ReturnKindExt returnKind, DataFlowCall call |
kind = TOutOf(call) and
exists(ReturnKindExt returnKind |
succ1.getNode() = returnKind.getAnOutNode(call) and
pred1.getNode().(ReturnNodeExt).getKind() = returnKind
)
}
private predicate into2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) {
private predicate out1(Flow1::PathNode pred1, Flow1::PathNode succ1, TKind kind) {
exists(DataFlowCall call |
outImpl1(pred1, succ1, call) and
kind = TOutOf(call)
)
}
private predicate intoImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2) and
pred2.getNode().(ArgumentNode).getCall() = call and
succ2.getNode() instanceof ParameterNode
}
private predicate into2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) {
exists(DataFlowCall call |
kind = TInto(call) and
pred2.getNode().(ArgumentNode).getCall() = call and
succ2.getNode() instanceof ParameterNode
intoImpl2(pred2, succ2, call)
)
}
private predicate outImpl2(Flow2::PathNode pred2, Flow2::PathNode succ2, DataFlowCall call) {
Flow2::PathGraph::edges(pred2, succ2) and
exists(ReturnKindExt returnKind |
succ2.getNode() = returnKind.getAnOutNode(call) and
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
)
}
private predicate out2(Flow2::PathNode pred2, Flow2::PathNode succ2, TKind kind) {
Flow2::PathGraph::edges(pred2, succ2) and
exists(ReturnKindExt returnKind, DataFlowCall call |
exists(DataFlowCall call |
kind = TOutOf(call) and
succ2.getNode() = returnKind.getAnOutNode(call) and
pred2.getNode().(ReturnNodeExt).getKind() = returnKind
outImpl2(pred2, succ2, call)
)
}