summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorChalard Jean <jchalard@google.com>2021-07-07 17:13:57 +0900
committerChalard Jean <jchalard@google.com>2021-07-29 13:18:54 +0900
commit249be21013e389837f5b2beb7d36890b25ecfaaf (patch)
tree24e60e1da38b860d8baaad8efc12c2e15eae3e69 /core/java/android
parent9f6b05e6fbf31ec26296f7e506ef0a38ec289038 (diff)
Fix: ConnectivityManager methods crashing with SecurityException
Starting in R, some methods in ConnectivityManager like getNetworkCapabilities started passing the package name from the context stored in CM to check that the package is really whom it pretends to be. Unfortunately, in some cases, the context contains package "android" for an app, and since the app is not the system, the check fails and crashes the app. It seems the culprit is updateHttpProxy, which is called by ProcessList when the PROXY_CHANGE_ACTION broadcast is sent. If this happens to run between the time the process is created and the activity thread is "bound", then the mInitialApplication member is not set, and updateHttpProxy uses a system context. Since ConnectivityManager caches the context forever in a static, this leads to subsequent legitimate calls crashing. Setting the proxy can be deffered until such a time that the app is bound, as it can't run any code before then. The member is never reset to null, so it's guaranteed to be non-null at bind time. An alternative would be to post a runnable on the handler thread if the member is null to try again later. This could however run the lambda a considerable number of times as binding can be delayed, and risks causing an infinite loop if some invariants are changed in the future. See also b/73572062 and ag/4056059 Bug: 155549446 Bug: 189360509 Test: ActivityThreadTest FrameworksNetTests NetworkStackTests Test: Manually set a proxy, observe the broadcast being sent and apps not crashing Change-Id: I956f76be2e0a1a675576511fb394d7ed4354b28a Merged-In: I956f76be2e0a1a675576511fb394d7ed4354b28a
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/ActivityThread.java28
1 files changed, 24 insertions, 4 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 193f7754f974..41170a4c2749 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -352,11 +352,12 @@ public final class ActivityThread extends ClientTransactionHandler {
@UnsupportedAppUsage
Configuration mConfiguration;
Configuration mCompatConfiguration;
+ @GuardedBy("this")
+ private boolean mUpdateHttpProxyOnBind = false;
@UnsupportedAppUsage
Application mInitialApplication;
@UnsupportedAppUsage
- final ArrayList<Application> mAllApplications
- = new ArrayList<Application>();
+ final ArrayList<Application> mAllApplications = new ArrayList<>();
/**
* Bookkeeping of instantiated backup agents indexed first by user id, then by package name.
* Indexing by user id supports parallel backups across users on system packages as they run in
@@ -1127,8 +1128,18 @@ public final class ActivityThread extends ClientTransactionHandler {
}
public void updateHttpProxy() {
- ActivityThread.updateHttpProxy(
- getApplication() != null ? getApplication() : getSystemContext());
+ final Application app;
+ synchronized (ActivityThread.this) {
+ app = getApplication();
+ if (null == app) {
+ // The app is not bound yet. Make a note to update the HTTP proxy when the
+ // app is bound.
+ mUpdateHttpProxyOnBind = true;
+ return;
+ }
+ }
+ // App is present, update the proxy inline.
+ ActivityThread.updateHttpProxy(app);
}
public void processInBackground() {
@@ -6697,6 +6708,15 @@ public final class ActivityThread extends ClientTransactionHandler {
app.setContentCaptureOptions(data.contentCaptureOptions);
mInitialApplication = app;
+ final boolean updateHttpProxy;
+ synchronized (this) {
+ updateHttpProxy = mUpdateHttpProxyOnBind;
+ // This synchronized block ensures that any subsequent call to updateHttpProxy()
+ // will see a non-null mInitialApplication.
+ }
+ if (updateHttpProxy) {
+ ActivityThread.updateHttpProxy(app);
+ }
// don't bring up providers in restricted mode; they may depend on the
// app's custom Application class