Skip to content

Commit d0d1363

Browse files
committed
unified: Move ad-hoc aliasing logic into a step
1 parent 3f7735f commit d0d1363

3 files changed

Lines changed: 22 additions & 15 deletions

File tree

‎unified/ql/lib/codeql/unified/internal/dataflow/CaptureSsa.qll‎

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ module CaptureSsaInput implements InputSig<Location, BasicBlock> {
7171
node.(BuilderNode).isCallable(callable)
7272
or
7373
exists(Stage2Node prev | callableHasLocalAlias(callable, prev) |
74-
step(prev, any(Step s | s.value()), node)
74+
step(prev, any(Step s | s.value() or s.callGraph()), node)
7575
or
7676
localSsaStep(prev, node, _)
7777
)
@@ -101,19 +101,6 @@ module CaptureSsaInput implements InputSig<Location, BasicBlock> {
101101
predicate hasAliasedAccess(Expr f) {
102102
// TODO: Restrict to places where the function is called or escapes into a call where it might get called.
103103
callableHasLocalAlias(callable, f) and not f.(LocalVariableRefNode).getRefKind().isWrite()
104-
or
105-
// Record the callee argument passed into a local capturing getter/setter as an alias for that getter/setter
106-
// so it can carry capture data in and out of the getter/setter call.
107-
exists(ComputedLocalVariable local, DataFlowCall call |
108-
callable = local.getAnAccessor() and
109-
f = TImplicitArgumentNode(call, any(ArgumentPosition p | p.isCallee()), false)
110-
|
111-
callable instanceof GetterDeclaration and
112-
call.asGetterCall() = local.getAnAccess()
113-
or
114-
callable instanceof SetterDeclaration and
115-
call.asSetterCall() = local.getAnAccess()
116-
)
117104
}
118105
}
119106
}

‎unified/ql/lib/codeql/unified/internal/dataflow/DataFlowGraph.qll‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,20 @@ predicate step(BuilderNode node1, Step step, BuilderNode node2) {
161161
node2.isIncomingValue(arg.getValue())
162162
)
163163
or
164+
// For local getters/setters, pass the callable into the callee argument.
165+
// Capture SSA depends on this.
166+
exists(ComputedLocalVariable local, AccessorDeclaration accessor, DataFlowCall call |
167+
accessor = local.getAnAccessor() and
168+
node1.isCallable(accessor) and
169+
step.callGraph() and
170+
(
171+
call.asGetterCall() = local.getAnAccess() and accessor instanceof GetterDeclaration
172+
or
173+
call.asSetterCall() = local.getAnAccess() and accessor instanceof SetterDeclaration
174+
) and
175+
node2.isImplicitArgument(call, any(ArgumentPosition pos | pos.isCallee()), false)
176+
)
177+
or
164178
exists(SwitchExpr expr |
165179
node1.isResultValue(expr.getValue()) and
166180
step.value() and

‎unified/ql/lib/codeql/unified/internal/dataflow/Step.qll‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ private newtype TStep =
77
TJumpStep() or
88
TTaintStep() or
99
TReadStep(ContentSet contents) or
10-
TStoreStep(ContentSet contents)
10+
TStoreStep(ContentSet contents) or
11+
TCallGraphStep()
1112

1213
/**
1314
* A type of data flow step, used during construction of the data flow graph.
@@ -47,6 +48,9 @@ class Step extends TStep {
4748
pragma[nomagic]
4849
predicate storeArrayElement() { this.store(ContentSet::arrayElement()) }
4950

51+
/** Holds if this step can only be used for call graph construction. */
52+
predicate callGraph() { this = TCallGraphStep() }
53+
5054
string toString() {
5155
this.value() and result = "value"
5256
or
@@ -61,5 +65,7 @@ class Step extends TStep {
6165
or
6266
this.store(contents) and result = "store[" + contents + "]"
6367
)
68+
or
69+
this.callGraph() and result = "call-graph"
6470
}
6571
}

0 commit comments

Comments
 (0)