Skip to content

Commit 69bf13b

Browse files
committed
Dataflow: Sync.
1 parent 2848909 commit 69bf13b

File tree

4 files changed

+212
-8
lines changed

4 files changed

+212
-8
lines changed

csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ module Public {
6161

6262
/** Gets a summary component for a return of kind `rk`. */
6363
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
64+
65+
/** Gets a summary component for synthetic global `sg`. */
66+
SummaryComponent syntheticGlobal(SyntheticGlobal sg) {
67+
result = TSyntheticGlobalSummaryComponent(sg)
68+
}
69+
70+
/**
71+
* A synthetic global. This represents some form of global state, which
72+
* summaries can read and write individually.
73+
*/
74+
abstract class SyntheticGlobal extends string {
75+
bindingset[this]
76+
SyntheticGlobal() { any() }
77+
}
6478
}
6579

6680
/**
@@ -256,6 +270,7 @@ module Private {
256270
TParameterSummaryComponent(ArgumentPosition pos) or
257271
TArgumentSummaryComponent(ParameterPosition pos) or
258272
TReturnSummaryComponent(ReturnKind rk) or
273+
TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or
259274
TWithoutContentSummaryComponent(ContentSet c) or
260275
TWithContentSummaryComponent(ContentSet c)
261276

@@ -563,6 +578,11 @@ module Private {
563578
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
564579
s.tail())), rk)
565580
)
581+
or
582+
exists(SummaryComponent::SyntheticGlobal sg |
583+
head = TSyntheticGlobalSummaryComponent(sg) and
584+
result = getSyntheticGlobalType(sg)
585+
)
566586
)
567587
or
568588
n = summaryNodeOutputState(c, s) and
@@ -582,6 +602,11 @@ module Private {
582602
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
583603
s.tail())), pos)
584604
)
605+
or
606+
exists(SummaryComponent::SyntheticGlobal sg |
607+
head = TSyntheticGlobalSummaryComponent(sg) and
608+
result = getSyntheticGlobalType(sg)
609+
)
585610
)
586611
)
587612
}
@@ -692,6 +717,18 @@ module Private {
692717
)
693718
}
694719

720+
/**
721+
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
722+
* from a flow summary.
723+
*/
724+
predicate summaryJumpStep(Node pred, Node succ) {
725+
exists(SummaryComponentStack s |
726+
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
727+
pred = summaryNodeOutputState(_, s) and
728+
succ = summaryNodeInputState(_, s)
729+
)
730+
}
731+
695732
/**
696733
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
697734
* synthesized summary node, so in order for values to be cleared at calls
@@ -871,18 +908,28 @@ module Private {
871908
AccessPathRange() { relevantSpec(this) }
872909
}
873910

874-
/** Holds if specification component `c` parses as parameter `n`. */
911+
/** Holds if specification component `token` parses as parameter `pos`. */
875912
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
876913
token.getName() = "Parameter" and
877914
pos = parseParamBody(token.getAnArgument())
878915
}
879916

880-
/** Holds if specification component `c` parses as argument `n`. */
917+
/** Holds if specification component `token` parses as argument `pos`. */
881918
predicate parseArg(AccessPathToken token, ParameterPosition pos) {
882919
token.getName() = "Argument" and
883920
pos = parseArgBody(token.getAnArgument())
884921
}
885922

