Loading core/java/android/os/INetworkManagementService.aidl +0 −12 Original line number Diff line number Diff line Loading @@ -320,16 +320,6 @@ interface INetworkManagementService void setFirewallUidRules(int chain, in int[] uids, in int[] rules); void setFirewallChainEnabled(int chain, boolean enable); /** * Set all packets from users in ranges to go through VPN specified by netId. */ void addVpnUidRanges(int netId, in UidRange[] ranges); /** * Clears the special VPN rules for users in ranges and VPN specified by netId. */ void removeVpnUidRanges(int netId, in UidRange[] ranges); /** * Start listening for mobile activity state changes. */ Loading Loading @@ -361,7 +351,5 @@ interface INetworkManagementService void removeInterfaceFromLocalNetwork(String iface); int removeRoutesFromLocalNetwork(in List<RouteInfo> routes); void setAllowOnlyVpnForUids(boolean enable, in UidRange[] uidRanges); boolean isNetworkRestricted(int uid); } services/core/java/com/android/server/ConnectivityService.java +15 −7 Original line number Diff line number Diff line Loading @@ -129,6 +129,7 @@ import android.net.RouteInfoParcel; import android.net.SocketKeepalive; import android.net.TetheringManager; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.Uri; import android.net.VpnManager; import android.net.VpnService; Loading Loading @@ -5152,7 +5153,7 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Starting user already has a VPN"); return; } userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId, mKeyStore); userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId, mKeyStore); mVpns.put(userId, userVpn); if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { updateLockdownVpn(); Loading Loading @@ -6622,6 +6623,16 @@ public class ConnectivityService extends IConnectivityManager.Stub && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute()); } private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()]; int index = 0; for (UidRange range : ranges) { stableRanges[index] = new UidRangeParcel(range.start, range.stop); index++; } return stableRanges; } private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc) { Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids(); Loading @@ -6641,14 +6652,11 @@ public class ConnectivityService extends IConnectivityManager.Stub // removing old range works because, unlike the filtering rules below, it's possible to // add duplicate UID routing rules. if (!newRanges.isEmpty()) { final UidRange[] addedRangesArray = new UidRange[newRanges.size()]; newRanges.toArray(addedRangesArray); mNMS.addVpnUidRanges(nai.network.getNetId(), addedRangesArray); mNetd.networkAddUidRanges(nai.network.netId, toUidRangeStableParcels(newRanges)); } if (!prevRanges.isEmpty()) { final UidRange[] removedRangesArray = new UidRange[prevRanges.size()]; prevRanges.toArray(removedRangesArray); mNMS.removeVpnUidRanges(nai.network.getNetId(), removedRangesArray); mNetd.networkRemoveUidRanges( nai.network.netId, toUidRangeStableParcels(prevRanges)); } final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties); final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties); Loading services/core/java/com/android/server/NetworkManagementService.java +2 −56 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ import android.net.NetworkStack; import android.net.NetworkStats; import android.net.RouteInfo; import android.net.TetherStatsParcel; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.shared.NetdUtils; import android.net.shared.RouteUtils; Loading Loading @@ -1393,38 +1392,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } private static UidRangeParcel makeUidRangeParcel(int start, int stop) { UidRangeParcel range = new UidRangeParcel(); range.start = start; range.stop = stop; return range; } private static UidRangeParcel[] toStableParcels(UidRange[] ranges) { UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; for (int i = 0; i < ranges.length; i++) { stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop); } return stableRanges; } @Override public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges) throws ServiceSpecificException { NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges)); } catch (ServiceSpecificException e) { Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" + ": netd command failed", e); throw e; } catch (RemoteException e) { Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" + ": netd command failed", e); throw e.rethrowAsRuntimeException(); } } private void applyUidCleartextNetworkPolicy(int uid, int policy) { final int policyValue; switch (policy) { Loading Loading @@ -1552,27 +1519,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return stats; } @Override public void addVpnUidRanges(int netId, UidRange[] ranges) { NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.networkAddUidRanges(netId, toStableParcels(ranges)); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); } } @Override public void removeVpnUidRanges(int netId, UidRange[] ranges) { NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges)); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); } } @Override public void setFirewallEnabled(boolean enabled) { enforceSystemUid(); Loading Loading @@ -1616,7 +1562,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { ranges = new UidRangeParcel[] { // TODO: is there a better way of finding all existing users? If so, we could // specify their ranges here. makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), new UidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), }; // ... except for the UIDs that have allow rules. synchronized (mRulesLock) { Loading Loading @@ -1647,7 +1593,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { for (int i = 0; i < ranges.length; i++) { if (rules.valueAt(i) == FIREWALL_RULE_DENY) { int uid = rules.keyAt(i); ranges[numUids] = makeUidRangeParcel(uid, uid); ranges[numUids] = new UidRangeParcel(uid, uid); numUids++; } } Loading services/core/java/com/android/server/connectivity/Vpn.java +39 −24 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.DnsResolver; import android.net.INetd; import android.net.INetworkManagementEventObserver; import android.net.Ikev2VpnProfile; import android.net.IpPrefix; Loading @@ -68,6 +69,7 @@ import android.net.NetworkProvider; import android.net.NetworkRequest; import android.net.RouteInfo; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.VpnManager; import android.net.VpnService; import android.net.ipsec.ike.ChildSessionCallback; Loading Loading @@ -188,7 +190,8 @@ public class Vpn { private PendingIntent mStatusIntent; private volatile boolean mEnableTeardown = true; private final INetworkManagementService mNetd; private final INetworkManagementService mNms; private final INetd mNetd; @VisibleForTesting protected VpnConfig mConfig; private final NetworkProvider mNetworkProvider; Loading Loading @@ -234,7 +237,7 @@ public class Vpn { * @see mLockdown */ @GuardedBy("this") private final Set<UidRange> mBlockedUidsAsToldToNetd = new ArraySet<>(); private final Set<UidRangeParcel> mBlockedUidsAsToldToNetd = new ArraySet<>(); // The user id of initiating VPN. private final int mUserId; Loading Loading @@ -363,22 +366,23 @@ public class Vpn { } } public Vpn(Looper looper, Context context, INetworkManagementService netService, public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd, @UserIdInt int userId, @NonNull KeyStore keyStore) { this(looper, context, new Dependencies(), netService, userId, keyStore, this(looper, context, new Dependencies(), netService, netd, userId, keyStore, new SystemServices(context), new Ikev2SessionCreator()); } @VisibleForTesting protected Vpn(Looper looper, Context context, Dependencies deps, INetworkManagementService netService, INetworkManagementService netService, INetd netd, int userId, @NonNull KeyStore keyStore, SystemServices systemServices, Ikev2SessionCreator ikev2SessionCreator) { mContext = context; mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */); mDeps = deps; mNetd = netService; mNms = netService; mNetd = netd; mUserId = userId; mLooper = looper; mSystemServices = systemServices; Loading Loading @@ -912,7 +916,7 @@ public class Vpn { } try { mNetd.denyProtect(mOwnerUID); mNms.denyProtect(mOwnerUID); } catch (Exception e) { Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e); } Loading @@ -922,7 +926,7 @@ public class Vpn { mOwnerUID = getAppUid(newPackage, mUserId); mIsPackageTargetingAtLeastQ = doesPackageTargetAtLeastQ(newPackage); try { mNetd.allowProtect(mOwnerUID); mNms.allowProtect(mOwnerUID); } catch (Exception e) { Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e); } Loading Loading @@ -1579,24 +1583,25 @@ public class Vpn { exemptedPackages = new ArrayList<>(mLockdownAllowlist); exemptedPackages.add(mPackage); } final Set<UidRange> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd); final Set<UidRangeParcel> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd); final Set<UidRange> rangesToTellNetdToAdd; final Set<UidRangeParcel> rangesToTellNetdToAdd; if (enforce) { final Set<UidRange> rangesThatShouldBeBlocked = final Set<UidRange> restrictedProfilesRanges = createUserAndRestrictedProfilesRanges(mUserId, /* allowedApplications */ null, /* disallowedApplications */ exemptedPackages); final Set<UidRangeParcel> rangesThatShouldBeBlocked = new ArraySet<>(); // The UID range of the first user (0-99999) would block the IPSec traffic, which comes // directly from the kernel and is marked as uid=0. So we adjust the range to allow // it through (b/69873852). for (UidRange range : rangesThatShouldBeBlocked) { if (range.start == 0) { rangesThatShouldBeBlocked.remove(range); if (range.stop != 0) { rangesThatShouldBeBlocked.add(new UidRange(1, range.stop)); } for (UidRange range : restrictedProfilesRanges) { if (range.start == 0 && range.stop != 0) { rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.stop)); } else if (range.start != 0) { rangesThatShouldBeBlocked.add(new UidRangeParcel(range.start, range.stop)); } } Loading Loading @@ -1628,13 +1633,13 @@ public class Vpn { * including added ranges that already existed or removed ones that didn't. */ @GuardedBy("this") private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRange> ranges) { private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRangeParcel> ranges) { if (ranges.size() == 0) { return true; } final UidRange[] rangesArray = ranges.toArray(new UidRange[ranges.size()]); final UidRangeParcel[] stableRanges = ranges.toArray(new UidRangeParcel[ranges.size()]); try { mNetd.setAllowOnlyVpnForUids(enforce, rangesArray); mNetd.networkRejectNonSecureVpn(enforce, stableRanges); } catch (RemoteException | RuntimeException e) { Log.e(TAG, "Updating blocked=" + enforce + " for UIDs " + Arrays.toString(ranges.toArray()) + " failed", e); Loading Loading @@ -1849,8 +1854,18 @@ public class Vpn { if (mNetworkInfo.isConnected()) { return !appliesToUid(uid); } else { return UidRange.containsUid(mBlockedUidsAsToldToNetd, uid); return containsUid(mBlockedUidsAsToldToNetd, uid); } } private boolean containsUid(Collection<UidRangeParcel> ranges, int uid) { if (ranges == null) return false; for (UidRangeParcel range : ranges) { if (range.start <= uid && uid <= range.stop) { return true; } } return false; } private void updateAlwaysOnNotification(DetailedState networkState) { Loading Loading @@ -2495,7 +2510,7 @@ public class Vpn { address /* unused */, address /* unused */, network); mNetd.setInterfaceUp(mTunnelIface.getInterfaceName()); mNms.setInterfaceUp(mTunnelIface.getInterfaceName()); mSession = mIkev2SessionCreator.createIkeSession( mContext, Loading tests/net/java/com/android/server/ConnectivityServiceTest.java +12 −5 Original line number Diff line number Diff line Loading @@ -188,6 +188,7 @@ import android.net.RouteInfo; import android.net.RouteInfoParcel; import android.net.SocketKeepalive; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.Uri; import android.net.VpnManager; import android.net.metrics.IpConnectivityLog; Loading Loading @@ -1055,7 +1056,7 @@ public class ConnectivityServiceTest { public MockVpn(int userId) { super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService, userId, mock(KeyStore.class)); mMockNetd, userId, mock(KeyStore.class)); mConfig = new VpnConfig(); } Loading Loading @@ -1094,10 +1095,11 @@ public class ConnectivityServiceTest { mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, mNetworkCapabilities); mMockNetworkAgent.waitForIdle(TIMEOUT_MS); verify(mNetworkManagementService, times(1)) .addVpnUidRanges(eq(mMockVpn.getNetId()), eq(uids.toArray(new UidRange[0]))); verify(mNetworkManagementService, never()) .removeVpnUidRanges(eq(mMockVpn.getNetId()), any()); verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetId()), eq(toUidRangeStableParcels(uids))); verify(mMockNetd, never()) .networkRemoveUidRanges(eq(mMockVpn.getNetId()), any()); mAgentRegistered = true; mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); Loading Loading @@ -1169,6 +1171,11 @@ public class ConnectivityServiceTest { } } private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { return ranges.stream().map( r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); } private void mockVpn(int uid) { synchronized (mService.mVpns) { int userId = UserHandle.getUserId(uid); Loading Loading
core/java/android/os/INetworkManagementService.aidl +0 −12 Original line number Diff line number Diff line Loading @@ -320,16 +320,6 @@ interface INetworkManagementService void setFirewallUidRules(int chain, in int[] uids, in int[] rules); void setFirewallChainEnabled(int chain, boolean enable); /** * Set all packets from users in ranges to go through VPN specified by netId. */ void addVpnUidRanges(int netId, in UidRange[] ranges); /** * Clears the special VPN rules for users in ranges and VPN specified by netId. */ void removeVpnUidRanges(int netId, in UidRange[] ranges); /** * Start listening for mobile activity state changes. */ Loading Loading @@ -361,7 +351,5 @@ interface INetworkManagementService void removeInterfaceFromLocalNetwork(String iface); int removeRoutesFromLocalNetwork(in List<RouteInfo> routes); void setAllowOnlyVpnForUids(boolean enable, in UidRange[] uidRanges); boolean isNetworkRestricted(int uid); }
services/core/java/com/android/server/ConnectivityService.java +15 −7 Original line number Diff line number Diff line Loading @@ -129,6 +129,7 @@ import android.net.RouteInfoParcel; import android.net.SocketKeepalive; import android.net.TetheringManager; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.Uri; import android.net.VpnManager; import android.net.VpnService; Loading Loading @@ -5152,7 +5153,7 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Starting user already has a VPN"); return; } userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, userId, mKeyStore); userVpn = new Vpn(mHandler.getLooper(), mContext, mNMS, mNetd, userId, mKeyStore); mVpns.put(userId, userVpn); if (mUserManager.getUserInfo(userId).isPrimary() && LockdownVpnTracker.isEnabled()) { updateLockdownVpn(); Loading Loading @@ -6622,6 +6623,16 @@ public class ConnectivityService extends IConnectivityManager.Stub && (lp.hasIpv6DefaultRoute() || lp.hasIpv6UnreachableDefaultRoute()); } private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { final UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.size()]; int index = 0; for (UidRange range : ranges) { stableRanges[index] = new UidRangeParcel(range.start, range.stop); index++; } return stableRanges; } private void updateUids(NetworkAgentInfo nai, NetworkCapabilities prevNc, NetworkCapabilities newNc) { Set<UidRange> prevRanges = null == prevNc ? null : prevNc.getUids(); Loading @@ -6641,14 +6652,11 @@ public class ConnectivityService extends IConnectivityManager.Stub // removing old range works because, unlike the filtering rules below, it's possible to // add duplicate UID routing rules. if (!newRanges.isEmpty()) { final UidRange[] addedRangesArray = new UidRange[newRanges.size()]; newRanges.toArray(addedRangesArray); mNMS.addVpnUidRanges(nai.network.getNetId(), addedRangesArray); mNetd.networkAddUidRanges(nai.network.netId, toUidRangeStableParcels(newRanges)); } if (!prevRanges.isEmpty()) { final UidRange[] removedRangesArray = new UidRange[prevRanges.size()]; prevRanges.toArray(removedRangesArray); mNMS.removeVpnUidRanges(nai.network.getNetId(), removedRangesArray); mNetd.networkRemoveUidRanges( nai.network.netId, toUidRangeStableParcels(prevRanges)); } final boolean wasFiltering = requiresVpnIsolation(nai, prevNc, nai.linkProperties); final boolean shouldFilter = requiresVpnIsolation(nai, newNc, nai.linkProperties); Loading
services/core/java/com/android/server/NetworkManagementService.java +2 −56 Original line number Diff line number Diff line Loading @@ -60,7 +60,6 @@ import android.net.NetworkStack; import android.net.NetworkStats; import android.net.RouteInfo; import android.net.TetherStatsParcel; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.shared.NetdUtils; import android.net.shared.RouteUtils; Loading Loading @@ -1393,38 +1392,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { } } private static UidRangeParcel makeUidRangeParcel(int start, int stop) { UidRangeParcel range = new UidRangeParcel(); range.start = start; range.stop = stop; return range; } private static UidRangeParcel[] toStableParcels(UidRange[] ranges) { UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; for (int i = 0; i < ranges.length; i++) { stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop); } return stableRanges; } @Override public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges) throws ServiceSpecificException { NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges)); } catch (ServiceSpecificException e) { Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" + ": netd command failed", e); throw e; } catch (RemoteException e) { Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" + ": netd command failed", e); throw e.rethrowAsRuntimeException(); } } private void applyUidCleartextNetworkPolicy(int uid, int policy) { final int policyValue; switch (policy) { Loading Loading @@ -1552,27 +1519,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub { return stats; } @Override public void addVpnUidRanges(int netId, UidRange[] ranges) { NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.networkAddUidRanges(netId, toStableParcels(ranges)); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); } } @Override public void removeVpnUidRanges(int netId, UidRange[] ranges) { NetworkStack.checkNetworkStackPermission(mContext); try { mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges)); } catch (RemoteException | ServiceSpecificException e) { throw new IllegalStateException(e); } } @Override public void setFirewallEnabled(boolean enabled) { enforceSystemUid(); Loading Loading @@ -1616,7 +1562,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { ranges = new UidRangeParcel[] { // TODO: is there a better way of finding all existing users? If so, we could // specify their ranges here. makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), new UidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), }; // ... except for the UIDs that have allow rules. synchronized (mRulesLock) { Loading Loading @@ -1647,7 +1593,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub { for (int i = 0; i < ranges.length; i++) { if (rules.valueAt(i) == FIREWALL_RULE_DENY) { int uid = rules.keyAt(i); ranges[numUids] = makeUidRangeParcel(uid, uid); ranges[numUids] = new UidRangeParcel(uid, uid); numUids++; } } Loading
services/core/java/com/android/server/connectivity/Vpn.java +39 −24 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.net.ConnectivityManager; import android.net.DnsResolver; import android.net.INetd; import android.net.INetworkManagementEventObserver; import android.net.Ikev2VpnProfile; import android.net.IpPrefix; Loading @@ -68,6 +69,7 @@ import android.net.NetworkProvider; import android.net.NetworkRequest; import android.net.RouteInfo; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.VpnManager; import android.net.VpnService; import android.net.ipsec.ike.ChildSessionCallback; Loading Loading @@ -188,7 +190,8 @@ public class Vpn { private PendingIntent mStatusIntent; private volatile boolean mEnableTeardown = true; private final INetworkManagementService mNetd; private final INetworkManagementService mNms; private final INetd mNetd; @VisibleForTesting protected VpnConfig mConfig; private final NetworkProvider mNetworkProvider; Loading Loading @@ -234,7 +237,7 @@ public class Vpn { * @see mLockdown */ @GuardedBy("this") private final Set<UidRange> mBlockedUidsAsToldToNetd = new ArraySet<>(); private final Set<UidRangeParcel> mBlockedUidsAsToldToNetd = new ArraySet<>(); // The user id of initiating VPN. private final int mUserId; Loading Loading @@ -363,22 +366,23 @@ public class Vpn { } } public Vpn(Looper looper, Context context, INetworkManagementService netService, public Vpn(Looper looper, Context context, INetworkManagementService netService, INetd netd, @UserIdInt int userId, @NonNull KeyStore keyStore) { this(looper, context, new Dependencies(), netService, userId, keyStore, this(looper, context, new Dependencies(), netService, netd, userId, keyStore, new SystemServices(context), new Ikev2SessionCreator()); } @VisibleForTesting protected Vpn(Looper looper, Context context, Dependencies deps, INetworkManagementService netService, INetworkManagementService netService, INetd netd, int userId, @NonNull KeyStore keyStore, SystemServices systemServices, Ikev2SessionCreator ikev2SessionCreator) { mContext = context; mConnectivityManager = mContext.getSystemService(ConnectivityManager.class); mUserIdContext = context.createContextAsUser(UserHandle.of(userId), 0 /* flags */); mDeps = deps; mNetd = netService; mNms = netService; mNetd = netd; mUserId = userId; mLooper = looper; mSystemServices = systemServices; Loading Loading @@ -912,7 +916,7 @@ public class Vpn { } try { mNetd.denyProtect(mOwnerUID); mNms.denyProtect(mOwnerUID); } catch (Exception e) { Log.wtf(TAG, "Failed to disallow UID " + mOwnerUID + " to call protect() " + e); } Loading @@ -922,7 +926,7 @@ public class Vpn { mOwnerUID = getAppUid(newPackage, mUserId); mIsPackageTargetingAtLeastQ = doesPackageTargetAtLeastQ(newPackage); try { mNetd.allowProtect(mOwnerUID); mNms.allowProtect(mOwnerUID); } catch (Exception e) { Log.wtf(TAG, "Failed to allow UID " + mOwnerUID + " to call protect() " + e); } Loading Loading @@ -1579,24 +1583,25 @@ public class Vpn { exemptedPackages = new ArrayList<>(mLockdownAllowlist); exemptedPackages.add(mPackage); } final Set<UidRange> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd); final Set<UidRangeParcel> rangesToTellNetdToRemove = new ArraySet<>(mBlockedUidsAsToldToNetd); final Set<UidRange> rangesToTellNetdToAdd; final Set<UidRangeParcel> rangesToTellNetdToAdd; if (enforce) { final Set<UidRange> rangesThatShouldBeBlocked = final Set<UidRange> restrictedProfilesRanges = createUserAndRestrictedProfilesRanges(mUserId, /* allowedApplications */ null, /* disallowedApplications */ exemptedPackages); final Set<UidRangeParcel> rangesThatShouldBeBlocked = new ArraySet<>(); // The UID range of the first user (0-99999) would block the IPSec traffic, which comes // directly from the kernel and is marked as uid=0. So we adjust the range to allow // it through (b/69873852). for (UidRange range : rangesThatShouldBeBlocked) { if (range.start == 0) { rangesThatShouldBeBlocked.remove(range); if (range.stop != 0) { rangesThatShouldBeBlocked.add(new UidRange(1, range.stop)); } for (UidRange range : restrictedProfilesRanges) { if (range.start == 0 && range.stop != 0) { rangesThatShouldBeBlocked.add(new UidRangeParcel(1, range.stop)); } else if (range.start != 0) { rangesThatShouldBeBlocked.add(new UidRangeParcel(range.start, range.stop)); } } Loading Loading @@ -1628,13 +1633,13 @@ public class Vpn { * including added ranges that already existed or removed ones that didn't. */ @GuardedBy("this") private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRange> ranges) { private boolean setAllowOnlyVpnForUids(boolean enforce, Collection<UidRangeParcel> ranges) { if (ranges.size() == 0) { return true; } final UidRange[] rangesArray = ranges.toArray(new UidRange[ranges.size()]); final UidRangeParcel[] stableRanges = ranges.toArray(new UidRangeParcel[ranges.size()]); try { mNetd.setAllowOnlyVpnForUids(enforce, rangesArray); mNetd.networkRejectNonSecureVpn(enforce, stableRanges); } catch (RemoteException | RuntimeException e) { Log.e(TAG, "Updating blocked=" + enforce + " for UIDs " + Arrays.toString(ranges.toArray()) + " failed", e); Loading Loading @@ -1849,8 +1854,18 @@ public class Vpn { if (mNetworkInfo.isConnected()) { return !appliesToUid(uid); } else { return UidRange.containsUid(mBlockedUidsAsToldToNetd, uid); return containsUid(mBlockedUidsAsToldToNetd, uid); } } private boolean containsUid(Collection<UidRangeParcel> ranges, int uid) { if (ranges == null) return false; for (UidRangeParcel range : ranges) { if (range.start <= uid && uid <= range.stop) { return true; } } return false; } private void updateAlwaysOnNotification(DetailedState networkState) { Loading Loading @@ -2495,7 +2510,7 @@ public class Vpn { address /* unused */, address /* unused */, network); mNetd.setInterfaceUp(mTunnelIface.getInterfaceName()); mNms.setInterfaceUp(mTunnelIface.getInterfaceName()); mSession = mIkev2SessionCreator.createIkeSession( mContext, Loading
tests/net/java/com/android/server/ConnectivityServiceTest.java +12 −5 Original line number Diff line number Diff line Loading @@ -188,6 +188,7 @@ import android.net.RouteInfo; import android.net.RouteInfoParcel; import android.net.SocketKeepalive; import android.net.UidRange; import android.net.UidRangeParcel; import android.net.Uri; import android.net.VpnManager; import android.net.metrics.IpConnectivityLog; Loading Loading @@ -1055,7 +1056,7 @@ public class ConnectivityServiceTest { public MockVpn(int userId) { super(startHandlerThreadAndReturnLooper(), mServiceContext, mNetworkManagementService, userId, mock(KeyStore.class)); mMockNetd, userId, mock(KeyStore.class)); mConfig = new VpnConfig(); } Loading Loading @@ -1094,10 +1095,11 @@ public class ConnectivityServiceTest { mMockNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_VPN, lp, mNetworkCapabilities); mMockNetworkAgent.waitForIdle(TIMEOUT_MS); verify(mNetworkManagementService, times(1)) .addVpnUidRanges(eq(mMockVpn.getNetId()), eq(uids.toArray(new UidRange[0]))); verify(mNetworkManagementService, never()) .removeVpnUidRanges(eq(mMockVpn.getNetId()), any()); verify(mMockNetd, times(1)).networkAddUidRanges(eq(mMockVpn.getNetId()), eq(toUidRangeStableParcels(uids))); verify(mMockNetd, never()) .networkRemoveUidRanges(eq(mMockVpn.getNetId()), any()); mAgentRegistered = true; mNetworkCapabilities.set(mMockNetworkAgent.getNetworkCapabilities()); mNetworkAgent = mMockNetworkAgent.getNetworkAgent(); Loading Loading @@ -1169,6 +1171,11 @@ public class ConnectivityServiceTest { } } private UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) { return ranges.stream().map( r -> new UidRangeParcel(r.start, r.stop)).toArray(UidRangeParcel[]::new); } private void mockVpn(int uid) { synchronized (mService.mVpns) { int userId = UserHandle.getUserId(uid); Loading