Block incoming packets in VPN Lockdown mode.
Currently, even when VPN Lockdown mode is enabled, incoming packets are
not dropped if VPN is not connected.
This commit fixed this issue.
After this commit, If VPN Lockdown mode is enabled, incoming packets
are dropped regardless of the VPN connectivity.
Bug: 206482423
Test: atest TrafficControllerTest ConnectivityServiceTest PermissionMonitorTest
Change-Id: If52ece613c8aac1073355e43b6fb9cb3fcc87d1d
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 6fcb680..02b8e62 100644
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -5969,6 +5969,10 @@
+ Arrays.toString(ranges) + "): netd command failed: " + e);
}
+ if (SdkLevel.isAtLeastT()) {
+ mPermissionMonitor.updateVpnLockdownUidRanges(requireVpn, ranges);
+ }
+
for (final NetworkAgentInfo nai : mNetworkAgentInfos) {
final boolean curMetered = nai.networkCapabilities.isMetered();
maybeNotifyNetworkBlocked(nai, curMetered, curMetered,
@@ -7734,8 +7738,8 @@
NetworkAgentInfo nai) {
final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp);
final String newIface = getVpnIsolationInterface(nai, nai.networkCapabilities, newLp);
- final boolean wasFiltering = requiresVpnAllowRule(oldIface);
- final boolean needsFiltering = requiresVpnAllowRule(newIface);
+ final boolean wasFiltering = requiresVpnAllowRule(nai, oldLp, oldIface);
+ final boolean needsFiltering = requiresVpnAllowRule(nai, newLp, newIface);
if (!wasFiltering && !needsFiltering) {
// Nothing to do.
@@ -7748,11 +7752,19 @@
}
final Set<UidRange> ranges = nai.networkCapabilities.getUidRanges();
+ if (ranges == null || ranges.isEmpty()) {
+ return;
+ }
+
final int vpnAppUid = nai.networkCapabilities.getOwnerUid();
// TODO: this create a window of opportunity for apps to receive traffic between the time
// when the old rules are removed and the time when new rules are added. To fix this,
// make eBPF support two allowlisted interfaces so here new rules can be added before the
// old rules are being removed.
+
+ // Null iface given to onVpnUidRangesAdded/Removed is a wildcard to allow apps to receive
+ // packets on all interfaces. This is required to accept incoming traffic in Lockdown mode
+ // by overriding the Lockdown blocking rule.
if (wasFiltering) {
mPermissionMonitor.onVpnUidRangesRemoved(oldIface, ranges, vpnAppUid);
}
@@ -8076,9 +8088,13 @@
/**
* Returns whether we need to set interface filtering rule or not
*/
- private boolean requiresVpnAllowRule(String filterIface) {
- // Allow rules are only needed if VPN isolation is enabled.
- return filterIface != null;
+ private boolean requiresVpnAllowRule(NetworkAgentInfo nai, LinkProperties lp,
+ String filterIface) {
+ // Only filter if lp has an interface.
+ if (lp == null || lp.getInterfaceName() == null) return false;
+ // Before T, allow rules are only needed if VPN isolation is enabled.
+ // T and After T, allow rules are needed for all VPNs.
+ return filterIface != null || (nai.isVPN() && SdkLevel.isAtLeastT());
}
private static UidRangeParcel[] toUidRangeStableParcels(final @NonNull Set<UidRange> ranges) {
@@ -8208,8 +8224,8 @@
}
final String oldIface = getVpnIsolationInterface(nai, prevNc, nai.linkProperties);
final String newIface = getVpnIsolationInterface(nai, newNc, nai.linkProperties);
- final boolean wasFiltering = requiresVpnAllowRule(oldIface);
- final boolean shouldFilter = requiresVpnAllowRule(newIface);
+ final boolean wasFiltering = requiresVpnAllowRule(nai, nai.linkProperties, oldIface);
+ final boolean shouldFilter = requiresVpnAllowRule(nai, nai.linkProperties, newIface);
// For VPN uid interface filtering, old ranges need to be removed before new ranges can
// be added, due to the range being expanded and stored as individual UIDs. For example
// the UIDs might be updated from [0, 99999] to ([0, 10012], [10014, 99999]) which means
@@ -8221,6 +8237,10 @@
// above, where the addition of new ranges happens before the removal of old ranges.
// TODO Fix this window by computing an accurate diff on Set<UidRange>, so the old range
// to be removed will never overlap with the new range to be added.
+
+ // Null iface given to onVpnUidRangesAdded/Removed is a wildcard to allow apps to
+ // receive packets on all interfaces. This is required to accept incoming traffic in
+ // Lockdown mode by overriding the Lockdown blocking rule.
if (wasFiltering && !prevRanges.isEmpty()) {
mPermissionMonitor.onVpnUidRangesRemoved(oldIface, prevRanges,
prevNc.getOwnerUid());