923+
/** Holds if specification component `token` parses as synthetic global `sg`. */
924+
predicate parseSynthGlobal(AccessPathToken token, string sg) {
925+
token.getName() = "SyntheticGlobal" and
926+
sg = token.getAnArgument()
927+
}
928+
929+
private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal {
930+
SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) }
931+
}
932+
886933
private SummaryComponent interpretComponent(AccessPathToken token) {
887934
exists(ParameterPosition pos |
888935
parseArg(token, pos) and result = SummaryComponent::argument(pos)
@@ -894,6 +941,10 @@ module Private {
894941
or
895942
token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
896943
or
944+
exists(string sg |
945+
parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg)
946+
)
947+
or
897948
result = interpretComponentSpecific(token)
898949
}
899950

python/ql/lib/semmle/python/dataflow/new/internal/FlowSummaryImpl.qll

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ module Public {
6161

6262
/** Gets a summary component for a return of kind `rk`. */
6363
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
64+
65+
/** Gets a summary component for synthetic global `sg`. */
66+
SummaryComponent syntheticGlobal(SyntheticGlobal sg) {
67+
result = TSyntheticGlobalSummaryComponent(sg)
68+
}
69+
70+
/**
71+
* A synthetic global. This represents some form of global state, which
72+
* summaries can read and write individually.
73+
*/
74+
abstract class SyntheticGlobal extends string {
75+
bindingset[this]
76+
SyntheticGlobal() { any() }
77+
}
6478
}
6579

6680
/**
@@ -256,6 +270,7 @@ module Private {
256270
TParameterSummaryComponent(ArgumentPosition pos) or
257271
TArgumentSummaryComponent(ParameterPosition pos) or
258272
TReturnSummaryComponent(ReturnKind rk) or
273+
TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or
259274
TWithoutContentSummaryComponent(ContentSet c) or
260275
TWithContentSummaryComponent(ContentSet c)
261276

@@ -563,6 +578,11 @@ module Private {
563578
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
564579
s.tail())), rk)
565580
)
581+
or
582+
exists(SummaryComponent::SyntheticGlobal sg |
583+
head = TSyntheticGlobalSummaryComponent(sg) and
584+
result = getSyntheticGlobalType(sg)
585+
)
566586
)
567587
or
568588
n = summaryNodeOutputState(c, s) and
@@ -582,6 +602,11 @@ module Private {
582602
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
583603
s.tail())), pos)
584604
)
605+
or
606+
exists(SummaryComponent::SyntheticGlobal sg |
607+
head = TSyntheticGlobalSummaryComponent(sg) and
608+
result = getSyntheticGlobalType(sg)
609+
)
585610
)
586611
)
587612
}
@@ -692,6 +717,18 @@ module Private {
692717
)
693718
}
694719

720+
/**
721+
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
722+
* from a flow summary.
723+
*/
724+
predicate summaryJumpStep(Node pred, Node succ) {
725+
exists(SummaryComponentStack s |
726+
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
727+
pred = summaryNodeOutputState(_, s) and
728+
succ = summaryNodeInputState(_, s)
729+
)
730+
}
731+
695732
/**
696733
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
697734
* synthesized summary node, so in order for values to be cleared at calls
@@ -871,18 +908,28 @@ module Private {
871908
AccessPathRange() { relevantSpec(this) }
872909
}
873910

874-
/** Holds if specification component `c` parses as parameter `n`. */
911+
/** Holds if specification component `token` parses as parameter `pos`. */
875912
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
876913
token.getName() = "Parameter" and
877914
pos = parseParamBody(token.getAnArgument())
878915
}
879916

880-
/** Holds if specification component `c` parses as argument `n`. */
917+
/** Holds if specification component `token` parses as argument `pos`. */
881918
predicate parseArg(AccessPathToken token, ParameterPosition pos) {
882919
token.getName() = "Argument" and
883920
pos = parseArgBody(token.getAnArgument())
884921
}
885922

