diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index e4e2151c56..ddac19d877 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -30,10 +30,10 @@ package android.net { method @Deprecated @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreference(@NonNull android.os.UserHandle, int, @Nullable java.util.concurrent.Executor, @Nullable Runnable); method @RequiresPermission(android.Manifest.permission.NETWORK_STACK) public void setProfileNetworkPreferences(@NonNull android.os.UserHandle, @NonNull java.util.List, @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>); + 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.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(); - method @RequiresPermission(anyOf={android.Manifest.permission.NETWORK_SETTINGS, android.Manifest.permission.NETWORK_STACK, android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK}) public void updateFirewallRule(int, int, boolean); field public static final String ACTION_CLEAR_DNS_CACHE = "android.net.action.CLEAR_DNS_CACHE"; field public static final String ACTION_PROMPT_LOST_VALIDATION = "android.net.action.PROMPT_LOST_VALIDATION"; field public static final String ACTION_PROMPT_PARTIAL_CONNECTIVITY = "android.net.action.PROMPT_PARTIAL_CONNECTIVITY"; @@ -54,6 +54,9 @@ package android.net { field public static final int FIREWALL_CHAIN_POWERSAVE = 3; // 0x3 field public static final int FIREWALL_CHAIN_RESTRICTED = 4; // 0x4 field public static final int FIREWALL_CHAIN_STANDBY = 2; // 0x2 + field public static final int FIREWALL_RULE_ALLOW = 1; // 0x1 + field public static final int FIREWALL_RULE_DEFAULT = 0; // 0x0 + field public static final int FIREWALL_RULE_DENY = 2; // 0x2 field public static final int PROFILE_NETWORK_PREFERENCE_DEFAULT = 0; // 0x0 field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE = 1; // 0x1 field public static final int PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK = 2; // 0x2 diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index a798f6e206..e25a85558c 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -994,6 +994,36 @@ public class ConnectivityManager { public @interface FirewallChain {} // LINT.ThenChange(packages/modules/Connectivity/service/native/include/Common.h) + /** + * Specify default rule which may allow or drop packets depending on existing policy. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int FIREWALL_RULE_DEFAULT = 0; + + /** + * Specify allow rule which allows packets. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int FIREWALL_RULE_ALLOW = 1; + + /** + * Specify deny rule which drops packets. + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int FIREWALL_RULE_DENY = 2; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(flag = false, prefix = "FIREWALL_RULE_", value = { + FIREWALL_RULE_DEFAULT, + FIREWALL_RULE_ALLOW, + FIREWALL_RULE_DENY + }) + public @interface FirewallRule {} + /** * A kludge to facilitate static access where a Context pointer isn't available, like in the * case of the static set/getProcessDefaultNetwork methods and from the Network class. @@ -5802,8 +5832,9 @@ public class ConnectivityManager { * * @param chain target chain. * @param uid uid to allow/deny. - * @param allow whether networking is allowed or denied. + * @param rule firewall rule to allow/drop packets. * @throws IllegalStateException if updating firewall rule failed. + * @throws IllegalArgumentException if {@code rule} is not a valid rule. * @hide */ @SystemApi(client = MODULE_LIBRARIES) @@ -5812,10 +5843,10 @@ public class ConnectivityManager { android.Manifest.permission.NETWORK_STACK, NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK }) - public void updateFirewallRule(@FirewallChain final int chain, final int uid, - final boolean allow) { + public void setUidFirewallRule(@FirewallChain final int chain, final int uid, + @FirewallRule final int rule) { try { - mService.updateFirewallRule(chain, uid, allow); + mService.setUidFirewallRule(chain, uid, rule); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/framework/src/android/net/IConnectivityManager.aidl b/framework/src/android/net/IConnectivityManager.aidl index 0988bf3a0f..bc73769f55 100644 --- a/framework/src/android/net/IConnectivityManager.aidl +++ b/framework/src/android/net/IConnectivityManager.aidl @@ -240,7 +240,7 @@ interface IConnectivityManager void updateMeteredNetworkDenyList(int uid, boolean add); - void updateFirewallRule(int chain, int uid, boolean allow); + void setUidFirewallRule(int chain, int uid, int rule); void setFirewallChainEnabled(int chain, boolean enable); diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index ab5f5d381a..b4cc41a94d 100644 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -34,6 +34,9 @@ import static android.net.ConnectivityManager.BLOCKED_METERED_REASON_MASK; import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; +import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; +import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; import static android.net.ConnectivityManager.TYPE_BLUETOOTH; import static android.net.ConnectivityManager.TYPE_ETHERNET; import static android.net.ConnectivityManager.TYPE_MOBILE; @@ -11218,17 +11221,43 @@ public class ConnectivityService extends IConnectivityManager.Stub } @Override - public void updateFirewallRule(final int chain, final int uid, final boolean allow) { + public void setUidFirewallRule(final int chain, final int uid, final int rule) { enforceNetworkStackOrSettingsPermission(); + // There are only two type of firewall rule: FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY + int firewallRule = getFirewallRuleType(chain, rule); + + if (firewallRule != FIREWALL_RULE_ALLOW && firewallRule != FIREWALL_RULE_DENY) { + throw new IllegalArgumentException("setUidFirewallRule with invalid rule: " + rule); + } + try { - mBpfNetMaps.setUidRule(chain, uid, - allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY); + mBpfNetMaps.setUidRule(chain, uid, firewallRule); } catch (ServiceSpecificException e) { throw new IllegalStateException(e); } } + private int getFirewallRuleType(int chain, int rule) { + final int defaultRule; + switch (chain) { + case ConnectivityManager.FIREWALL_CHAIN_STANDBY: + defaultRule = FIREWALL_RULE_ALLOW; + break; + case ConnectivityManager.FIREWALL_CHAIN_DOZABLE: + case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: + case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: + case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: + defaultRule = FIREWALL_RULE_DENY; + break; + default: + throw new IllegalArgumentException("Unsupported firewall chain: " + chain); + } + if (rule == FIREWALL_RULE_DEFAULT) rule = defaultRule; + + return rule; + } + @Override public void setFirewallChainEnabled(final int chain, final boolean enable) { enforceNetworkStackOrSettingsPermission();