@@ -4,49 +4,101 @@ import java
4
4
private import semmle.code.java.dataflow.DataFlow
5
5
private import semmle.code.java.dataflow.FlowSteps
6
6
7
+ /*
8
+ * The following flow steps aim to model the life-cycle of `AsyncTask`s described here:
9
+ * https://developer.android.com/reference/android/os/AsyncTask#the-4-steps
10
+ */
11
+
7
12
/**
8
- * Models the value-preserving step from `asyncTask.execute(params)` to `AsyncTask::doInBackground(params)`.
13
+ * A taint step from the vararg arguments of `AsyncTask::execute` and `AsyncTask::executeOnExecutor`
14
+ * to the parameter of `AsyncTask::doInBackground`.
9
15
*/
10
- private class AsyncTaskAdditionalValueStep extends AdditionalValueStep {
16
+ private class AsyncTaskExecuteAdditionalValueStep extends AdditionalTaintStep {
11
17
override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
12
18
exists ( ExecuteAsyncTaskMethodAccess ma , AsyncTaskRunInBackgroundMethod m |
13
- DataFlow:: getInstanceArgument ( ma ) .getType ( ) = m .getDeclaringType ( ) and
19
+ DataFlow:: getInstanceArgument ( ma ) .getType ( ) = m .getDeclaringType ( )
20
+ |
14
21
node1 .asExpr ( ) = ma .getParamsArgument ( ) and
15
22
node2 .asParameter ( ) = m .getParameter ( 0 )
16
23
)
17
24
}
18
25
}
19
26
27
+ /**
28
+ * A value-preserving step from the return value of `AsyncTask::doInBackground`
29
+ * to the parameter of `AsyncTask::onPostExecute`.
30
+ */
31
+ private class AsyncTaskOnPostExecuteAdditionalValueStep extends AdditionalValueStep {
32
+ override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
33
+ exists (
34
+ AsyncTaskRunInBackgroundMethod runInBackground , AsyncTaskOnPostExecuteMethod onPostExecute
35
+ |
36
+ onPostExecute .getDeclaringType ( ) = runInBackground .getDeclaringType ( )
37
+ |
38
+ node1 .asExpr ( ) = any ( ReturnStmt r | r .getEnclosingCallable ( ) = runInBackground ) .getResult ( ) and
39
+ node2 .asParameter ( ) = onPostExecute .getParameter ( 0 )
40
+ )
41
+ }
42
+ }
43
+
44
+ /**
45
+ * A value-preserving step from field initializers in `AsyncTask`'s constructor or initializer method
46
+ * to the instance parameter of `AsyncTask::runInBackground` and `AsyncTask::onPostExecute`.
47
+ */
48
+ private class AsyncTaskFieldInitQualifierToInstanceParameterStep extends AdditionalValueStep {
49
+ override predicate step ( DataFlow:: Node n1 , DataFlow:: Node n2 ) {
50
+ exists ( AsyncTaskInit init , Callable receiver |
51
+ n1 .( DataFlow:: PostUpdateNode ) .getPreUpdateNode ( ) =
52
+ DataFlow:: getFieldQualifier ( any ( FieldWrite f | f .getEnclosingCallable ( ) = init ) ) and
53
+ n2 .( DataFlow:: InstanceParameterNode ) .getCallable ( ) = receiver and
54
+ receiver .getDeclaringType ( ) = init .getDeclaringType ( ) and
55
+ (
56
+ receiver instanceof AsyncTaskRunInBackgroundMethod or
57
+ receiver instanceof AsyncTaskOnPostExecuteMethod
58
+ )
59
+ )
60
+ }
61
+ }
62
+
20
63
/**
21
64
* The Android class `android.os.AsyncTask`.
22
65
*/
23
66
private class AsyncTask extends RefType {
24
67
AsyncTask ( ) { this .hasQualifiedName ( "android.os" , "AsyncTask" ) }
25
68
}
26
69
70
+ /** The constructor or initializer method of the `android.os.AsyncTask` class. */
71
+ private class AsyncTaskInit extends Callable {
72
+ AsyncTaskInit ( ) {
73
+ this .getDeclaringType ( ) .getSourceDeclaration ( ) .getASourceSupertype * ( ) instanceof AsyncTask and
74
+ ( this instanceof Constructor or this instanceof InitializerMethod )
75
+ }
76
+ }
77
+
27
78
/** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */
28
79
private class ExecuteAsyncTaskMethodAccess extends MethodAccess {
29
- Argument paramsArgument ;
30
-
31
80
ExecuteAsyncTaskMethodAccess ( ) {
32
- exists ( Method m |
33
- this .getMethod ( ) = m and
34
- m .getDeclaringType ( ) .getSourceDeclaration ( ) .getASourceSupertype * ( ) instanceof AsyncTask
35
- |
36
- m .getName ( ) = "execute" and not m .isStatic ( ) and paramsArgument = this .getArgument ( 0 )
37
- or
38
- m .getName ( ) = "executeOnExecutor" and paramsArgument = this .getArgument ( 1 )
39
- )
81
+ this .getMethod ( ) .hasName ( [ "execute" , "executeOnExecutor" ] ) and
82
+ this .getMethod ( ) .getDeclaringType ( ) .getSourceDeclaration ( ) .getASourceSupertype * ( ) instanceof
83
+ AsyncTask
40
84
}
41
85
42
86
/** Returns the `params` argument of this call. */
43
- Argument getParamsArgument ( ) { result = paramsArgument }
87
+ Argument getParamsArgument ( ) { result = this . getAnArgument ( ) and result . isVararg ( ) }
44
88
}
45
89
46
90
/** The `doInBackground` method of the `android.os.AsyncTask` class. */
47
91
private class AsyncTaskRunInBackgroundMethod extends Method {
48
92
AsyncTaskRunInBackgroundMethod ( ) {
49
93
this .getDeclaringType ( ) .getSourceDeclaration ( ) .getASourceSupertype * ( ) instanceof AsyncTask and
50
- this .getName ( ) = "doInBackground"
94
+ this .hasName ( "doInBackground" )
95
+ }
96
+ }
97
+
98
+ /** The `onPostExecute` method of the `android.os.AsyncTask` class. */
99
+ private class AsyncTaskOnPostExecuteMethod extends Method {
100
+ AsyncTaskOnPostExecuteMethod ( ) {
101
+ this .getDeclaringType ( ) .getSourceDeclaration ( ) .getASourceSupertype * ( ) instanceof AsyncTask and
102
+ this .hasName ( "onPostExecute" )
51
103
}
52
104
}
0 commit comments