From 22ea166bbc3e6a73212b96b23bf291515e4ae2c1 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla Date: Thu, 8 Feb 2024 16:06:01 -0800 Subject: [PATCH] Shell commands to tweak uid rules on FIREWALL_CHAIN_BACKGROUND These can be used by manual or automated tests. Test: Manual by using the `cmd connectivity` shell commands Test: atest CtsNetTestCases:ConnectivityManagerTest Test: atest netd_integration_test Bug: 322562125 Change-Id: I1de55e430141f566e510b37554a9416c4444213b --- .../android/server/ConnectivityService.java | 68 ++++++++++++++++--- .../net/cts/ConnectivityManagerTest.java | 34 ++++++++++ 2 files changed, 92 insertions(+), 10 deletions(-) diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java index 1c924889e0..eff9bbd1fc 100755 --- a/service/src/com/android/server/ConnectivityService.java +++ b/service/src/com/android/server/ConnectivityService.java @@ -38,6 +38,7 @@ import static android.net.ConnectivityManager.BLOCKED_REASON_LOCKDOWN_VPN; import static android.net.ConnectivityManager.BLOCKED_REASON_NONE; import static android.net.ConnectivityManager.CALLBACK_IP_CHANGED; import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; +import static android.net.ConnectivityManager.FIREWALL_CHAIN_BACKGROUND; import static android.net.ConnectivityManager.FIREWALL_RULE_ALLOW; import static android.net.ConnectivityManager.FIREWALL_RULE_DEFAULT; import static android.net.ConnectivityManager.FIREWALL_RULE_DENY; @@ -11278,17 +11279,28 @@ public class ConnectivityService extends IConnectivityManager.Stub err.getFileDescriptor(), args); } - private Boolean parseBooleanArgument(final String arg) { - if ("true".equals(arg)) { - return true; - } else if ("false".equals(arg)) { - return false; - } else { - return null; - } - } - private class ShellCmd extends BasicShellCommandHandler { + + private Boolean parseBooleanArgument(final String arg) { + if ("true".equals(arg)) { + return true; + } else if ("false".equals(arg)) { + return false; + } else { + getOutPrintWriter().println("Invalid boolean argument: " + arg); + return null; + } + } + + private Integer parseIntegerArgument(final String arg) { + try { + return Integer.valueOf(arg); + } catch (NumberFormatException ne) { + getOutPrintWriter().println("Invalid integer argument: " + arg); + return null; + } + } + @Override public int onCommand(String cmd) { if (cmd == null) { @@ -11365,6 +11377,38 @@ public class ConnectivityService extends IConnectivityManager.Stub } return 0; } + case "set-background-networking-enabled-for-uid": { + final Integer uid = parseIntegerArgument(getNextArg()); + final Boolean enabled = parseBooleanArgument(getNextArg()); + if (null == enabled || null == uid) { + onHelp(); + return -1; + } + final int rule = enabled ? FIREWALL_RULE_ALLOW : FIREWALL_RULE_DEFAULT; + setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid, rule); + final String msg = (enabled ? "Enabled" : "Disabled") + + " background networking for uid " + uid; + Log.i(TAG, msg); + pw.println(msg); + return 0; + } + case "get-background-networking-enabled-for-uid": { + final Integer uid = parseIntegerArgument(getNextArg()); + if (null == uid) { + onHelp(); + return -1; + } + final int rule = getUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, uid); + if (FIREWALL_RULE_ALLOW == rule) { + pw.println(uid + ": allow"); + } else if (FIREWALL_RULE_DENY == rule || FIREWALL_RULE_DEFAULT == rule) { + pw.println(uid + ": deny"); + } else { + throw new IllegalStateException( + "Unknown rule " + rule + " for uid " + uid); + } + return 0; + } case "reevaluate": // Usage : adb shell cmd connectivity reevaluate // If netId is omitted, then reevaluate the default network @@ -11425,6 +11469,10 @@ public class ConnectivityService extends IConnectivityManager.Stub + " no effect if the chain is disabled."); pw.println(" get-package-networking-enabled [package name]"); pw.println(" Get the deny bit in FIREWALL_CHAIN_OEM_DENY_3 for package."); + pw.println(" set-background-networking-enabled-for-uid [uid] [true|false]"); + pw.println(" Set the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid."); + pw.println(" get-background-networking-enabled-for-uid [uid]"); + pw.println(" Get the allow bit in FIREWALL_CHAIN_BACKGROUND for the given uid."); } } diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java index 2646b609f1..f0edee26ca 100644 --- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java +++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java @@ -1552,6 +1552,40 @@ public class ConnectivityManagerTest { } } + @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @ConnectivityModuleTest + public void testSetBackgroundNetworkingShellCommand() { + final int testUid = 54352; + runShellCommand("cmd connectivity set-background-networking-enabled-for-uid " + testUid + + " true"); + int rule = runAsShell(NETWORK_SETTINGS, + () -> mCm.getUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, testUid)); + assertEquals(rule, FIREWALL_RULE_ALLOW); + + runShellCommand("cmd connectivity set-background-networking-enabled-for-uid " + testUid + + " false"); + rule = runAsShell(NETWORK_SETTINGS, + () -> mCm.getUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, testUid)); + assertEquals(rule, FIREWALL_RULE_DENY); + } + + @Test @IgnoreUpTo(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) @ConnectivityModuleTest + public void testGetBackgroundNetworkingShellCommand() { + final int testUid = 54312; + runAsShell(NETWORK_SETTINGS, + () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, testUid, + FIREWALL_RULE_ALLOW)); + String output = runShellCommand( + "cmd connectivity get-background-networking-enabled-for-uid " + testUid); + assertTrue(output.contains("allow")); + + runAsShell(NETWORK_SETTINGS, + () -> mCm.setUidFirewallRule(FIREWALL_CHAIN_BACKGROUND, testUid, + FIREWALL_RULE_DEFAULT)); + output = runShellCommand( + "cmd connectivity get-background-networking-enabled-for-uid " + testUid); + assertTrue(output.contains("deny")); + } + // TODO: move the following socket keep alive test to dedicated test class. /** * Callback used in tcp keepalive offload that allows caller to wait callback fires.