Skip to content

Commit 4b3cc5b

Browse files
authored
Merge pull request #17219 from michaelnebel/shared/neutralsourcesink
C#/Java: Fix source- and sink callable provenance overlap.
2 parents b16dc20 + eaf4f5e commit 4b3cc5b

File tree

7 files changed

+53
-71
lines changed

7 files changed

+53
-71
lines changed

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

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -613,32 +613,6 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
613613
}
614614
}
615615

616-
/**
617-
* A callable where there exists a MaD sink model that applies to it.
618-
*/
619-
private class SinkModelCallableAdapter extends SinkModelCallable {
620-
private Provenance provenance;
621-
622-
SinkModelCallableAdapter() {
623-
SourceSinkInterpretationInput::sinkElement(this, _, _, provenance, _)
624-
}
625-
626-
override predicate hasProvenance(Provenance p) { provenance = p }
627-
}
616+
final class SourceCallable = SourceModelCallable;
628617

629618
final class SinkCallable = SinkModelCallable;
630-
631-
/**
632-
* A callable where there exists a MaD source model that applies to it.
633-
*/
634-
private class SourceModelCallableAdapter extends SourceModelCallable {
635-
private Provenance provenance;
636-
637-
SourceModelCallableAdapter() {
638-
SourceSinkInterpretationInput::sourceElement(this, _, _, provenance, _)
639-
}
640-
641-
override predicate hasProvenance(Provenance p) { provenance = p }
642-
}
643-
644-
final class SourceCallable = SourceModelCallable;

csharp/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ext.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ extensions:
66
- [ "Sinks", "NewSinks", False, "Sink", "(System.Object)", "", "Argument[0]", "test-sink", "manual"]
77
- [ "Sinks", "NewSinks", False, "Sink2", "(System.Object)", "", "Argument[0]", "test-sink2", "manual"]
88
- [ "Sinks", "NewSinks", False, "ManualSinkAlreadyDefined", "(System.Object)", "", "Argument[0]", "test-sink", "manual"]
9+
- [ "Sinks", "NewSinks", False, "SaveAndGet", "(System.Object)", "", "Argument[0]", "test-sink", "df-generated"]
10+
11+
- addsTo:
12+
pack: codeql/csharp-all
13+
extensible: sourceModel
14+
data:
15+
- [ "Sinks", "NewSinks", False, "SaveAndGet", "(System.Object)", "", "ReturnValue", "test-source", "manual"]
916

1017
- addsTo:
1118
pack: codeql/csharp-all

csharp/ql/test/utils/modelgenerator/dataflow/Sinks.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ public class NewSinks
2424
// neutral=Sinks;NewSinks;NoSink;(System.Object);summary;df-generated
2525
public static void NoSink(object o) => throw null;
2626

27+
// Sink and Source defined in the extensible file next to the sink test.
28+
// sink=Sinks;NewSinks;false;SaveAndGet;(System.Object);;Argument[0];test-sink;df-generated
29+
// neutral=Sinks;NewSinks;SaveAndGet;(System.Object);summary;df-generated
30+
public static object SaveAndGet(object o)
31+
{
32+
Sink(o);
33+
return null;
34+
}
35+
2736
// New sink
2837
// sink=Sinks;NewSinks;false;WrapResponseWrite;(System.Object);;Argument[0];html-injection;df-generated
2938
// neutral=Sinks;NewSinks;WrapResponseWrite;(System.Object);summary;df-generated

java/ql/lib/semmle/code/java/dataflow/ExternalFlow.qll

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -636,32 +636,6 @@ private class SummarizedCallableAdapter extends SummarizedCallable {
636636
override predicate hasExactModel() { summaryElement(this, _, _, _, _, _, true) }
637637
}
638638

639-
/**
640-
* A callable where there exists a MaD sink model that applies to it.
641-
*/
642-
private class SinkModelCallableAdapter extends SinkModelCallable {
643-
private Provenance provenance;
644-
645-
SinkModelCallableAdapter() {
646-
SourceSinkInterpretationInput::sinkElement(this, _, _, provenance, _)
647-
}
648-
649-
override predicate hasProvenance(Provenance p) { provenance = p }
650-
}
651-
652639
final class SinkCallable = SinkModelCallable;
653640

654-
/**
655-
* A callable where there exists a MaD source model that applies to it.
656-
*/
657-
private class SourceModelCallableAdapter extends SourceModelCallable {
658-
private Provenance provenance;
659-
660-
SourceModelCallableAdapter() {
661-
SourceSinkInterpretationInput::sourceElement(this, _, _, provenance, _)
662-
}
663-
664-
override predicate hasProvenance(Provenance p) { provenance = p }
665-
}
666-
667641
final class SourceCallable = SourceModelCallable;

