From 2d893b68a9e756e83e5fadd472c1639fa8655693 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Mon, 6 Nov 2023 08:47:40 -0800 Subject: [PATCH] New firewall chain for default background restrictions A new firewall chain is needed to configure background network restrictions for apps. This change only adds the API stubs and traffic controller constants to make the chain work. Policy changes using this chain will follow in the framework code. Test: atest CtsNetTestCases:ConnectivityManagerTest Test: atest ConnectivityServiceTest NO_IFTTT=The Lint rule along with the relevant code in Common.h is being deleted in aosp/2819759 Bug: 304347838 Change-Id: I33e2db6671431f7c576fc931d9f96e684fc1e78a --- bpf_progs/netd.h | 4 +++- common/flags.aconfig | 7 ++++++ framework/api/module-lib-current.txt | 2 ++ .../src/android/net/BpfNetMapsConstants.java | 8 +++++-- .../src/android/net/BpfNetMapsUtils.java | 4 ++++ .../src/android/net/ConnectivityManager.java | 24 +++++++++++++++++++ .../android/server/ConnectivityService.java | 1 + .../net/cts/ConnectivityManagerTest.java | 7 ++++++ .../server/ConnectivityServiceTest.java | 5 ++++ 9 files changed, 59 insertions(+), 3 deletions(-) diff --git a/bpf_progs/netd.h b/bpf_progs/netd.h index d1fc58d627..64ed633277 100644 --- a/bpf_progs/netd.h +++ b/bpf_progs/netd.h @@ -192,6 +192,7 @@ enum UidOwnerMatchType { OEM_DENY_1_MATCH = (1 << 9), OEM_DENY_2_MATCH = (1 << 10), OEM_DENY_3_MATCH = (1 << 11), + BACKGROUND_MATCH = (1 << 12) }; // LINT.ThenChange(../framework/src/android/net/BpfNetMapsConstants.java) @@ -244,7 +245,8 @@ STRUCT_SIZE(IngressDiscardValue, 2 * 4); // 8 // DROP_IF_SET is set of rules that DROP if rule is globally enabled, and per-uid bit is set #define DROP_IF_SET (STANDBY_MATCH | OEM_DENY_1_MATCH | OEM_DENY_2_MATCH | OEM_DENY_3_MATCH) // DROP_IF_UNSET is set of rules that should DROP if globally enabled, and per-uid bit is NOT set -#define DROP_IF_UNSET (DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH | LOW_POWER_STANDBY_MATCH) +#define DROP_IF_UNSET (DOZABLE_MATCH | POWERSAVE_MATCH | RESTRICTED_MATCH \ + | LOW_POWER_STANDBY_MATCH | BACKGROUND_MATCH) // Warning: funky bit-wise arithmetic: in parallel, for all DROP_IF_SET/UNSET rules // check whether the rules are globally enabled, and if so whether the rules are diff --git a/common/flags.aconfig b/common/flags.aconfig index 0c46b4882c..b85c2fefe5 100644 --- a/common/flags.aconfig +++ b/common/flags.aconfig @@ -34,3 +34,10 @@ flag { description: "This flag controls whether isUidNetworkingBlocked is supported" bug: "297836825" } + +flag { + name: "basic_background_restrictions_enabled" + namespace: "android_core_networking" + description: "Block network access for apps in a low importance background state" + bug: "304347838" +} diff --git a/framework/api/module-lib-current.txt b/framework/api/module-lib-current.txt index 4d550678f1..bfb498114a 100644 --- a/framework/api/module-lib-current.txt +++ b/framework/api/module-lib-current.txt @@ -45,6 +45,7 @@ package android.net { field public static final int BLOCKED_METERED_REASON_DATA_SAVER = 65536; // 0x10000 field public static final int BLOCKED_METERED_REASON_MASK = -65536; // 0xffff0000 field public static final int BLOCKED_METERED_REASON_USER_RESTRICTED = 131072; // 0x20000 + field @FlaggedApi("com.android.net.flags.basic_background_restrictions_enabled") public static final int BLOCKED_REASON_APP_BACKGROUND = 64; // 0x40 field public static final int BLOCKED_REASON_APP_STANDBY = 4; // 0x4 field public static final int BLOCKED_REASON_BATTERY_SAVER = 1; // 0x1 field public static final int BLOCKED_REASON_DOZE = 2; // 0x2 @@ -52,6 +53,7 @@ package android.net { field public static final int BLOCKED_REASON_LOW_POWER_STANDBY = 32; // 0x20 field public static final int BLOCKED_REASON_NONE = 0; // 0x0 field public static final int BLOCKED_REASON_RESTRICTED_MODE = 8; // 0x8 + field @FlaggedApi("com.android.net.flags.basic_background_restrictions_enabled") public static final int FIREWALL_CHAIN_BACKGROUND = 6; // 0x6 field public static final int FIREWALL_CHAIN_DOZABLE = 1; // 0x1 field public static final int FIREWALL_CHAIN_LOW_POWER_STANDBY = 5; // 0x5 field public static final int FIREWALL_CHAIN_OEM_DENY_1 = 7; // 0x7 diff --git a/framework/src/android/net/BpfNetMapsConstants.java b/framework/src/android/net/BpfNetMapsConstants.java index c7845979e6..5d0fe73ca4 100644 --- a/framework/src/android/net/BpfNetMapsConstants.java +++ b/framework/src/android/net/BpfNetMapsConstants.java @@ -16,6 +16,7 @@ package android.net; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -77,6 +78,7 @@ public class BpfNetMapsConstants { public static final long OEM_DENY_1_MATCH = (1 << 9); public static final long OEM_DENY_2_MATCH = (1 << 10); public static final long OEM_DENY_3_MATCH = (1 << 11); + public static final long BACKGROUND_MATCH = (1 << 12); public static final List> MATCH_LIST = Arrays.asList( Pair.create(HAPPY_BOX_MATCH, "HAPPY_BOX_MATCH"), @@ -90,7 +92,8 @@ public class BpfNetMapsConstants { Pair.create(LOCKDOWN_VPN_MATCH, "LOCKDOWN_VPN_MATCH"), Pair.create(OEM_DENY_1_MATCH, "OEM_DENY_1_MATCH"), Pair.create(OEM_DENY_2_MATCH, "OEM_DENY_2_MATCH"), - Pair.create(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH") + Pair.create(OEM_DENY_3_MATCH, "OEM_DENY_3_MATCH"), + Pair.create(BACKGROUND_MATCH, "BACKGROUND_MATCH") ); /** @@ -102,7 +105,8 @@ public class BpfNetMapsConstants { FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, - FIREWALL_CHAIN_LOW_POWER_STANDBY + FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND ); /** diff --git a/framework/src/android/net/BpfNetMapsUtils.java b/framework/src/android/net/BpfNetMapsUtils.java index e9c9137e37..11d610cbfe 100644 --- a/framework/src/android/net/BpfNetMapsUtils.java +++ b/framework/src/android/net/BpfNetMapsUtils.java @@ -17,6 +17,7 @@ package android.net; import static android.net.BpfNetMapsConstants.ALLOW_CHAINS; +import static android.net.BpfNetMapsConstants.BACKGROUND_MATCH; import static android.net.BpfNetMapsConstants.DENY_CHAINS; import static android.net.BpfNetMapsConstants.DOZABLE_MATCH; import static android.net.BpfNetMapsConstants.LOW_POWER_STANDBY_MATCH; @@ -28,6 +29,7 @@ import static android.net.BpfNetMapsConstants.OEM_DENY_3_MATCH; import static android.net.BpfNetMapsConstants.POWERSAVE_MATCH; import static android.net.BpfNetMapsConstants.RESTRICTED_MATCH; import static android.net.BpfNetMapsConstants.STANDBY_MATCH; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -70,6 +72,8 @@ public class BpfNetMapsUtils { return POWERSAVE_MATCH; case FIREWALL_CHAIN_RESTRICTED: return RESTRICTED_MATCH; + case FIREWALL_CHAIN_BACKGROUND: + return BACKGROUND_MATCH; case FIREWALL_CHAIN_LOW_POWER_STANDBY: return LOW_POWER_STANDBY_MATCH; case FIREWALL_CHAIN_OEM_DENY_1: diff --git a/framework/src/android/net/ConnectivityManager.java b/framework/src/android/net/ConnectivityManager.java index 586e4b0d6b..57ecf4968a 100644 --- a/framework/src/android/net/ConnectivityManager.java +++ b/framework/src/android/net/ConnectivityManager.java @@ -135,6 +135,8 @@ public class ConnectivityManager { "com.android.net.flags.set_data_saver_via_cm"; static final String SUPPORT_IS_UID_NETWORKING_BLOCKED = "com.android.net.flags.support_is_uid_networking_blocked"; + static final String BASIC_BACKGROUND_RESTRICTIONS_ENABLED = + "com.android.net.flags.basic_background_restrictions_enabled"; } /** @@ -907,6 +909,16 @@ public class ConnectivityManager { @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) public static final int BLOCKED_REASON_LOW_POWER_STANDBY = 1 << 5; + /** + * Flag to indicate that an app is subject to default background restrictions that would + * result in its network access being blocked. + * + * @hide + */ + @FlaggedApi(Flags.BASIC_BACKGROUND_RESTRICTIONS_ENABLED) + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + public static final int BLOCKED_REASON_APP_BACKGROUND = 1 << 6; + /** * Flag to indicate that an app is subject to Data saver restrictions that would * result in its metered network access being blocked. @@ -946,6 +958,7 @@ public class ConnectivityManager { BLOCKED_REASON_RESTRICTED_MODE, BLOCKED_REASON_LOCKDOWN_VPN, BLOCKED_REASON_LOW_POWER_STANDBY, + BLOCKED_REASON_APP_BACKGROUND, BLOCKED_METERED_REASON_DATA_SAVER, BLOCKED_METERED_REASON_USER_RESTRICTED, BLOCKED_METERED_REASON_ADMIN_DISABLED, @@ -1003,6 +1016,16 @@ public class ConnectivityManager { @SystemApi(client = MODULE_LIBRARIES) public static final int FIREWALL_CHAIN_LOW_POWER_STANDBY = 5; + /** + * Firewall chain used for always-on default background restrictions. + * Allowlist of apps that have access because either they are in the foreground or they are + * exempted for specific situations while in the background. + * @hide + */ + @FlaggedApi(Flags.BASIC_BACKGROUND_RESTRICTIONS_ENABLED) + @SystemApi(client = MODULE_LIBRARIES) + public static final int FIREWALL_CHAIN_BACKGROUND = 6; + /** * Firewall chain used for OEM-specific application restrictions. * @@ -1062,6 +1085,7 @@ public class ConnectivityManager { FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_CHAIN_OEM_DENY_3 diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index d8417c1541..47e0bd9a7f 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -12884,6 +12884,7 @@ public class ConnectivityService extends IConnectivityManager.Stub case ConnectivityManager.FIREWALL_CHAIN_POWERSAVE: case ConnectivityManager.FIREWALL_CHAIN_RESTRICTED: case ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY: + case ConnectivityManager.FIREWALL_CHAIN_BACKGROUND: defaultRule = FIREWALL_RULE_DENY; break; default: diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 62614c1231..0a143c538a 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -38,6 +38,7 @@ import static android.content.pm.PackageManager.GET_PERMISSIONS; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.net.ConnectivityManager.EXTRA_NETWORK; import static android.net.ConnectivityManager.EXTRA_NETWORK_REQUEST; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -3538,6 +3539,12 @@ public class ConnectivityManagerTest { doTestFirewallBlocking(FIREWALL_CHAIN_DOZABLE, ALLOWLIST); } + @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @ConnectivityModuleTest + @AppModeFull(reason = "Socket cannot bind in instant app mode") + public void testFirewallBlockingBackground() { + doTestFirewallBlocking(FIREWALL_CHAIN_BACKGROUND, ALLOWLIST); + } + @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest @AppModeFull(reason = "Socket cannot bind in instant app mode") public void testFirewallBlockingPowersave() { diff --git a/tests/unit/java/com/android/server/ConnectivityServiceTest.java b/tests/unit/java/com/android/server/ConnectivityServiceTest.java index aae37e5630..bafd450ff3 100755 --- a/tests/unit/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/unit/java/com/android/server/ConnectivityServiceTest.java @@ -59,6 +59,7 @@ import static android.net.ConnectivityManager.EXTRA_IS_ACTIVE; import static android.net.ConnectivityManager.EXTRA_NETWORK_INFO; import static android.net.ConnectivityManager.EXTRA_NETWORK_TYPE; import static android.net.ConnectivityManager.EXTRA_REALTIME_NS; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_CHAIN_DOZABLE; import static android.net.ConnectivityManager.FIREWALL_CHAIN_LOW_POWER_STANDBY; import static android.net.ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_1; @@ -10475,6 +10476,7 @@ public class ConnectivityServiceTest { doTestSetUidFirewallRule(FIREWALL_CHAIN_POWERSAVE, FIREWALL_RULE_DENY); doTestSetUidFirewallRule(FIREWALL_CHAIN_RESTRICTED, FIREWALL_RULE_DENY); doTestSetUidFirewallRule(FIREWALL_CHAIN_LOW_POWER_STANDBY, FIREWALL_RULE_DENY); + doTestSetUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, FIREWALL_RULE_DENY); doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_RULE_ALLOW); doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_RULE_ALLOW); doTestSetUidFirewallRule(FIREWALL_CHAIN_OEM_DENY_3, FIREWALL_RULE_ALLOW); @@ -10488,6 +10490,7 @@ public class ConnectivityServiceTest { FIREWALL_CHAIN_POWERSAVE, FIREWALL_CHAIN_RESTRICTED, FIREWALL_CHAIN_LOW_POWER_STANDBY, + FIREWALL_CHAIN_BACKGROUND, FIREWALL_CHAIN_OEM_DENY_1, FIREWALL_CHAIN_OEM_DENY_2, FIREWALL_CHAIN_OEM_DENY_3); @@ -10537,6 +10540,7 @@ public class ConnectivityServiceTest { doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_POWERSAVE, allowlist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_RESTRICTED, allowlist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_LOW_POWER_STANDBY, allowlist); + doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_BACKGROUND, allowlist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_STANDBY, denylist); doTestSetFirewallChainEnabledCloseSocket(FIREWALL_CHAIN_OEM_DENY_1, denylist); @@ -10558,6 +10562,7 @@ public class ConnectivityServiceTest { doTestReplaceFirewallChain(FIREWALL_CHAIN_POWERSAVE); doTestReplaceFirewallChain(FIREWALL_CHAIN_RESTRICTED); doTestReplaceFirewallChain(FIREWALL_CHAIN_LOW_POWER_STANDBY); + doTestReplaceFirewallChain(FIREWALL_CHAIN_BACKGROUND); doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_1); doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_2); doTestReplaceFirewallChain(FIREWALL_CHAIN_OEM_DENY_3);