Python: Remove points-to to from ControlFlowNode

Moves the existing points-to predicates to the newly added class
`ControlFlowNodeWithPointsTo` which resides in the `LegacyPointsTo`
module.

(Existing code that uses these predicates should import this module, and
references to `ControlFlowNode` should be changed to
`ControlFlowNodeWithPointsTo`.)

Also updates all existing points-to based code to do just this.
This commit is contained in:
Taus
2025-10-29 22:05:43 +00:00
parent 4461be180a
commit fef08afff9
75 changed files with 410 additions and 236 deletions

View File

@@ -1,4 +1,5 @@
import python
private import LegacyPointsTo
import semmle.python.dataflow.TaintTracking
private import semmle.python.objects.ObjectInternal
private import semmle.python.pointsto.Filters as Filters
@@ -374,7 +375,7 @@ class TaintTrackingImplementation extends string instanceof TaintTracking::Confi
exists(ModuleValue m, string name |
src = TTaintTrackingNode_(_, context, path, kind, this) and
this.moduleAttributeTainted(m, name, src) and
node.asCfgNode().(ImportMemberNode).getModule(name).pointsTo(m)
node.asCfgNode().(ImportMemberNode).getModule(name).(ControlFlowNodeWithPointsTo).pointsTo(m)
)
}
@@ -408,7 +409,9 @@ class TaintTrackingImplementation extends string instanceof TaintTracking::Confi
src = TTaintTrackingNode_(srcnode, context, srcpath, srckind, this) and
exists(CallNode call, ControlFlowNode arg |
call = node.asCfgNode() and
call.getFunction().pointsTo(ObjectInternal::builtin("getattr")) and
call.getFunction()
.(ControlFlowNodeWithPointsTo)
.pointsTo(ObjectInternal::builtin("getattr")) and
arg = call.getArg(0) and
attrname = call.getArg(1).getNode().(StringLiteral).getText() and
arg = srcnode.asCfgNode()
@@ -515,7 +518,7 @@ class TaintTrackingImplementation extends string instanceof TaintTracking::Confi
TaintTrackingContext caller, TaintTrackingContext callee
) {
exists(ClassValue cls |
call.getFunction().pointsTo(cls) and
call.getFunction().(ControlFlowNodeWithPointsTo).pointsTo(cls) and
cls.lookup("__init__") = init
|
exists(int arg, TaintKind callerKind, AttributePath callerPath, DataFlow::Node argument |
@@ -878,7 +881,7 @@ private class EssaTaintTracking extends string instanceof TaintTracking::Configu
const.getNode() instanceof ImmutableLiteral
)
or
exists(ControlFlowNode c, ClassValue cls |
exists(ControlFlowNodeWithPointsTo c, ClassValue cls |
Filters::isinstance(test, c, use) and
c.pointsTo(cls)
|
@@ -978,7 +981,7 @@ module Implementation {
tonode.getArg(0) = fromnode
)
or
tonode.getFunction().pointsTo(ObjectInternal::builtin("reversed")) and
tonode.getFunction().(ControlFlowNodeWithPointsTo).pointsTo(ObjectInternal::builtin("reversed")) and
tonode.getArg(0) = fromnode
}
}

View File

@@ -87,6 +87,7 @@
*/
import python
private import LegacyPointsTo
private import semmle.python.pointsto.Filters as Filters
private import semmle.python.objects.ObjectInternal
private import semmle.python.dataflow.Implementation
@@ -267,7 +268,11 @@ module DictKind {
Implementation::copyCall(fromnode, tonode) and
edgeLabel = "dict copy"
or
tonode.(CallNode).getFunction().pointsTo(ObjectInternal::builtin("dict")) and
tonode
.(CallNode)
.getFunction()
.(ControlFlowNodeWithPointsTo)
.pointsTo(ObjectInternal::builtin("dict")) and
tonode.(CallNode).getArg(0) = fromnode and
edgeLabel = "dict() call"
}
@@ -615,7 +620,7 @@ module DataFlow {
TCfgNode(ControlFlowNode node)
abstract class Node extends TDataFlowNode {
abstract ControlFlowNode asCfgNode();
abstract ControlFlowNodeWithPointsTo asCfgNode();
abstract EssaVariable asVariable();
@@ -632,7 +637,7 @@ module DataFlow {
}
class CfgNode extends Node, TCfgNode {
override ControlFlowNode asCfgNode() { this = TCfgNode(result) }
override ControlFlowNodeWithPointsTo asCfgNode() { this = TCfgNode(result) }
override EssaVariable asVariable() { none() }
@@ -647,7 +652,7 @@ module DataFlow {
}
class EssaNode extends Node, TEssaNode {
override ControlFlowNode asCfgNode() { none() }
override ControlFlowNodeWithPointsTo asCfgNode() { none() }
override EssaVariable asVariable() { this = TEssaNode(result) }
@@ -668,7 +673,11 @@ pragma[noinline]
private predicate dict_construct(ControlFlowNode itemnode, ControlFlowNode dictnode) {
dictnode.(DictNode).getAValue() = itemnode
or
dictnode.(CallNode).getFunction().pointsTo(ObjectInternal::builtin("dict")) and
dictnode
.(CallNode)
.getFunction()
.(ControlFlowNodeWithPointsTo)
.pointsTo(ObjectInternal::builtin("dict")) and
dictnode.(CallNode).getArgByName(_) = itemnode
}
@@ -688,7 +697,7 @@ private predicate sequence_construct(ControlFlowNode itemnode, ControlFlowNode s
pragma[noinline]
private predicate sequence_call(ControlFlowNode fromnode, CallNode tonode) {
tonode.getArg(0) = fromnode and
exists(ControlFlowNode cls | cls = tonode.getFunction() |
exists(ControlFlowNodeWithPointsTo cls | cls = tonode.getFunction() |
cls.pointsTo(ObjectInternal::builtin("list"))
or
cls.pointsTo(ObjectInternal::builtin("tuple"))