923+
/** Holds if specification component `token` parses as synthetic global `sg`. */
924+
predicate parseSynthGlobal(AccessPathToken token, string sg) {
925+
token.getName() = "SyntheticGlobal" and
926+
sg = token.getAnArgument()
927+
}
928+
929+
private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal {
930+
SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) }
931+
}
932+
886933
private SummaryComponent interpretComponent(AccessPathToken token) {
887934
exists(ParameterPosition pos |
888935
parseArg(token, pos) and result = SummaryComponent::argument(pos)
@@ -894,6 +941,10 @@ module Private {
894941
or
895942
token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
896943
or
944+
exists(string sg |
945+
parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg)
946+
)
947+
or
897948
result = interpretComponentSpecific(token)
898949
}
899950

ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,20 @@ module Public {
6161

6262
/** Gets a summary component for a return of kind `rk`. */
6363
SummaryComponent return(ReturnKind rk) { result = TReturnSummaryComponent(rk) }
64+
65+
/** Gets a summary component for synthetic global `sg`. */
66+
SummaryComponent syntheticGlobal(SyntheticGlobal sg) {
67+
result = TSyntheticGlobalSummaryComponent(sg)
68+
}
69+
70+
/**
71+
* A synthetic global. This represents some form of global state, which
72+
* summaries can read and write individually.
73+
*/
74+
abstract class SyntheticGlobal extends string {
75+
bindingset[this]
76+
SyntheticGlobal() { any() }
77+
}
6478
}
6579

6680
/**
@@ -256,6 +270,7 @@ module Private {
256270
TParameterSummaryComponent(ArgumentPosition pos) or
257271
TArgumentSummaryComponent(ParameterPosition pos) or
258272
TReturnSummaryComponent(ReturnKind rk) or
273+
TSyntheticGlobalSummaryComponent(SummaryComponent::SyntheticGlobal sg) or
259274
TWithoutContentSummaryComponent(ContentSet c) or
260275
TWithContentSummaryComponent(ContentSet c)
261276

@@ -563,6 +578,11 @@ module Private {
563578
getCallbackReturnType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
564579
s.tail())), rk)
565580
)
581+
or
582+
exists(SummaryComponent::SyntheticGlobal sg |
583+
head = TSyntheticGlobalSummaryComponent(sg) and
584+
result = getSyntheticGlobalType(sg)
585+
)
566586
)
567587
or
568588
n = summaryNodeOutputState(c, s) and
@@ -582,6 +602,11 @@ module Private {
582602
getCallbackParameterType(getNodeType(summaryNodeInputState(pragma[only_bind_out](c),
583603
s.tail())), pos)
584604
)
605+
or
606+
exists(SummaryComponent::SyntheticGlobal sg |
607+
head = TSyntheticGlobalSummaryComponent(sg) and
608+
result = getSyntheticGlobalType(sg)
609+
)
585610
)
586611
)
587612
}
@@ -692,6 +717,18 @@ module Private {
692717
)
693718
}
694719

720+
/**
721+
* Holds if there is a jump step from `pred` to `succ`, which is synthesized
722+
* from a flow summary.
723+
*/
724+
predicate summaryJumpStep(Node pred, Node succ) {
725+
exists(SummaryComponentStack s |
726+
s = SummaryComponentStack::singleton(SummaryComponent::syntheticGlobal(_)) and
727+
pred = summaryNodeOutputState(_, s) and
728+
succ = summaryNodeInputState(_, s)
729+
)
730+
}
731+
695732
/**
696733
* Holds if values stored inside content `c` are cleared at `n`. `n` is a
697734
* synthesized summary node, so in order for values to be cleared at calls
@@ -871,18 +908,28 @@ module Private {
871908
AccessPathRange() { relevantSpec(this) }
872909
}
873910

874-
/** Holds if specification component `c` parses as parameter `n`. */
911+
/** Holds if specification component `token` parses as parameter `pos`. */
875912
predicate parseParam(AccessPathToken token, ArgumentPosition pos) {
876913
token.getName() = "Parameter" and
877914
pos = parseParamBody(token.getAnArgument())
878915
}
879916

880-
/** Holds if specification component `c` parses as argument `n`. */
917+
/** Holds if specification component `token` parses as argument `pos`. */
881918
predicate parseArg(AccessPathToken token, ParameterPosition pos) {
882919
token.getName() = "Argument" and
883920
pos = parseArgBody(token.getAnArgument())
884921
}
885922

923+
/** Holds if specification component `token` parses as synthetic global `sg`. */
924+
predicate parseSynthGlobal(AccessPathToken token, string sg) {
925+
token.getName() = "SyntheticGlobal" and
926+
sg = token.getAnArgument()
927+
}
928+
929+
private class SyntheticGlobalFromAccessPath extends SummaryComponent::SyntheticGlobal {
930+
SyntheticGlobalFromAccessPath() { parseSynthGlobal(_, this) }
931+
}
932+
886933
private SummaryComponent interpretComponent(AccessPathToken token) {
887934
exists(ParameterPosition pos |
888935
parseArg(token, pos) and result = SummaryComponent::argument(pos)
@@ -894,6 +941,10 @@ module Private {
894941
or
895942
token = "ReturnValue" and result = SummaryComponent::return(getReturnValueKind())
896943
or
944+
exists(string sg |
945+
parseSynthGlobal(token, sg) and result = SummaryComponent::syntheticGlobal(sg)
946+
)
947+
or
897948
result = interpretComponentSpecific(token)
898949
}
899950

0 commit comments

Comments
 (0)