Skip to content

Commit 3d73432

Browse files
authored
Merge pull request #19813 from github/kaspersv/overlay-java-discarding
Overlay: Add manual Java overlay annotations & discard predicates
2 parents 7c38c48 + c7194a4 commit 3d73432

File tree

15 files changed

+139
-1
lines changed

15 files changed

+139
-1
lines changed

java/ql/lib/semmle/code/Location.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module;
88

99
import FileSystem
1010
import semmle.code.java.Element
11+
private import semmle.code.java.Overlay
1112
private import semmle.code.SMAP
1213

1314
/** Holds if element `e` has name `name`. */
@@ -221,3 +222,16 @@ private predicate fixedHasLocation(Top l, Location loc, File f) {
221222
not hasSourceLocation(l, _, _) and
222223
locations_default(loc, f, _, _, _, _)
223224
}
225+
226+
overlay[local]
227+
private predicate discardableLocation(string file, @location l) {
228+
not isOverlay() and
229+
file = getRawFileForLoc(l) and
230+
not exists(@file f | hasLocation(f, l))
231+
}
232+
233+
/** Discard base locations in files fully extracted in the overlay. */
234+
overlay[discard_entity]
235+
private predicate discardLocation(@location l) {
236+
exists(string file | discardableLocation(file, l) and extractedInOverlay(file))
237+
}

java/ql/lib/semmle/code/java/Expr.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module;
77
import java
88
private import semmle.code.java.frameworks.android.Compose
99
private import semmle.code.java.Constants
10+
private import semmle.code.java.Overlay
1011

1112
/** A common super-class that represents all kinds of expressions. */
1213
class Expr extends ExprParent, @expr {
@@ -2701,3 +2702,6 @@ class RecordPatternExpr extends Expr, @recordpatternexpr {
27012702
)
27022703
}
27032704
}
2705+
2706+
overlay[local]
2707+
private class DiscardableExpr extends DiscardableLocatable, @expr { }

java/ql/lib/semmle/code/java/Javadoc.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ overlay[local?]
55
module;
66

77
import semmle.code.Location
8+
private import semmle.code.java.Overlay
89

