From d90d6457fbe44399fc3498982cd5a03e9fbc92c4 Mon Sep 17 00:00:00 2001 From: Chalard Jean Date: Wed, 7 Jul 2021 17:13:57 +0900 Subject: [PATCH] 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 (cherry picked from commit b0d13e29515d5b7c82daed7533b78ac57e46bd93) --- core/java/android/app/ActivityThread.java | 28 +++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 3915abe1e9ebf..dbaf2757a9e25 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -369,11 +369,12 @@ public final class ActivityThread extends ClientTransactionHandler @UnsupportedAppUsage(trackingBug = 176961850, maxTargetSdk = Build.VERSION_CODES.R, publicAlternatives = "Use {@code Context#getResources()#getConfiguration()} instead.") Configuration mConfiguration; + @GuardedBy("this") + private boolean mUpdateHttpProxyOnBind = false; @UnsupportedAppUsage Application mInitialApplication; @UnsupportedAppUsage - final ArrayList mAllApplications - = new ArrayList(); + final ArrayList 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 @@ -1187,8 +1188,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() { @@ -6685,6 +6696,15 @@ public final class ActivityThread extends ClientTransactionHandler sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName); 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