@@ -4,49 +4,101 @@ import java
44private import semmle.code.java.dataflow.DataFlow
55private import semmle.code.java.dataflow.FlowSteps
66
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+
712/**
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`.
915 */
10- private class AsyncTaskAdditionalValueStep extends AdditionalValueStep {
16+ private class AsyncTaskExecuteAdditionalValueStep extends AdditionalTaintStep {
1117 override predicate step ( DataFlow:: Node node1 , DataFlow:: Node node2 ) {
1218 exists ( ExecuteAsyncTaskMethodAccess ma , AsyncTaskRunInBackgroundMethod m |
13- DataFlow:: getInstanceArgument ( ma ) .getType ( ) = m .getDeclaringType ( ) and
19+ DataFlow:: getInstanceArgument ( ma ) .getType ( ) = m .getDeclaringType ( )
20+ |
1421 node1 .asExpr ( ) = ma .getParamsArgument ( ) and
1522 node2 .asParameter ( ) = m .getParameter ( 0 )
1623 )
1724 }
1825}
1926
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+
2063/**
2164 * The Android class `android.os.AsyncTask`.
2265 */
2366private class AsyncTask extends RefType {
2467 AsyncTask ( ) { this .hasQualifiedName ( "android.os" , "AsyncTask" ) }
2568}
2669
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+
2778/** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */
2879private class ExecuteAsyncTaskMethodAccess extends MethodAccess {
29- Argument paramsArgument ;
30-
3180 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
4084 }
4185
4286 /** Returns the `params` argument of this call. */
43- Argument getParamsArgument ( ) { result = paramsArgument }
87+ Argument getParamsArgument ( ) { result = this . getAnArgument ( ) and result . isVararg ( ) }
4488}
4589
4690/** The `doInBackground` method of the `android.os.AsyncTask` class. */
4791private class AsyncTaskRunInBackgroundMethod extends Method {
4892 AsyncTaskRunInBackgroundMethod ( ) {
4993 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" )
51103 }
52104}
0 commit comments