diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 6e80f024ee..31516fd457 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -894,6 +894,17 @@ public final class NetworkCapabilities implements Parcelable { */ private Set mUids = null; + /** + * Convenience method to set the UIDs this network applies to to a single UID. + * @hide + */ + public NetworkCapabilities setSingleUid(int uid) { + final ArraySet identity = new ArraySet<>(1); + identity.add(new UidRange(uid, uid)); + setUids(identity); + return this; + } + /** * Set the list of UIDs this network applies to. * This makes a copy of the set so that callers can't modify it after the call. diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 216e19b10b..6dbf53850e 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -30,6 +30,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED; import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN; import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; import static android.net.NetworkCapabilities.TRANSPORT_VPN; @@ -711,12 +712,12 @@ public class ConnectivityService extends IConnectivityManager.Stub mSystemProperties = getSystemProperties(); mMetricsLog = logger; - mDefaultRequest = createInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); + mDefaultRequest = createDefaultInternetRequestForTransport(-1, NetworkRequest.Type.REQUEST); NetworkRequestInfo defaultNRI = new NetworkRequestInfo(null, mDefaultRequest, new Binder()); mNetworkRequests.put(mDefaultRequest, defaultNRI); mNetworkRequestInfoLogs.log("REGISTER " + defaultNRI); - mDefaultMobileDataRequest = createInternetRequestForTransport( + mDefaultMobileDataRequest = createDefaultInternetRequestForTransport( NetworkCapabilities.TRANSPORT_CELLULAR, NetworkRequest.Type.BACKGROUND_REQUEST); mHandlerThread = new HandlerThread("ConnectivityServiceThread"); @@ -881,7 +882,7 @@ public class ConnectivityService extends IConnectivityManager.Stub deps); } - private NetworkRequest createInternetRequestForTransport( + private NetworkRequest createDefaultInternetRequestForTransport( int transportType, NetworkRequest.Type type) { NetworkCapabilities netCap = new NetworkCapabilities(); netCap.addCapability(NET_CAPABILITY_INTERNET); @@ -1259,7 +1260,11 @@ public class ConnectivityService extends IConnectivityManager.Stub for (Network network : networks) { nai = getNetworkAgentInfoForNetwork(network); nc = getNetworkCapabilitiesInternal(nai); + // nc is a copy of the capabilities in nai, so it's fine to mutate it + // TODO : don't remove the UIDs when communicating with processes + // that have the NETWORK_SETTINGS permission. if (nc != null) { + nc.setSingleUid(userId); result.put(network, nc); } } @@ -4190,6 +4195,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // the system default network. if (type == NetworkRequest.Type.TRACK_DEFAULT) { networkCapabilities = new NetworkCapabilities(mDefaultRequest.networkCapabilities); + networkCapabilities.removeCapability(NET_CAPABILITY_NOT_VPN); enforceAccessPermission(); } else { networkCapabilities = new NetworkCapabilities(networkCapabilities); @@ -4200,6 +4206,13 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceMeteredApnPolicy(networkCapabilities); } ensureRequestableCapabilities(networkCapabilities); + // Set the UID range for this request to the single UID of the requester. + // This will overwrite any allowed UIDs in the requested capabilities. Though there + // are no visible methods to set the UIDs, an app could use reflection to try and get + // networks for other apps so it's essential that the UIDs are overwritten. + // TODO : don't forcefully set the UID when communicating with processes + // that have the NETWORK_SETTINGS permission. + networkCapabilities.setSingleUid(Binder.getCallingUid()); if (timeoutMs < 0) { throw new IllegalArgumentException("Bad timeout specified"); @@ -4273,6 +4286,9 @@ public class ConnectivityService extends IConnectivityManager.Stub enforceMeteredApnPolicy(networkCapabilities); ensureRequestableCapabilities(networkCapabilities); ensureValidNetworkSpecifier(networkCapabilities); + // TODO : don't forcefully set the UID when communicating with processes + // that have the NETWORK_SETTINGS permission. + networkCapabilities.setSingleUid(Binder.getCallingUid()); NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.REQUEST); @@ -4326,6 +4342,9 @@ public class ConnectivityService extends IConnectivityManager.Stub } NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); + // TODO : don't forcefully set the UIDs when communicating with processes + // that have the NETWORK_SETTINGS permission. + nc.setSingleUid(Binder.getCallingUid()); if (!ConnectivityManager.checkChangePermission(mContext)) { // Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so // make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get @@ -4354,8 +4373,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } ensureValidNetworkSpecifier(networkCapabilities); - NetworkRequest networkRequest = new NetworkRequest( - new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(), + final NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities); + // TODO : don't forcefully set the UIDs when communicating with processes + // that have the NETWORK_SETTINGS permission. + nc.setSingleUid(Binder.getCallingUid()); + + NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(), NetworkRequest.Type.LISTEN); NetworkRequestInfo nri = new NetworkRequestInfo(networkRequest, operation); if (VDBG) log("pendingListenForNetwork for " + nri); @@ -4904,7 +4927,12 @@ public class ConnectivityService extends IConnectivityManager.Stub break; } case ConnectivityManager.CALLBACK_CAP_CHANGED: { - putParcelable(bundle, new NetworkCapabilities(networkAgent.networkCapabilities)); + final NetworkCapabilities nc = + new NetworkCapabilities(networkAgent.networkCapabilities); + // TODO : don't remove the UIDs when communicating with processes + // that have the NETWORK_SETTINGS permission. + nc.setSingleUid(nri.mUid); + putParcelable(bundle, nc); break; } case ConnectivityManager.CALLBACK_IP_CHANGED: { diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 4733deba6d..6e643a3dae 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -128,11 +128,13 @@ import com.android.internal.util.ArrayUtils; import com.android.internal.util.WakeupMessage; import com.android.internal.util.test.BroadcastInterceptingContext; import com.android.internal.util.test.FakeSettingsProvider; +import com.android.server.connectivity.ConnectivityConstants; import com.android.server.connectivity.DefaultNetworkMetrics; import com.android.server.connectivity.IpConnectivityMetrics; import com.android.server.connectivity.MockableSystemProperties; import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkMonitor; +import com.android.server.connectivity.Vpn; import com.android.server.net.NetworkPinner; import com.android.server.net.NetworkPolicyManagerInternal; @@ -380,7 +382,7 @@ public class ConnectivityServiceTest { mScore = 20; break; case TRANSPORT_VPN: - mScore = 0; + mScore = ConnectivityConstants.VPN_DEFAULT_SCORE; break; default: throw new UnsupportedOperationException("unimplemented network type");