From 92f128c51c7a063595abe1e142617e43a0231797 Mon Sep 17 00:00:00 2001 From: paulhu Date: Thu, 1 Jul 2021 18:04:45 +0800 Subject: [PATCH] Force only system uid can set uids allowed on restricted networks - Check whether calling UID/PID is system_server. - For CTS test, enforce NETWORK_SETTINGS permission otherwise if it's a debug build. Bug: 175199465 Test: atest FrameworksNetTests Test: atest ConnectivityManagerTest#testUidsAllowedOnRestrictedNetworks Merged-In: I175a831671d3e52460d28203b09f6c0dda56b61c Change-Id: I175a831671d3e52460d28203b09f6c0dda56b61c --- .../net/ConnectivitySettingsManager.java | 20 +++++++++++++++++++ .../net/cts/ConnectivityManagerTest.java | 19 ++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/framework/src/android/net/ConnectivitySettingsManager.java b/framework/src/android/net/ConnectivitySettingsManager.java index 085de6b685..8fc0065347 100644 --- a/framework/src/android/net/ConnectivitySettingsManager.java +++ b/framework/src/android/net/ConnectivitySettingsManager.java @@ -29,6 +29,8 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.content.Context; import android.net.ConnectivityManager.MultipathPreference; +import android.os.Binder; +import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.provider.Settings; @@ -1039,6 +1041,15 @@ public class ConnectivitySettingsManager { return getUidSetFromString(uidList); } + private static boolean isCallingFromSystem() { + final int uid = Binder.getCallingUid(); + final int pid = Binder.getCallingPid(); + if (uid == Process.SYSTEM_UID && pid == Process.myPid()) { + return true; + } + return false; + } + /** * Set the list of uids(from {@link Settings}) that is allowed to use restricted networks. * @@ -1047,6 +1058,15 @@ public class ConnectivitySettingsManager { */ public static void setUidsAllowedOnRestrictedNetworks(@NonNull Context context, @NonNull Set uidList) { + final boolean calledFromSystem = isCallingFromSystem(); + if (!calledFromSystem) { + // Enforce NETWORK_SETTINGS check if it's debug build. This is for MTS test only. + if (!Build.isDebuggable()) { + throw new SecurityException("Only system can set this setting."); + } + context.enforceCallingOrSelfPermission(android.Manifest.permission.NETWORK_SETTINGS, + "Requires NETWORK_SETTINGS permission"); + } final String uids = getUidStringFromSet(uidList); Settings.Global.putString(context.getContentResolver(), UIDS_ALLOWED_ON_RESTRICTED_NETWORKS, uids); diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index cd5281ff2b..527897eba2 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -2876,6 +2876,10 @@ public class ConnectivityManagerTest { public void testUidsAllowedOnRestrictedNetworks() throws Exception { assumeTrue(TestUtils.shouldTestSApis()); + // TODO (b/175199465): figure out a reasonable permission check for + // setUidsAllowedOnRestrictedNetworks that allows tests but not system-external callers. + assumeTrue(Build.isDebuggable()); + final int uid = mPackageManager.getPackageUid(mContext.getPackageName(), 0 /* flag */); final Set originalUidsAllowedOnRestrictedNetworks = ConnectivitySettingsManager.getUidsAllowedOnRestrictedNetworks(mContext); @@ -2883,8 +2887,9 @@ public class ConnectivityManagerTest { // because it has been just installed to device. In case the uid is existed in setting // mistakenly, try to remove the uid and set correct uids to setting. originalUidsAllowedOnRestrictedNetworks.remove(uid); - ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, - originalUidsAllowedOnRestrictedNetworks); + runWithShellPermissionIdentity(() -> + ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks( + mContext, originalUidsAllowedOnRestrictedNetworks), NETWORK_SETTINGS); final Handler h = new Handler(Looper.getMainLooper()); final TestableNetworkCallback testNetworkCb = new TestableNetworkCallback(); @@ -2931,8 +2936,9 @@ public class ConnectivityManagerTest { final Set newUidsAllowedOnRestrictedNetworks = new ArraySet<>(originalUidsAllowedOnRestrictedNetworks); newUidsAllowedOnRestrictedNetworks.add(uid); - ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, - newUidsAllowedOnRestrictedNetworks); + runWithShellPermissionIdentity(() -> + ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks( + mContext, newUidsAllowedOnRestrictedNetworks), NETWORK_SETTINGS); // Wait a while for sending allowed uids on the restricted network to netd. // TODD: Have a significant signal to know the uids has been send to netd. assertBindSocketToNetworkSuccess(network); @@ -2941,8 +2947,9 @@ public class ConnectivityManagerTest { agent.unregister(); // Restore setting. - ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks(mContext, - originalUidsAllowedOnRestrictedNetworks); + runWithShellPermissionIdentity(() -> + ConnectivitySettingsManager.setUidsAllowedOnRestrictedNetworks( + mContext, originalUidsAllowedOnRestrictedNetworks), NETWORK_SETTINGS); } } }