From 8acc99a974a8c0a8f3e3ca3be06356b0f5e6f702 Mon Sep 17 00:00:00 2001 From: Remi NGUYEN VAN Date: Fri, 8 Mar 2019 17:20:49 +0900 Subject: [PATCH] Use an in-process APK for in-process NetworkStack Instead of having a library in the classpath where the NetworkStack is created by reflection on devices using the network stack in-process, just bind to a version of the network stack service that runs in the system process. If the in-process version is installed it will be used, otherwise the module is used with its own process. Bug: 127908503 Test: blueline boots and has functional WiFi Test: atest FrameworksNetTests NetworkStackTests Test: svelte build boots and has functional WiFi Change-Id: I7722b173e5686e0dbb9cfddcfb34344b0f4135d9 --- packages/NetworkStack/Android.bp | 33 ++++++-- packages/NetworkStack/AndroidManifest.xml | 24 +----- packages/NetworkStack/AndroidManifestBase.xml | 39 ++++++++++ .../NetworkStack/AndroidManifest_InProcess.xml | 30 ++++++++ packages/NetworkStack/tests/Android.bp | 2 +- .../net/java/android/net/NetworkStackClient.java | 88 ++++++++++++---------- 6 files changed, 148 insertions(+), 68 deletions(-) create mode 100644 packages/NetworkStack/AndroidManifestBase.xml create mode 100644 packages/NetworkStack/AndroidManifest_InProcess.xml diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp index f210840b976f..190247aecb2e 100644 --- a/packages/NetworkStack/Android.bp +++ b/packages/NetworkStack/Android.bp @@ -14,12 +14,11 @@ // limitations under the License. // -// Library including the network stack, used to compile the network stack app, or linked into the -// system server on devices that run the stack there -java_library { - name: "NetworkStackLib", +// Library including the network stack, used to compile both variants of the network stack +android_library { + name: "NetworkStackBase", sdk_version: "system_current", - installable: true, + min_sdk_version: "28", srcs: [ "src/**/*.java", ":framework-networkstack-shared-srcs", @@ -29,7 +28,24 @@ java_library { "netd_aidl_interface-java", "networkstack-aidl-interfaces-java", "datastallprotosnano", - ] + ], + manifest: "AndroidManifestBase.xml", +} + +// Non-updatable in-process network stack for devices not using the module +android_app { + name: "InProcessNetworkStack", + sdk_version: "system_current", + min_sdk_version: "28", + certificate: "platform", + privileged: true, + static_libs: [ + "NetworkStackBase", + ], + jarjar_rules: "jarjar-rules-shared.txt", + // The permission configuration *must* be included to ensure security of the device + required: ["NetworkStackPermissionStub"], + manifest: "AndroidManifest_InProcess.xml", } // Updatable network stack packaged as an application @@ -40,9 +56,10 @@ android_app { certificate: "networkstack", privileged: true, static_libs: [ - "NetworkStackLib" + "NetworkStackBase" ], jarjar_rules: "jarjar-rules-shared.txt", - manifest: "AndroidManifest.xml", + // The permission configuration *must* be included to ensure security of the device required: ["NetworkStackPermissionStub"], + manifest: "AndroidManifest.xml", } diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml index 003f1e59d743..a90db11df016 100644 --- a/packages/NetworkStack/AndroidManifest.xml +++ b/packages/NetworkStack/AndroidManifest.xml @@ -1,7 +1,7 @@ - - - - - - + android:sharedUserId="android.uid.networkstack"> - - - - - + - + \ No newline at end of file diff --git a/packages/NetworkStack/AndroidManifestBase.xml b/packages/NetworkStack/AndroidManifestBase.xml new file mode 100644 index 000000000000..621d30c31f98 --- /dev/null +++ b/packages/NetworkStack/AndroidManifestBase.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + diff --git a/packages/NetworkStack/AndroidManifest_InProcess.xml b/packages/NetworkStack/AndroidManifest_InProcess.xml new file mode 100644 index 000000000000..48fcecd2f06d --- /dev/null +++ b/packages/NetworkStack/AndroidManifest_InProcess.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/packages/NetworkStack/tests/Android.bp b/packages/NetworkStack/tests/Android.bp index f22b6472847c..690c2cf6eeb3 100644 --- a/packages/NetworkStack/tests/Android.bp +++ b/packages/NetworkStack/tests/Android.bp @@ -24,7 +24,7 @@ android_test { "androidx.test.rules", "frameworks-base-testutils", "mockito-target-extended-minus-junit4", - "NetworkStackLib", + "NetworkStackBase", "testables", ], libs: [ diff --git a/services/net/java/android/net/NetworkStackClient.java b/services/net/java/android/net/NetworkStackClient.java index 830dbbe8b8c0..6bfc39109c08 100644 --- a/services/net/java/android/net/NetworkStackClient.java +++ b/services/net/java/android/net/NetworkStackClient.java @@ -42,7 +42,6 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; -import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; /** @@ -53,6 +52,7 @@ public class NetworkStackClient { private static final String TAG = NetworkStackClient.class.getSimpleName(); private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; + private static final String IN_PROCESS_SUFFIX = ".InProcess"; private static NetworkStackClient sInstance; @@ -175,42 +175,50 @@ public class NetworkStackClient { public void start(Context context) { log("Starting network stack"); mNetworkStackStartRequested = true; - // Try to bind in-process if the library is available - IBinder connector = null; - try { - final Class service = Class.forName( - "com.android.server.NetworkStackService", - true /* initialize */, - context.getClassLoader()); - connector = (IBinder) service.getMethod("makeConnector", Context.class) - .invoke(null, context); - } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { - logWtf("Could not create network stack connector from NetworkStackService", e); - // TODO: crash/reboot system here ? - return; - } catch (ClassNotFoundException e) { - // Normal behavior if stack is provided by the app: fall through + + final PackageManager pm = context.getPackageManager(); + + // Try to bind in-process if the device was shipped with an in-process version + Intent intent = getNetworkStackIntent(pm, true /* inSystemProcess */); + + // Otherwise use the updatable module version + if (intent == null) { + intent = getNetworkStackIntent(pm, false /* inSystemProcess */); + log("Starting network stack process"); + } else { + log("Starting network stack in-process"); } - // In-process network stack. Add the service to the service manager here. - if (connector != null) { - log("Registering in-process network stack connector"); - registerNetworkStackService(connector); + if (intent == null) { + logWtf("Could not resolve the network stack", null); + // TODO: crash/reboot system server ? return; } - // Start the network stack process. The service will be added to the service manager in + + // Start the network stack. The service will be added to the service manager in // NetworkStackConnection.onServiceConnected(). - log("Starting network stack process"); - final Intent intent = new Intent(INetworkStackConnector.class.getName()); - final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0); - intent.setComponent(comp); + if (!context.bindServiceAsUser(intent, new NetworkStackConnection(), + Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { + logWtf("Could not bind to network stack with " + intent, null); + return; + // TODO: crash/reboot system server if no network stack after a timeout ? + } + + log("Network stack service start requested"); + } + + @Nullable + private Intent getNetworkStackIntent(@NonNull PackageManager pm, boolean inSystemProcess) { + final String baseAction = INetworkStackConnector.class.getName(); + final Intent intent = + new Intent(inSystemProcess ? baseAction + IN_PROCESS_SUFFIX : baseAction); + final ComponentName comp = intent.resolveSystemService(pm, 0); if (comp == null) { - logWtf("Could not resolve the network stack with " + intent, null); - // TODO: crash/reboot system server ? - return; + return null; } - final PackageManager pm = context.getPackageManager(); + intent.setComponent(comp); + int uid = -1; try { uid = pm.getPackageUidAsUser(comp.getPackageName(), UserHandle.USER_SYSTEM); @@ -218,25 +226,27 @@ public class NetworkStackClient { logWtf("Network stack package not found", e); // Fall through } - if (uid != Process.NETWORK_STACK_UID) { + + final int expectedUid = inSystemProcess ? Process.SYSTEM_UID : Process.NETWORK_STACK_UID; + if (uid != expectedUid) { throw new SecurityException("Invalid network stack UID: " + uid); } + if (!inSystemProcess) { + checkNetworkStackPermission(pm, comp); + } + + return intent; + } + + private void checkNetworkStackPermission( + @NonNull PackageManager pm, @NonNull ComponentName comp) { final int hasPermission = pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName()); if (hasPermission != PERMISSION_GRANTED) { throw new SecurityException( "Network stack does not have permission " + PERMISSION_MAINLINE_NETWORK_STACK); } - - if (!context.bindServiceAsUser(intent, new NetworkStackConnection(), - Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) { - logWtf("Could not bind to network stack in-process, or in app with " + intent, null); - return; - // TODO: crash/reboot system server if no network stack after a timeout ? - } - - log("Network stack service start requested"); } private void log(@NonNull String message) { -- 2.11.0