@@ -25,7 +25,20 @@ predicate isPrimitiveTypeUsedForBulkData(J::Type t) {
2525 t .hasName ( [ "byte" , "char" , "Byte" , "Character" ] )
2626}
2727
28- module ModelGeneratorInput implements ModelGeneratorInputSig< Location , JavaDataFlow > {
28+ private predicate isInfrequentlyUsed ( J:: CompilationUnit cu ) {
29+ cu .getPackage ( ) .getName ( ) .matches ( "javax.swing%" ) or
30+ cu .getPackage ( ) .getName ( ) .matches ( "java.awt%" )
31+ }
32+
33+ private predicate relevant ( Callable api ) {
34+ api .isPublic ( ) and
35+ api .getDeclaringType ( ) .isPublic ( ) and
36+ api .fromSource ( ) and
37+ not isUninterestingForModels ( api ) and
38+ not isInfrequentlyUsed ( api .getCompilationUnit ( ) )
39+ }
40+
41+ module ModelGeneratorCommonInput implements ModelGeneratorCommonInputSig< Location , JavaDataFlow > {
2942 class Type = J:: Type ;
3043
3144 class Parameter = J:: Parameter ;
@@ -34,96 +47,8 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
3447
3548 class NodeExtended = DataFlow:: Node ;
3649
37- Callable getAsExprEnclosingCallable ( NodeExtended node ) {
38- result = node .asExpr ( ) .getEnclosingCallable ( )
39- }
40-
4150 Callable getEnclosingCallable ( NodeExtended node ) { result = node .getEnclosingCallable ( ) }
4251
43- Parameter asParameter ( NodeExtended node ) { result = node .asParameter ( ) }
44-
45- private predicate isInfrequentlyUsed ( J:: CompilationUnit cu ) {
46- cu .getPackage ( ) .getName ( ) .matches ( "javax.swing%" ) or
47- cu .getPackage ( ) .getName ( ) .matches ( "java.awt%" )
48- }
49-
50- private predicate relevant ( Callable api ) {
51- api .isPublic ( ) and
52- api .getDeclaringType ( ) .isPublic ( ) and
53- api .fromSource ( ) and
54- not isUninterestingForModels ( api ) and
55- not isInfrequentlyUsed ( api .getCompilationUnit ( ) )
56- }
57-
58- private J:: Method getARelevantOverride ( J:: Method m ) {
59- result = m .getAnOverride ( ) and
60- relevant ( result ) and
61- // Other exclusions for overrides.
62- not m instanceof J:: ToStringMethod
63- }
64-
65- /**
66- * Gets the super implementation of `m` if it is relevant.
67- * If such a super implementations does not exist, returns `m` if it is relevant.
68- */
69- private J:: Callable liftedImpl ( J:: Callable m ) {
70- (
71- result = getARelevantOverride ( m )
72- or
73- result = m and relevant ( m )
74- ) and
75- not exists ( getARelevantOverride ( result ) )
76- }
77-
78- private predicate hasManualSummaryModel ( Callable api ) {
79- api = any ( FlowSummaryImpl:: Public:: SummarizedCallable sc | sc .applyManualModel ( ) ) .asCallable ( ) or
80- api = any ( FlowSummaryImpl:: Public:: NeutralSummaryCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
81- }
82-
83- private predicate hasManualSourceModel ( Callable api ) {
84- api = any ( ExternalFlow:: SourceCallable sc | sc .hasManualModel ( ) ) or
85- api = any ( FlowSummaryImpl:: Public:: NeutralSourceCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
86- }
87-
88- private predicate hasManualSinkModel ( Callable api ) {
89- api = any ( ExternalFlow:: SinkCallable sc | sc .hasManualModel ( ) ) or
90- api = any ( FlowSummaryImpl:: Public:: NeutralSinkCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
91- }
92-
93- predicate isUninterestingForDataFlowModels ( Callable api ) {
94- api .getDeclaringType ( ) instanceof J:: Interface and not exists ( api .getBody ( ) )
95- }
96-
97- predicate isUninterestingForHeuristicDataFlowModels ( Callable api ) { none ( ) }
98-
99- class SourceOrSinkTargetApi extends Callable {
100- SourceOrSinkTargetApi ( ) { relevant ( this ) }
101- }
102-
103- class SinkTargetApi extends SourceOrSinkTargetApi {
104- SinkTargetApi ( ) { not hasManualSinkModel ( this ) }
105- }
106-
107- class SourceTargetApi extends SourceOrSinkTargetApi {
108- SourceTargetApi ( ) { not hasManualSourceModel ( this ) }
109- }
110-
111- class SummaryTargetApi extends Callable {
112- private Callable lift ;
113-
114- SummaryTargetApi ( ) {
115- lift = liftedImpl ( this ) and
116- not hasManualSummaryModel ( lift )
117- }
118-
119- Callable lift ( ) { result = lift }
120-
121- predicate isRelevant ( ) {
122- relevant ( this ) and
123- not hasManualSummaryModel ( this )
124- }
125- }
126-
12752 private string isExtensible ( Callable c ) {
12853 if c .getDeclaringType ( ) .isFinal ( ) then result = "false" else result = "true"
12954 }
@@ -204,49 +129,89 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
204129 node .asExpr ( ) .( J:: ThisAccess ) .isOwnInstanceAccess ( )
205130 }
206131
207- predicate sinkModelSanitizer ( DataFlow:: Node node ) {
208- // exclude variable capture jump steps
209- exists ( Ssa:: SsaImplicitInit closure |
210- closure .captures ( _) and
211- node .asExpr ( ) = closure .getAFirstUse ( )
212- )
132+ predicate containerContent = DataFlowPrivate:: containerContent / 1 ;
133+
134+ string partialModelRow ( Callable api , int i ) {
135+ i = 0 and qualifiedName ( api , result , _) // package
136+ or
137+ i = 1 and qualifiedName ( api , _, result ) // type
138+ or
139+ i = 2 and result = isExtensible ( api ) // extensible
140+ or
141+ i = 3 and result = api .getName ( ) // name
142+ or
143+ i = 4 and result = ExternalFlow:: paramsString ( api ) // parameters
144+ or
145+ i = 5 and result = "" and exists ( api ) // ext
213146 }
214147
215- predicate apiSource ( DataFlow:: Node source ) {
148+ string partialNeutralModelRow ( Callable api , int i ) {
149+ i = 0 and qualifiedName ( api , result , _) // package
150+ or
151+ i = 1 and qualifiedName ( api , _, result ) // type
152+ or
153+ i = 2 and result = api .getName ( ) // name
154+ or
155+ i = 3 and result = ExternalFlow:: paramsString ( api ) // parameters
156+ }
157+ }
158+
159+ private import ModelGeneratorCommonInput
160+ private import MakeModelGeneratorFactory< Location , JavaDataFlow , JavaTaintTracking , ModelGeneratorCommonInput >
161+
162+ module SummaryModelGeneratorInput implements SummaryModelGeneratorInputSig {
163+ Callable getAsExprEnclosingCallable ( NodeExtended node ) {
164+ result = node .asExpr ( ) .getEnclosingCallable ( )
165+ }
166+
167+ Parameter asParameter ( NodeExtended node ) { result = node .asParameter ( ) }
168+
169+ private J:: Method getARelevantOverride ( J:: Method m ) {
170+ result = m .getAnOverride ( ) and
171+ relevant ( result ) and
172+ // Other exclusions for overrides.
173+ not m instanceof J:: ToStringMethod
174+ }
175+
176+ /**
177+ * Gets the super implementation of `m` if it is relevant.
178+ * If such a super implementations does not exist, returns `m` if it is relevant.
179+ */
180+ private J:: Callable liftedImpl ( J:: Callable m ) {
216181 (
217- source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
218- source instanceof DataFlow:: ParameterNode
182+ result = getARelevantOverride ( m )
183+ or
184+ result = m and relevant ( m )
219185 ) and
220- exists ( J:: RefType t |
221- t = source .getEnclosingCallable ( ) .getDeclaringType ( ) .getAnAncestor ( ) and
222- not t instanceof J:: TypeObject and
223- t .isPublic ( )
224- )
186+ not exists ( getARelevantOverride ( result ) )
225187 }
226188
227- predicate irrelevantSourceSinkApi ( Callable source , SourceTargetApi api ) { none ( ) }
228-
229- string getInputArgument ( DataFlow:: Node source ) {
230- exists ( int pos |
231- source .( DataFlow:: ParameterNode ) .isParameterOf ( _, pos ) and
232- if pos >= 0 then result = "Argument[" + pos + "]" else result = qualifierString ( )
233- )
234- or
235- source .asExpr ( ) instanceof J:: FieldAccess and
236- result = qualifierString ( )
189+ private predicate hasManualSummaryModel ( Callable api ) {
190+ api = any ( FlowSummaryImpl:: Public:: SummarizedCallable sc | sc .applyManualModel ( ) ) .asCallable ( ) or
191+ api = any ( FlowSummaryImpl:: Public:: NeutralSummaryCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
237192 }
238193
239- bindingset [ kind]
240- predicate isRelevantSinkKind ( string kind ) {
241- not kind = "log-injection" and
242- not kind .matches ( "regex-use%" ) and
243- not kind = "file-content-store"
194+ class SummaryTargetApi extends Callable {
195+ private Callable lift ;
196+
197+ SummaryTargetApi ( ) {
198+ lift = liftedImpl ( this ) and
199+ not hasManualSummaryModel ( lift )
200+ }
201+
202+ Callable lift ( ) { result = lift }
203+
204+ predicate isRelevant ( ) {
205+ relevant ( this ) and
206+ not hasManualSummaryModel ( this )
207+ }
244208 }
245209
246- bindingset [ kind]
247- predicate isRelevantSourceKind ( string kind ) { any ( ) }
210+ predicate isUninterestingForDataFlowModels ( Callable api ) {
211+ api .getDeclaringType ( ) instanceof J:: Interface and not exists ( api .getBody ( ) )
212+ }
248213
249- predicate containerContent = DataFlowPrivate :: containerContent / 1 ;
214+ predicate isUninterestingForHeuristicDataFlowModels ( Callable api ) { none ( ) }
250215
251216 predicate isAdditionalContentFlowStep ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
252217 TaintTracking:: defaultAdditionalTaintStep ( node1 , node2 , _) and
@@ -287,34 +252,76 @@ module ModelGeneratorInput implements ModelGeneratorInputSig<Location, JavaDataF
287252 or
288253 c instanceof DataFlowUtil:: MapKeyContent and result = "MapKey"
289254 }
255+ }
290256
291- string partialModelRow ( Callable api , int i ) {
292- i = 0 and qualifiedName ( api , result , _) // package
293- or
294- i = 1 and qualifiedName ( api , _, result ) // type
295- or
296- i = 2 and result = isExtensible ( api ) // extensible
297- or
298- i = 3 and result = api .getName ( ) // name
299- or
300- i = 4 and result = ExternalFlow:: paramsString ( api ) // parameters
301- or
302- i = 5 and result = "" and exists ( api ) // ext
257+ private module SourceModelGeneratorInput implements SourceModelGeneratorInputSig {
258+ private predicate hasManualSourceModel ( Callable api ) {
259+ api = any ( ExternalFlow:: SourceCallable sc | sc .hasManualModel ( ) ) or
260+ api = any ( FlowSummaryImpl:: Public:: NeutralSourceCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
303261 }
304262
305- string partialNeutralModelRow ( Callable api , int i ) {
306- i = 0 and qualifiedName ( api , result , _) // package
307- or
308- i = 1 and qualifiedName ( api , _, result ) // type
309- or
310- i = 2 and result = api .getName ( ) // name
311- or
312- i = 3 and result = ExternalFlow:: paramsString ( api ) // parameters
263+ class SourceTargetApi extends Callable {
264+ SourceTargetApi ( ) { relevant ( this ) and not hasManualSourceModel ( this ) }
313265 }
314266
267+ predicate irrelevantSourceSinkApi ( Callable source , SourceTargetApi api ) { none ( ) }
268+
269+ bindingset [ kind]
270+ predicate isRelevantSourceKind ( string kind ) { any ( ) }
271+
315272 predicate sourceNode = ExternalFlow:: sourceNode / 2 ;
273+ }
274+
275+ private module SinkModelGeneratorInput implements SinkModelGeneratorInputSig {
276+ private predicate hasManualSinkModel ( Callable api ) {
277+ api = any ( ExternalFlow:: SinkCallable sc | sc .hasManualModel ( ) ) or
278+ api = any ( FlowSummaryImpl:: Public:: NeutralSinkCallable sc | sc .hasManualModel ( ) ) .asCallable ( )
279+ }
280+
281+ class SinkTargetApi extends Callable {
282+ SinkTargetApi ( ) { relevant ( this ) and not hasManualSinkModel ( this ) }
283+ }
284+
285+ predicate sinkModelSanitizer ( DataFlow:: Node node ) {
286+ // exclude variable capture jump steps
287+ exists ( Ssa:: SsaImplicitInit closure |
288+ closure .captures ( _) and
289+ node .asExpr ( ) = closure .getAFirstUse ( )
290+ )
291+ }
292+
293+ predicate apiSource ( DataFlow:: Node source ) {
294+ (
295+ source .asExpr ( ) .( J:: FieldAccess ) .isOwnFieldAccess ( ) or
296+ source instanceof DataFlow:: ParameterNode
297+ ) and
298+ exists ( J:: RefType t |
299+ t = source .getEnclosingCallable ( ) .getDeclaringType ( ) .getAnAncestor ( ) and
300+ not t instanceof J:: TypeObject and
301+ t .isPublic ( )
302+ )
303+ }
304+
305+ string getInputArgument ( DataFlow:: Node source ) {
306+ exists ( int pos |
307+ source .( DataFlow:: ParameterNode ) .isParameterOf ( _, pos ) and
308+ if pos >= 0 then result = "Argument[" + pos + "]" else result = qualifierString ( )
309+ )
310+ or
311+ source .asExpr ( ) instanceof J:: FieldAccess and
312+ result = qualifierString ( )
313+ }
314+
315+ bindingset [ kind]
316+ predicate isRelevantSinkKind ( string kind ) {
317+ not kind = "log-injection" and
318+ not kind .matches ( "regex-use%" ) and
319+ not kind = "file-content-store"
320+ }
316321
317322 predicate sinkNode = ExternalFlow:: sinkNode / 2 ;
318323}
319324
320- import MakeModelGenerator< Location , JavaDataFlow , JavaTaintTracking , ModelGeneratorInput >
325+ import MakeSummaryModelGenerator< SummaryModelGeneratorInput > as SummaryModels
326+ import MakeSourceModelGenerator< SourceModelGeneratorInput > as SourceModels
327+ import MakeSinkModelGenerator< SinkModelGeneratorInput > as SinkModels
0 commit comments