Set allowed UIDs for networks based on policies
Use both per-network allowlisting and all-network denylisting to ensure
consistent and expected firewall behavior for denied transport types.
* [Allowlist] Only allow UIDs to send traffic over a physical network
of a given transport type when their policy permits it.
This addresses previously-unhandled problems that allowed access to
physical network types that should be denied, e.g. when connected to
split-tunnel VPNs. Internally, this uses IP rules that only consult
the routing table for a network for UIDs that are allowed on that
network, using the same methods that are used to implement a VPN's
inclusion or exclusion of UIDs. (Also requires a netd change to
remove default rules; see the referenced change ID.)
* [Denylist] When UIDs' policies deny them access on their active
network's transport type, add them to an overall networking deny-
list, providing similar functionality to the restricted mode
allowlist that was previously also involved in transport-based
restrictions. This accomplishes three things: it prevents incoming
traffic to such UIDs; it allows a UID's active network blocked state
to be tracked for firewall indicator purposes via a later change; and
it's needed for UIDs whose policy prevents them from accessing VPNs,
because the underlying allowlist approach is already in use for
another purpose for virtual networks, as described earlier.
Requires: Icd64aa530e8d202abb97d8325160a5d4c0b4c490
Change-Id: I79342edbec92090cca20853ba50ea7fd48ec81c2
Signed-off-by: Mohammad Hasan Keramat J <ikeramat@protonmail.com>
diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt
index ddac19d..6131116 100644
--- a/framework/api/module-lib-current.txt
+++ b/framework/api/module-lib-current.txt
@@ -31,6 +31,7 @@
method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreferences(@NonNull android.os.UserHandle, @NonNull java.util.List<android.net.ProfileNetworkPreference>, @Nullable java.util.concurrent.Executor, @Nullable Runnable);
method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setRequireVpnForUids(boolean, @NonNull java.util.Collection<android.util.Range<java.lang.Integer>>);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void setUidFirewallRule(int, int, int);
+ method @RequiresPermission(anyOf={android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK, android.Manifest.permission.NETWORK_STACK, android.Manifest.permission.NETWORK_SETTINGS}) public void setUidsAllowedTransports(@NonNull int[], @NonNull long[]);
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_TEST_NETWORKS, android.Manifest.permission.NETWORK_STACK}) public void simulateDataStall(int, long, @NonNull android.net.Network, @NonNull android.os.PersistableBundle);
method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void startCaptivePortalApp(@NonNull android.net.Network);
method public void systemReady();
diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java
index f741c2b..4ab2d0f 100644
--- a/framework/src/android/net/ConnectivityManager.java
+++ b/framework/src/android/net/ConnectivityManager.java
@@ -1408,6 +1408,36 @@
}
/**
+ * Update ConnectivityService's map of UIDs to the transports they are allowed to use.
+ * If a network has a transport type that is not an allowed type for the UID, the UID will
+ * not be allowed to access that network.
+ *
+ * @param uids UIDs to update.
+ * @param allowedTransportsPacked Corresponding bit-packed allowed transports to update.
+ *
+ * @hide
+ */
+ @RequiresPermission(anyOf = {
+ NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK,
+ android.Manifest.permission.NETWORK_STACK,
+ android.Manifest.permission.NETWORK_SETTINGS})
+ @SystemApi(client = MODULE_LIBRARIES)
+ public void setUidsAllowedTransports(@NonNull final int[] uids,
+ @NonNull final long[] allowedTransportsPacked) {
+ Objects.requireNonNull(uids);
+ Objects.requireNonNull(allowedTransportsPacked);
+ if (uids.length != allowedTransportsPacked.length) {
+ throw new IllegalArgumentException(
+ "uids and allowedTransportsPacked must be equal length");
+ }
+ try {
+ mService.setUidsAllowedTransports(uids, allowedTransportsPacked);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Informs ConnectivityService of whether the legacy lockdown VPN, as implemented by
* LockdownVpnTracker, is in use. This is deprecated for new devices starting from Android 12
* but is still supported for backwards compatibility.
diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl
index bc73769..bb36bb8 100644
--- a/framework/src/android/net/IConnectivityManager.aidl
+++ b/framework/src/android/net/IConnectivityManager.aidl
@@ -245,4 +245,6 @@
void setFirewallChainEnabled(int chain, boolean enable);
void replaceFirewallChain(int chain, in int[] uids);
+
+ void setUidsAllowedTransports(in int[] uids, in long[] allowedTransportsPacked);
}