Merge "Use an in-process APK for in-process NetworkStack"

This commit is contained in:
Remi NGUYEN VAN
2019-03-12 01:37:26 +00:00
committed by Gerrit Code Review
6 changed files with 151 additions and 71 deletions

View File

@@ -14,12 +14,11 @@
// limitations under the License. // limitations under the License.
// //
// Library including the network stack, used to compile the network stack app, or linked into the // Library including the network stack, used to compile both variants of the network stack
// system server on devices that run the stack there android_library {
java_library { name: "NetworkStackBase",
name: "NetworkStackLib",
sdk_version: "system_current", sdk_version: "system_current",
installable: true, min_sdk_version: "28",
srcs: [ srcs: [
"src/**/*.java", "src/**/*.java",
":framework-networkstack-shared-srcs", ":framework-networkstack-shared-srcs",
@@ -29,7 +28,24 @@ java_library {
"netd_aidl_interface-java", "netd_aidl_interface-java",
"networkstack-aidl-interfaces-java", "networkstack-aidl-interfaces-java",
"datastallprotosnano", "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 // Updatable network stack packaged as an application
@@ -40,9 +56,10 @@ android_app {
certificate: "networkstack", certificate: "networkstack",
privileged: true, privileged: true,
static_libs: [ static_libs: [
"NetworkStackLib" "NetworkStackBase"
], ],
jarjar_rules: "jarjar-rules-shared.txt", jarjar_rules: "jarjar-rules-shared.txt",
manifest: "AndroidManifest.xml", // The permission configuration *must* be included to ensure security of the device
required: ["NetworkStackPermissionStub"], required: ["NetworkStackPermissionStub"],
manifest: "AndroidManifest.xml",
} }

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <!--
/* /*
* Copyright (C) 2014 The Android Open Source Project * Copyright (C) 2019 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -18,30 +18,14 @@
--> -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack" package="com.android.networkstack"
android:sharedUserId="android.uid.networkstack" android:sharedUserId="android.uid.networkstack">
android:versionCode="11"
android:versionName="Q-initial">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<!-- Signature permission defined in NetworkStackStub --> <!-- Signature permission defined in NetworkStackStub -->
<uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" /> <uses-permission android:name="android.permission.MAINLINE_NETWORK_STACK" />
<!-- Send latency broadcast as current user --> <application>
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<application
android:label="NetworkStack"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:usesCleartextTraffic="true">
<service android:name="com.android.server.NetworkStackService"> <service android:name="com.android.server.NetworkStackService">
<intent-filter> <intent-filter>
<action android:name="android.net.INetworkStackConnector"/> <action android:name="android.net.INetworkStackConnector"/>
</intent-filter> </intent-filter>
</service> </service>
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack"
android:versionCode="11"
android:versionName="Q-initial">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
<!-- Send latency broadcast as current user -->
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<application
android:label="NetworkStack"
android:defaultToDeviceProtectedStorage="true"
android:directBootAware="true"
android:usesCleartextTraffic="true">
</application>
</manifest>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack.inprocess"
android:sharedUserId="android.uid.system"
android:process="system">
<application>
<service android:name="com.android.server.NetworkStackService" android:process="system">
<intent-filter>
<action android:name="android.net.INetworkStackConnector.InProcess"/>
</intent-filter>
</service>
</application>
</manifest>

View File

@@ -23,7 +23,7 @@ android_test {
static_libs: [ static_libs: [
"androidx.test.rules", "androidx.test.rules",
"mockito-target-extended-minus-junit4", "mockito-target-extended-minus-junit4",
"NetworkStackLib", "NetworkStackBase",
"testables", "testables",
], ],
libs: [ libs: [

View File

@@ -42,7 +42,6 @@ import android.util.Slog;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList; import java.util.ArrayList;
/** /**
@@ -53,6 +52,7 @@ public class NetworkStackClient {
private static final String TAG = NetworkStackClient.class.getSimpleName(); private static final String TAG = NetworkStackClient.class.getSimpleName();
private static final int NETWORKSTACK_TIMEOUT_MS = 10_000; private static final int NETWORKSTACK_TIMEOUT_MS = 10_000;
private static final String IN_PROCESS_SUFFIX = ".InProcess";
private static NetworkStackClient sInstance; private static NetworkStackClient sInstance;
@@ -175,42 +175,50 @@ public class NetworkStackClient {
public void start(Context context) { public void start(Context context) {
log("Starting network stack"); log("Starting network stack");
mNetworkStackStartRequested = true; mNetworkStackStartRequested = true;
// Try to bind in-process if the library is available
IBinder connector = null; final PackageManager pm = context.getPackageManager();
try {
final Class service = Class.forName( // Try to bind in-process if the device was shipped with an in-process version
"com.android.server.NetworkStackService", Intent intent = getNetworkStackIntent(pm, true /* inSystemProcess */);
true /* initialize */,
context.getClassLoader()); // Otherwise use the updatable module version
connector = (IBinder) service.getMethod("makeConnector", Context.class) if (intent == null) {
.invoke(null, context); intent = getNetworkStackIntent(pm, false /* inSystemProcess */);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { log("Starting network stack process");
logWtf("Could not create network stack connector from NetworkStackService", e); } else {
// TODO: crash/reboot system here ? log("Starting network stack in-process");
return;
} catch (ClassNotFoundException e) {
// Normal behavior if stack is provided by the app: fall through
} }
// In-process network stack. Add the service to the service manager here. if (intent == null) {
if (connector != null) { logWtf("Could not resolve the network stack", null);
log("Registering in-process network stack connector");
registerNetworkStackService(connector);
return;
}
// Start the network stack process. 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 (comp == null) {
logWtf("Could not resolve the network stack with " + intent, null);
// TODO: crash/reboot system server ? // TODO: crash/reboot system server ?
return; return;
} }
final PackageManager pm = context.getPackageManager();
// Start the network stack. The service will be added to the service manager in
// NetworkStackConnection.onServiceConnected().
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) {
return null;
}
intent.setComponent(comp);
int uid = -1; int uid = -1;
try { try {
uid = pm.getPackageUidAsUser(comp.getPackageName(), UserHandle.USER_SYSTEM); uid = pm.getPackageUidAsUser(comp.getPackageName(), UserHandle.USER_SYSTEM);
@@ -218,25 +226,27 @@ public class NetworkStackClient {
logWtf("Network stack package not found", e); logWtf("Network stack package not found", e);
// Fall through // 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); 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 = final int hasPermission =
pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName()); pm.checkPermission(PERMISSION_MAINLINE_NETWORK_STACK, comp.getPackageName());
if (hasPermission != PERMISSION_GRANTED) { if (hasPermission != PERMISSION_GRANTED) {
throw new SecurityException( throw new SecurityException(
"Network stack does not have permission " + PERMISSION_MAINLINE_NETWORK_STACK); "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) { private void log(@NonNull String message) {