Merge changes I5a6174a4,Idfbfdf54

* changes:
  Acquire lock to write NetworkStackConnector
  Allow Bluetooth to bind to NetworkStack
This commit is contained in:
Remi NGUYEN VAN
2019-01-21 23:31:07 +00:00
committed by Gerrit Code Review
3 changed files with 63 additions and 5 deletions

View File

@@ -50,6 +50,8 @@ public class NetworkStack {
public static final String NETWORKSTACK_PACKAGE_NAME = "com.android.mainline.networkstack";
private static final int NETWORKSTACK_TIMEOUT_MS = 10_000;
@NonNull
@GuardedBy("mPendingNetStackRequests")
private final ArrayList<NetworkStackCallback> mPendingNetStackRequests = new ArrayList<>();
@@ -57,6 +59,8 @@ public class NetworkStack {
@GuardedBy("mPendingNetStackRequests")
private INetworkStackConnector mConnector;
private volatile boolean mNetworkStackStartRequested = false;
private interface NetworkStackCallback {
void onNetworkStackConnected(INetworkStackConnector connector);
}
@@ -134,6 +138,7 @@ public class NetworkStack {
* started.
*/
public void start(Context context) {
mNetworkStackStartRequested = true;
// Try to bind in-process if the library is available
IBinder connector = null;
try {
@@ -170,15 +175,54 @@ public class NetworkStack {
}
}
// TODO: use this method to obtain the connector when implementing network stack operations
/**
* For non-system server clients, get the connector registered by the system server.
*/
private INetworkStackConnector getRemoteConnector() {
// Block until the NetworkStack connector is registered in ServiceManager.
// <p>This is only useful for non-system processes that do not have a way to be notified of
// registration completion. Adding a callback system would be too heavy weight considering
// that the connector is registered on boot, so it is unlikely that a client would request
// it before it is registered.
// TODO: consider blocking boot on registration and simplify much of the logic in this class
IBinder connector;
try {
final long before = System.currentTimeMillis();
while ((connector = ServiceManager.getService(Context.NETWORK_STACK_SERVICE)) == null) {
Thread.sleep(20);
if (System.currentTimeMillis() - before > NETWORKSTACK_TIMEOUT_MS) {
Slog.e(TAG, "Timeout waiting for NetworkStack connector");
return null;
}
}
} catch (InterruptedException e) {
Slog.e(TAG, "Error waiting for NetworkStack connector", e);
return null;
}
return INetworkStackConnector.Stub.asInterface(connector);
}
private void requestConnector(@NonNull NetworkStackCallback request) {
// TODO: PID check.
if (Binder.getCallingUid() != Process.SYSTEM_UID) {
final int caller = Binder.getCallingUid();
if (caller != Process.SYSTEM_UID && caller != Process.BLUETOOTH_UID) {
// Don't even attempt to obtain the connector and give a nice error message
throw new SecurityException(
"Only the system server should try to bind to the network stack.");
}
if (!mNetworkStackStartRequested) {
// The network stack is not being started in this process, e.g. this process is not
// the system server. Get a remote connector registered by the system server.
final INetworkStackConnector connector = getRemoteConnector();
synchronized (mPendingNetStackRequests) {
mConnector = connector;
}
request.onNetworkStackConnected(connector);
return;
}
final INetworkStackConnector connector;
synchronized (mPendingNetStackRequests) {
connector = mConnector;

View File

@@ -20,6 +20,7 @@ import static android.net.dhcp.IDhcpServer.STATUS_INVALID_ARGUMENT;
import static android.net.dhcp.IDhcpServer.STATUS_SUCCESS;
import static android.net.dhcp.IDhcpServer.STATUS_UNKNOWN_ERROR;
import static com.android.server.util.PermissionUtil.checkDumpPermission;
import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
import android.annotation.NonNull;
@@ -139,7 +140,7 @@ public class NetworkStackService extends Service {
@Override
protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
@Nullable String[] args) {
checkNetworkStackCallingPermission();
checkDumpPermission();
final IndentingPrintWriter pw = new IndentingPrintWriter(fout, " ");
pw.println("NetworkStack logs:");
mLog.dump(fd, pw, args);

View File

@@ -31,8 +31,21 @@ public final class PermissionUtil {
*/
public static void checkNetworkStackCallingPermission() {
// TODO: check that the calling PID is the system server.
if (getCallingUid() != Process.SYSTEM_UID && getCallingUid() != Process.ROOT_UID) {
throw new SecurityException("Invalid caller: " + getCallingUid());
final int caller = getCallingUid();
if (caller != Process.SYSTEM_UID && caller != Process.BLUETOOTH_UID) {
throw new SecurityException("Invalid caller: " + caller);
}
}
/**
* Check that the caller is allowed to dump the network stack, e.g. dumpsys.
* @throws SecurityException The caller is not allowed to dump the network stack.
*/
public static void checkDumpPermission() {
final int caller = getCallingUid();
if (caller != Process.SYSTEM_UID && caller != Process.ROOT_UID
&& caller != Process.SHELL_UID) {
throw new SecurityException("No dump permissions for caller: " + caller);
}
}