Loading core/java/android/net/NetworkStack.java +46 −2 Original line number Diff line number Diff line Loading @@ -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<>(); Loading @@ -57,6 +59,8 @@ public class NetworkStack { @GuardedBy("mPendingNetStackRequests") private INetworkStackConnector mConnector; private volatile boolean mNetworkStackStartRequested = false; private interface NetworkStackCallback { void onNetworkStackConnected(INetworkStackConnector connector); } Loading Loading @@ -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 { Loading Loading @@ -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; Loading packages/NetworkStack/src/com/android/server/NetworkStackService.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading packages/NetworkStack/src/com/android/server/util/PermissionUtil.java +15 −2 Original line number Diff line number Diff line Loading @@ -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); } } Loading Loading
core/java/android/net/NetworkStack.java +46 −2 Original line number Diff line number Diff line Loading @@ -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<>(); Loading @@ -57,6 +59,8 @@ public class NetworkStack { @GuardedBy("mPendingNetStackRequests") private INetworkStackConnector mConnector; private volatile boolean mNetworkStackStartRequested = false; private interface NetworkStackCallback { void onNetworkStackConnected(INetworkStackConnector connector); } Loading Loading @@ -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 { Loading Loading @@ -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; Loading
packages/NetworkStack/src/com/android/server/NetworkStackService.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading
packages/NetworkStack/src/com/android/server/util/PermissionUtil.java +15 −2 Original line number Diff line number Diff line Loading @@ -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); } } Loading