Skip to content

Commit d97b130

Browse files
authored
Merge pull request #7092 from atorralba/atorralba/android-asynctask-jumpstep
Java: Add AsyncTask additional value step
2 parents a40a393 + 87ebcea commit d97b130

File tree

7 files changed

+101
-0
lines changed

7 files changed

+101
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ private import semmle.code.java.dataflow.DataFlow
1111
*/
1212
private module Frameworks {
1313
private import semmle.code.java.frameworks.jackson.JacksonSerializability
14+
private import semmle.code.java.frameworks.android.AsyncTask
1415
private import semmle.code.java.frameworks.android.Intent
1516
private import semmle.code.java.frameworks.android.SQLite
1617
private import semmle.code.java.frameworks.Guice
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/** Provides classes and predicates to reason about `AsyncTask`s in Android. */
2+
3+
import java
4+
private import semmle.code.java.dataflow.DataFlow
5+
private import semmle.code.java.dataflow.FlowSteps
6+
7+
/**
8+
* Models the value-preserving step from `asyncTask.execute(params)` to `AsyncTask::doInBackground(params)`.
9+
*/
10+
private class AsyncTaskAdditionalValueStep extends AdditionalValueStep {
11+
override predicate step(DataFlow::Node node1, DataFlow::Node node2) {
12+
exists(ExecuteAsyncTaskMethodAccess ma, AsyncTaskRunInBackgroundMethod m |
13+
DataFlow::getInstanceArgument(ma).getType() = m.getDeclaringType() and
14+
node1.asExpr() = ma.getParamsArgument() and
15+
node2.asParameter() = m.getParameter(0)
16+
)
17+
}
18+
}
19+
20+
/**
21+
* The Android class `android.os.AsyncTask`.
22+
*/
23+
private class AsyncTask extends RefType {
24+
AsyncTask() { this.hasQualifiedName("android.os", "AsyncTask") }
25+
}
26+
27+
/** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */
28+
private class ExecuteAsyncTaskMethodAccess extends MethodAccess {
29+
Argument paramsArgument;
30+
31+
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+
)
40+
}
41+
42+
/** Returns the `params` argument of this call. */
43+
Argument getParamsArgument() { result = paramsArgument }
44+
}
45+
46+
/** The `doInBackground` method of the `android.os.AsyncTask` class. */
47+
private class AsyncTaskRunInBackgroundMethod extends Method {
48+
AsyncTaskRunInBackgroundMethod() {
49+
this.getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask and
50+
this.getName() = "doInBackground"
51+
}
52+
}

java/ql/test/experimental/query-tests/security/CWE-200/SensitiveAndroidFileLeak.expected

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,17 @@ edges
44
| FileService.java:21:28:21:64 | getStringExtra(...) : Object | FileService.java:25:42:25:50 | localPath : Object |
55
| FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] | FileService.java:40:41:40:55 | params : Object[] |
66
| FileService.java:25:13:25:51 | makeParamsToExecute(...) [[]] : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) : Object[] |
7+
| FileService.java:25:13:25:51 | makeParamsToExecute(...) [[]] : Object | FileService.java:40:41:40:55 | params [[]] : Object |
78
| FileService.java:25:42:25:50 | localPath : Object | FileService.java:25:13:25:51 | makeParamsToExecute(...) [[]] : Object |
89
| FileService.java:25:42:25:50 | localPath : Object | FileService.java:32:13:32:28 | sourceUri : Object |
910
| FileService.java:32:13:32:28 | sourceUri : Object | FileService.java:35:17:35:25 | sourceUri : Object |
1011
| FileService.java:34:20:36:13 | {...} [[]] : Object | FileService.java:34:20:36:13 | new Object[] [[]] : Object |
1112
| FileService.java:35:17:35:25 | sourceUri : Object | FileService.java:34:20:36:13 | {...} [[]] : Object |
1213
| FileService.java:40:41:40:55 | params : Object[] | FileService.java:44:33:44:52 | (...)... : Object |
14+
| FileService.java:40:41:40:55 | params [[]] : Object | FileService.java:44:44:44:49 | params [[]] : Object |
1315
| FileService.java:44:33:44:52 | (...)... : Object | FileService.java:45:53:45:59 | ...[...] |
16+
| FileService.java:44:44:44:49 | params [[]] : Object | FileService.java:44:44:44:52 | ...[...] : Object |
17+
| FileService.java:44:44:44:52 | ...[...] : Object | FileService.java:44:33:44:52 | (...)... : Object |
1418
| LeakFileActivity2.java:15:13:15:18 | intent : Intent | LeakFileActivity2.java:16:26:16:31 | intent : Intent |
1519
| LeakFileActivity2.java:16:26:16:31 | intent : Intent | FileService.java:20:31:20:43 | intent : Intent |
1620
| LeakFileActivity.java:14:35:14:38 | data : Intent | LeakFileActivity.java:18:40:18:59 | contentIntent : Intent |
@@ -30,7 +34,10 @@ nodes
3034
| FileService.java:34:20:36:13 | {...} [[]] : Object | semmle.label | {...} [[]] : Object |
3135
| FileService.java:35:17:35:25 | sourceUri : Object | semmle.label | sourceUri : Object |
3236
| FileService.java:40:41:40:55 | params : Object[] | semmle.label | params : Object[] |
37+
| FileService.java:40:41:40:55 | params [[]] : Object | semmle.label | params [[]] : Object |
3338
| FileService.java:44:33:44:52 | (...)... : Object | semmle.label | (...)... : Object |
39+
| FileService.java:44:44:44:49 | params [[]] : Object | semmle.label | params [[]] : Object |
40+
| FileService.java:44:44:44:52 | ...[...] : Object | semmle.label | ...[...] : Object |
3441
| FileService.java:45:53:45:59 | ...[...] | semmle.label | ...[...] |
3542
| LeakFileActivity2.java:15:13:15:18 | intent : Intent | semmle.label | intent : Intent |
3643
| LeakFileActivity2.java:16:26:16:31 | intent : Intent | semmle.label | intent : Intent |
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import android.os.AsyncTask;
2+
3+
public class Test {
4+
5+
private static Object source(String kind) {
6+
return null;
7+
}
8+
9+
private static void sink(Object o) {}
10+
11+
public void test() {
12+
TestAsyncTask t = new TestAsyncTask();
13+
t.execute(source("execute"));
14+
t.executeOnExecutor(null, source("executeOnExecutor"));
15+
SafeAsyncTask t2 = new SafeAsyncTask();
16+
t2.execute("safe");
17+
}
18+
19+
private class TestAsyncTask extends AsyncTask<Object, Object, Object> {
20+
@Override
21+
protected Object doInBackground(Object... params) {
22+
sink(params); // $ hasValueFlow=execute hasValueFlow=executeOnExecutor
23+
return null;
24+
}
25+
}
26+
27+
private class SafeAsyncTask extends AsyncTask<Object, Object, Object> {
28+
@Override
29+
protected Object doInBackground(Object... params) {
30+
sink(params); // Safe
31+
return null;
32+
}
33+
}
34+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
//semmle-extractor-options: --javac-args -cp ${testdir}/../../../../stubs/google-android-9.0.0

java/ql/test/library-tests/frameworks/android/asynctask/test.expected

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import java
2+
import TestUtilities.InlineFlowTest
3+
4+
class AsyncTaskTest extends InlineFlowTest {
5+
override TaintTracking::Configuration getTaintFlowConfig() { none() }
6+
}

0 commit comments

Comments
 (0)