java/ql/test/utils/modelgenerator/dataflow/CaptureSinkModels.ext.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ extensions:
77
- [ "p", "Sinks", False, "sink", "(Object)", "", "Argument[0]", "test-sink", "manual" ]
88
- [ "p", "Sinks", False, "sink2", "(Object)", "", "Argument[0]", "test-sink2", "manual" ]
99
- [ "p", "Sinks", False, "manualSinkAlreadyDefined", "(Object)", "", "Argument[0]", "test-sink", "manual" ]
10+
- [ "p", "Sinks", False, "saveAndGet", "(Object)", "", "Argument[0]", "test-sink", "df-generated"]
11+
12+
- addsTo:
13+
pack: codeql/java-all
14+
extensible: sourceModel
15+
data:
16+
- [ "p", "Sinks", False, "saveAndGet", "(Object)", "", "ReturnValue", "test-source", "manual"]
1017

1118
- addsTo:
1219
pack: codeql/java-all

java/ql/test/utils/modelgenerator/dataflow/p/Sinks.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ public void sink2(Object o) {}
2525
// neutral=p;Sinks;nosink;(Object);summary;df-generated
2626
public void nosink(Object o) {}
2727

28+
// Sink and Source defined in the extensible file next to the sink test.
29+
// sink=p;Sinks;true;saveAndGet;(Object);;Argument[0];test-sink;df-generated
30+
// neutral=p;Sinks;saveAndGet;(Object);summary;df-generated
31+
public Object saveAndGet(Object o) {
32+
sink(o);
33+
return null;
34+
}
35+
2836
// sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[0];path-injection;df-generated
2937
// sink=p;Sinks;true;copyFileToDirectory;(Path,Path,CopyOption[]);;Argument[1];path-injection;df-generated
3038
// neutral=p;Sinks;copyFileToDirectory;(Path,Path,CopyOption[]);summary;df-generated

shared/dataflow/codeql/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1808,34 +1808,37 @@ module Make<
18081808

18091809
final private class SourceOrSinkElementFinal = SourceOrSinkElement;
18101810

1811-
bindingset[this]
1812-
abstract private class SourceSinkModelCallableBase extends SourceOrSinkElementFinal {
1813-
/**
1814-
* Holds if there exists a manual model that applies to this.
1815-
*/
1816-
final predicate hasManualModel() { any(Provenance p | this.hasProvenance(p)).isManual() }
1811+
signature predicate sourceOrSinkElementSig(
1812+
Element e, string path, string kind, Provenance provenance, string model
1813+
);
18171814

1818-
/**
1819-
* Holds if this has provenance `p`.
1820-
*/
1821-
abstract predicate hasProvenance(Provenance p);
1815+
private module MakeSourceOrSinkCallable<sourceOrSinkElementSig/5 sourceOrSinkElement> {
1816+
class SourceSinkCallable extends SourceOrSinkElementFinal {
1817+
private Provenance provenance;
1818+
1819+
SourceSinkCallable() { sourceOrSinkElement(this, _, _, provenance, _) }
1820+
1821+
/**
1822+
* Holds if there exists a manual model that applies to this.
1823+
*/
1824+
predicate hasManualModel() { any(Provenance p | this.hasProvenance(p)).isManual() }
1825+
1826+
/**
1827+
* Holds if this has provenance `p`.
1828+
*/
1829+
predicate hasProvenance(Provenance p) { provenance = p }
1830+
}
18221831
}
18231832

18241833
/**
18251834
* A callable that has a source model.
18261835
*/
1827-
abstract class SourceModelCallable extends SourceSinkModelCallableBase {
1828-
bindingset[this]
1829-
SourceModelCallable() { exists(this) }
1830-
}
1836+
class SourceModelCallable = MakeSourceOrSinkCallable<sourceElement/5>::SourceSinkCallable;
18311837

18321838
/**
18331839
* A callable that has a sink model.
18341840
*/
1835-
abstract class SinkModelCallable extends SourceSinkModelCallableBase {
1836-
bindingset[this]
1837-
SinkModelCallable() { exists(this) }
1838-
}
1841+
class SinkModelCallable = MakeSourceOrSinkCallable<sinkElement/5>::SourceSinkCallable;
18391842

18401843
/** A source or sink relevant for testing. */
18411844
signature class RelevantSourceOrSinkElementSig extends SourceOrSinkElement {

0 commit comments

Comments
 (0)