910
/** A Javadoc parent is an element whose child can be some Javadoc documentation. */
1011
class JavadocParent extends @javadocParent, Top {
@@ -196,3 +197,6 @@ class KtCommentSection extends @ktcommentsection {
196197
/** Gets the string representation of this section. */
197198
string toString() { result = this.getContent() }
198199
}
200+
201+
overlay[local]
202+
private class DiscardableJavadoc extends DiscardableLocatable, @javadoc { }

java/ql/lib/semmle/code/java/Member.qll

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Annotation
1111
import Exception
1212
import metrics.MetricField
1313
private import dispatch.VirtualDispatch
14+
private import semmle.code.java.Overlay
1415

1516
/**
1617
* A common abstraction for type member declarations,
@@ -623,7 +624,13 @@ class SrcMethod extends Method {
623624
then implementsInterfaceMethod(result, this)
624625
else result.getASourceOverriddenMethod*() = this
625626
) and
626-
(exists(result.getBody()) or result.hasModifier("native"))
627+
(
628+
// We allow empty method bodies for the local overlay variant to allow
629+
// calls to methods only fully extracted in base.
630+
isOverlay() or
631+
exists(result.getBody()) or
632+
result.hasModifier("native")
633+
)
627634
}
628635
}
629636

@@ -897,3 +904,13 @@ class ExtensionMethod extends Method {
897904
else result = 0
898905
}
899906
}
907+
908+
overlay[local]
909+
private class DiscardableAnonymousMethod extends DiscardableLocatable, @method {
910+
DiscardableAnonymousMethod() {
911+
exists(@classorinterface c | methods(this, _, _, _, c, _) and isAnonymClass(c, _))
912+
}
913+
}
914+
915+
overlay[local]
916+
private class DiscardableMethod extends DiscardableReferableLocatable, @method { }
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Defines entity discard predicates for Java overlay analysis.
3+
*/
4+
overlay[local?]
5+
module;
6+
7+
import java
8+
9+
/**
10+
* A local predicate that always holds for the overlay variant and
11+
* never holds for the base variant. This is used to define local
12+
* predicates that behave differently for the base and overlay variant.
13+
*/
14+
overlay[local]
15+
predicate isOverlay() { databaseMetadata("isOverlay", "true") }
16+
17+
/** Gets the raw file for a locatable. */
18+
overlay[local]
19+
string getRawFile(@locatable el) {
20+
exists(@location loc, @file file |
21+
hasLocation(el, loc) and
22+
locations_default(loc, file, _, _, _, _) and
23+
files(file, result)
24+
)
25+
}
26+
27+
/** Gets the raw file for a location. */
28+
overlay[local]
29+
string getRawFileForLoc(@location l) {
30+
exists(@file f | locations_default(l, f, _, _, _, _) and files(f, result))
31+
}
32+
33+
/** Holds for files fully extracted in the overlay. */
34+
overlay[local]
35+
predicate extractedInOverlay(string file) {
36+
isOverlay() and
37+
// numlines is used to restrict attention to fully extracted files and
38+
// ignore skeleton extracted files in the overlay
39+
exists(@locatable l | numlines(l, _, _, _) and file = getRawFile(l))
40+
}
41+
42+
/**
43+
* A `@locatable` that should be discarded in the base variant if its file is
44+
* extracted in the overlay variant.
45+
*/
46+
overlay[local]
47+
abstract class DiscardableLocatable extends @locatable {
48+
/** Gets the raw file for a locatable in base. */
49+
string getRawFileInBase() { not isOverlay() and result = getRawFile(this) }
50+
51+
/** Gets a textual representation of this discardable locatable. */
52+
string toString() { none() }
53+
}
54+
55+
overlay[discard_entity]
56+
private predicate discardLocatable(@locatable el) {
57+
extractedInOverlay(el.(DiscardableLocatable).getRawFileInBase())
58+
}
59+
60+
/**
61+
* A `@locatable` that should be discarded in the base variant if its file is
62+
* extracted in the overlay variant and it is itself not extracted in the
63+
* overlay, that is, it is deleted in the overlay.
64+
*/
65+
overlay[local]
66+
abstract class DiscardableReferableLocatable extends @locatable {
67+
/** Gets the raw file for a locatable in base. */
68+
string getRawFileInBase() { not isOverlay() and result = getRawFile(this) }
69+
70+
/** Holds if the locatable exists in the overlay. */
71+
predicate existsInOverlay() { isOverlay() and exists(this) }
72+
73+
/** Gets a textual representation of this discardable locatable. */
74+
string toString() { none() }
75+
}
76+
77+
overlay[discard_entity]
78+
private predicate discardReferableLocatable(@locatable el) {
79+
exists(DiscardableReferableLocatable drl | drl = el |
80+
extractedInOverlay(drl.getRawFileInBase()) and
81+
not drl.existsInOverlay()
82+
)
83+
}

java/ql/lib/semmle/code/java/Statement.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module;
66

77
import Expr
88
import metrics.MetricStmt
9+
private import semmle.code.java.Overlay
910

1011
/** A common super-class of all statements. */
1112
class Stmt extends StmtParent, ExprParent, @stmt {
@@ -987,3 +988,6 @@ class SuperConstructorInvocationStmt extends Stmt, ConstructorCall, @superconstr
987988

988989
override string getAPrimaryQlClass() { result = "SuperConstructorInvocationStmt" }
989990
}
991+
992+
overlay[local]
993+
private class DiscardableStmt extends DiscardableLocatable, @stmt { }

java/ql/lib/semmle/code/java/Variable.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ overlay[local?]
55
module;
66

77
import Element
8+
private import semmle.code.java.Overlay
89

910
/** A variable is a field, a local variable or a parameter. */
1011
class Variable extends @variable, Annotatable, Element, Modifiable {
@@ -133,3 +134,6 @@ class Parameter extends Element, @param, LocalScopeVariable {
133134
/** Holds if this is an anonymous parameter, `_` */
134135
predicate isAnonymous() { this.getName() = "" }
135136
}
137+
138+
overlay[local]
139+
private class DiscardableLocalScopeVariable extends DiscardableLocatable, @localscopevariable { }

java/ql/src/experimental/Security/CWE/CWE-020/Log4jJndiInjection.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import semmle.code.java.dataflow.ExternalFlow
2222
private import semmle.code.java.security.Sanitizers
2323
import Log4jInjectionFlow::PathGraph
2424

25+
overlay[local?]
2526
deprecated private class ActivateModels extends ActiveExperimentalModels {
2627
ActivateModels() { this = "log4j-injection" }
2728
}

java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import semmle.code.java.dataflow.FlowSources
1717
import semmle.code.java.dataflow.ExternalFlow
1818
import RemoteUrlToOpenStreamFlow::PathGraph
1919

20+
overlay[local?]
2021
deprecated private class ActivateModels extends ActiveExperimentalModels {
2122
ActivateModels() { this = "openstream-called-on-tainted-url" }
2223
}

java/ql/src/experimental/Security/CWE/CWE-073/FilePathInjection.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import semmle.code.java.security.PathSanitizer
2222
private import semmle.code.java.security.Sanitizers
2323
import InjectFilePathFlow::PathGraph
2424

25+
overlay[local?]
2526
deprecated private class ActivateModels extends ActiveExperimentalModels {
2627
ActivateModels() { this = "file-path-injection" }
2728
}

java/ql/src/experimental/Security/CWE/CWE-078/ExecTainted.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import semmle.code.java.security.CommandLineQuery
1818
import InputToArgumentToExecFlow::PathGraph
1919
private import semmle.code.java.dataflow.ExternalFlow
2020

21+
overlay[local?]
2122
deprecated private class ActivateModels extends ActiveExperimentalModels {
2223
ActivateModels() { this = "jsch-os-injection" }
2324
}

java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ private import semmle.code.java.dataflow.ExternalFlow
77
private import semmle.code.java.dataflow.FlowSteps
88
private import semmle.code.java.frameworks.android.WebView
99

10+
overlay[local?]
1011
private class ActivateModels extends ActiveExperimentalModels {
1112
ActivateModels() { this = "android-web-resource-response" }
1213
}

java/ql/src/experimental/Security/CWE/CWE-400/ThreadResourceAbuse.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import semmle.code.java.arithmetic.Overflow
88
import semmle.code.java.dataflow.FlowSteps
99
import semmle.code.java.controlflow.Guards
1010

11+
overlay[local?]
1112
private class ActivateModels extends ActiveExperimentalModels {
1213
ActivateModels() { this = "thread-resource-abuse" }
1314
}

java/ql/src/experimental/Security/CWE/CWE-625/PermissiveDotRegexQuery.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import semmle.code.java.controlflow.Guards
99
import semmle.code.java.security.UrlRedirect
1010
import Regex
1111

12+
overlay[local?]
1213
private class ActivateModels extends ActiveExperimentalModels {
1314
ActivateModels() { this = "permissive-dot-regex-query" }
1415
}

shared/dataflow/codeql/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ module MakeImplCommon<LocationSig Location, InputSig<Location> Lang> {
291291
* to `lambdaCall`, if any. That is, `lastCall` is able to target the enclosing
292292
* callable of `lambdaCall`.
293293
*/
294+
overlay[global]
294295
pragma[nomagic]
295296
predicate revLambdaFlow(
296297
Call lambdaCall, LambdaCallKind kind, Node node, Type t, boolean toReturn, boolean toJump,

0 commit comments

Comments
 (0)