From bbadec37d215190583d260d5e1d4ab1df00009d2 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Mon, 16 Aug 2021 15:30:05 +0900 Subject: [PATCH] Add a unit test for a bug in registerDefaultNetworkCallback. Currently, when a VPN app calls registerDefaultNetworkCallback, it will always get its own VPN, even if the VPN app called VpnService.Builder#addDisallowedApplication to take itself out of the VPN's UID ranges. Add a test for the current incorrect behaviour. Also fix an indentation error elsewhere. Bug: 195265065 Test: test-only change Change-Id: Id9648ea71fc7ae10855aa311beeb7975569d17f2 --- .../server/ConnectivityServiceTest.java | 50 ++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index c19ed611fa..06d5e0045f 100644 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -7739,8 +7739,8 @@ public class ConnectivityServiceTest { mMockVpn.disconnect(); } - @Test - public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { + @Test + public void testIsActiveNetworkMeteredOverVpnSpecifyingUnderlyingNetworks() throws Exception { // Returns true by default when no network is available. assertTrue(mCm.isActiveNetworkMetered()); mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR); @@ -8305,6 +8305,52 @@ public class ConnectivityServiceTest { mCm.unregisterNetworkCallback(vpnDefaultCallbackAsUid); } + @Test + public void testVpnExcludesOwnUid() throws Exception { + // required for registerDefaultNetworkCallbackForUid. + mServiceContext.setPermission(NETWORK_SETTINGS, PERMISSION_GRANTED); + + // Connect Wi-Fi. + mWiFiNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_WIFI); + mWiFiNetworkAgent.connect(true /* validated */); + + // Connect a VPN that excludes its UID from its UID ranges. + final LinkProperties lp = new LinkProperties(); + lp.setInterfaceName(VPN_IFNAME); + final int myUid = Process.myUid(); + final Set ranges = new ArraySet<>(); + ranges.add(new UidRange(0, myUid - 1)); + ranges.add(new UidRange(myUid + 1, UserHandle.PER_USER_RANGE - 1)); + mMockVpn.setUnderlyingNetworks(new Network[]{mWiFiNetworkAgent.getNetwork()}); + mMockVpn.establish(lp, myUid, ranges); + + // Wait for validation before registering callbacks. + waitForIdle(); + + final int otherUid = myUid + 1; + final Handler h = new Handler(ConnectivityThread.getInstanceLooper()); + final TestNetworkCallback otherUidCb = new TestNetworkCallback(); + final TestNetworkCallback defaultCb = new TestNetworkCallback(); + final TestNetworkCallback perUidCb = new TestNetworkCallback(); + registerDefaultNetworkCallbackAsUid(otherUidCb, otherUid); + mCm.registerDefaultNetworkCallback(defaultCb, h); + doAsUid(Process.SYSTEM_UID, + () -> mCm.registerDefaultNetworkCallbackForUid(myUid, perUidCb, h)); + + otherUidCb.expectAvailableCallbacksValidated(mMockVpn); + // BUG (b/195265065): the default network for the VPN app is actually Wi-Fi, not the VPN. + defaultCb.expectAvailableCallbacksValidated(mMockVpn); + perUidCb.expectAvailableCallbacksValidated(mMockVpn); + // getActiveNetwork is not affected by this bug. + assertEquals(mMockVpn.getNetwork(), mCm.getActiveNetworkForUid(myUid + 1)); + assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetwork()); + assertEquals(mWiFiNetworkAgent.getNetwork(), mCm.getActiveNetworkForUid(myUid)); + + doAsUid(otherUid, () -> mCm.unregisterNetworkCallback(otherUidCb)); + mCm.unregisterNetworkCallback(defaultCb); + doAsUid(Process.SYSTEM_UID, () -> mCm.unregisterNetworkCallback(perUidCb)); + } + private void setupLegacyLockdownVpn() { final String profileName = "testVpnProfile"; final byte[] profileTag = profileName.getBytes(StandardCharsets.UTF_8);