From aa4ad8c2d152f2d46af9b0b75fed9ca077c0b64c Mon Sep 17 00:00:00 2001 From: Junyu Lai Date: Fri, 28 Oct 2022 15:42:00 +0800 Subject: [PATCH] Allow USE_RESTRICTED_NETWORKS for registerSystemDefaultNetworkCallback Some callers (e.g. iwlan) need to learn about system default network but they cannot have NETWORK_SETTINGS permission. To allow them to use this API but prevent from misuse by unprivileged apps, enforce USE_RESTRICTED_NETWORKS for this API. Test: atest com.android.server.ConnectivityServiceTest#testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings android.net.cts.ConnectivityManagerTest#testRegisterNetworkCallback Fix: 242456635 Change-Id: I80ab27445af874328c9c0f4814a8fbf035ae5df4 --- framework/api/module-lib-current.txt | 2 +- framework/src/android/net/ConnectivityManager.java | 3 ++- .../src/com/android/server/ConnectivityService.java | 9 ++++++++- .../src/android/net/cts/ConnectivityManagerTest.java | 10 ++++++++++ .../com/android/server/ConnectivityServiceTest.java | 9 ++++++++- 5 files changed, 29 insertions(+), 4 deletions(-) diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index a2a1ac0992..073cca25a8 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -15,7 +15,7 @@ package android.net { method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.LinkProperties getRedactedLinkPropertiesForPackage(@NonNull android.net.LinkProperties, int, @NonNull String); method @Nullable @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public android.net.NetworkCapabilities getRedactedNetworkCapabilitiesForPackage(@NonNull android.net.NetworkCapabilities, int, @NonNull String); method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerDefaultNetworkCallbackForUid(int, @NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); - method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); + method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS}) public void registerSystemDefaultNetworkCallback(@NonNull android.net.ConnectivityManager.NetworkCallback, @NonNull android.os.Handler); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkAllowList(int); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void removeUidFromMeteredNetworkDenyList(int); method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void replaceFirewallChain(int, @NonNull int[]); diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 547b4babf7..27bb4c5641 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -4786,7 +4786,8 @@ public class ConnectivityManager { @SuppressLint({"ExecutorRegistration", "PairedRegistration"}) @RequiresPermission(anyOf = { NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, - android.Manifest.permission.NETWORK_SETTINGS}) + android.Manifest.permission.NETWORK_SETTINGS, + android.Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS}) public void registerSystemDefaultNetworkCallback(@NonNull NetworkCallback networkCallback, @NonNull Handler handler) { CallbackHandler cbHandler = new CallbackHandler(handler); diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 93265e51ca..038c42ccf0 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -2800,6 +2800,13 @@ public class ConnectivityService extends IConnectivityManager.Stub NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK); } + private void enforceSettingsOrUseRestrictedNetworksPermission() { + enforceAnyPermissionOf(mContext, + android.Manifest.permission.NETWORK_SETTINGS, + NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, + Manifest.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS); + } + private void enforceNetworkFactoryPermission() { // TODO: Check for the BLUETOOTH_STACK permission once that is in the API surface. if (UserHandle.getAppId(getCallingUid()) == Process.BLUETOOTH_UID) return; @@ -6592,7 +6599,7 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceAccessPermission(); break; case TRACK_SYSTEM_DEFAULT: - enforceSettingsPermission(); + enforceSettingsOrUseRestrictedNetworksPermission(); networkCapabilities = new NetworkCapabilities(defaultNc); break; case BACKGROUND_REQUEST: diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 8dbcc0032d..05e84b7e2f 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -1044,12 +1044,22 @@ public class ConnectivityManagerTest { final TestNetworkCallback bestMatchingCallback = new TestNetworkCallback(); final Handler h = new Handler(Looper.getMainLooper()); if (TestUtils.shouldTestSApis()) { + assertThrows(SecurityException.class, () -> + registerSystemDefaultNetworkCallback(systemDefaultCallback, h)); runWithShellPermissionIdentity(() -> { registerSystemDefaultNetworkCallback(systemDefaultCallback, h); registerDefaultNetworkCallbackForUid(Process.myUid(), perUidCallback, h); }, NETWORK_SETTINGS); registerBestMatchingNetworkCallback(makeDefaultRequest(), bestMatchingCallback, h); } + if (TestUtils.shouldTestTApis()) { + // Verify registerSystemDefaultNetworkCallback can be accessed via + // CONNECTIVITY_USE_RESTRICTED_NETWORKS permission. + final TestNetworkCallback systemDefaultCallback2 = new TestNetworkCallback(); + runWithShellPermissionIdentity(() -> + registerSystemDefaultNetworkCallback(systemDefaultCallback2, h), + CONNECTIVITY_USE_RESTRICTED_NETWORKS); + } Network wifiNetwork = null; mCtsNetUtils.ensureWifiConnected(); diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index d2a71354ec..53cb71c483 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -5121,9 +5121,10 @@ public class ConnectivityServiceTest { } @Test - public void testRegisterPrivilegedDefaultCallbacksRequireNetworkSettings() throws Exception { + public void testRegisterPrivilegedDefaultCallbacksRequirePermissions() throws Exception { mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); mCellNetworkAgent.connect(false /* validated */); + mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); final Handler handler = new Handler(ConnectivityThread.getInstanceLooper()); final TestNetworkCallback callback = new TestNetworkCallback(); @@ -5134,6 +5135,12 @@ public class ConnectivityServiceTest { () -> mCm.registerDefaultNetworkCallbackForUid(APP1_UID, callback, handler)); callback.assertNoCallback(); + mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_GRANTED); + mCm.registerSystemDefaultNetworkCallback(callback, handler); + mServiceContext.setPermission(CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERMISSION_DENIED); + callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent); + mCm.unregisterNetworkCallback(callback); + mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); mCm.registerSystemDefaultNetworkCallback(callback, handler); callback.expectAvailableCallbacksUnvalidated(mCellNetworkAgent);