Add a command to block networking for an app
Test: Manual
Bug: 284534251
Change-Id: I90566998501c215de350965e3bffcd852d487bfe
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 85507f6..f888da5 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -97,14 +97,12 @@
import static android.system.OsConstants.ETH_P_ALL;
import static android.system.OsConstants.IPPROTO_TCP;
import static android.system.OsConstants.IPPROTO_UDP;
-
import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired;
import static com.android.net.module.util.PermissionUtils.checkAnyPermissionOf;
import static com.android.net.module.util.PermissionUtils.enforceAnyPermissionOf;
import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermission;
import static com.android.net.module.util.PermissionUtils.enforceNetworkStackPermissionOr;
import static com.android.server.ConnectivityStatsLog.CONNECTIVITY_STATE_SAMPLE;
-
import static java.util.Map.Entry;
import android.Manifest;
@@ -10614,6 +10612,16 @@
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 {
@Override
public int onCommand(String cmd) {
@@ -10643,6 +10651,54 @@
onHelp();
return -1;
}
+ case "set-chain3-enabled": {
+ final Boolean enabled = parseBooleanArgument(getNextArg());
+ if (null == enabled) {
+ onHelp();
+ return -1;
+ }
+ Log.i(TAG, (enabled ? "En" : "Dis") + "abled FIREWALL_CHAIN_OEM_DENY_3");
+ setFirewallChainEnabled(ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3,
+ enabled);
+ return 0;
+ }
+ case "get-chain3-enabled": {
+ final boolean chainEnabled = getFirewallChainEnabled(
+ ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3);
+ pw.println("chain:" + (chainEnabled ? "enabled" : "disabled"));
+ return 0;
+ }
+ case "set-package-networking-enabled": {
+ final Boolean enabled = parseBooleanArgument(getNextArg());
+ final String packageName = getNextArg();
+ if (null == enabled || null == packageName) {
+ onHelp();
+ return -1;
+ }
+ // Throws NameNotFound if the package doesn't exist.
+ final int appId = setPackageFirewallRule(
+ ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3,
+ packageName, enabled ? FIREWALL_RULE_DEFAULT : FIREWALL_RULE_DENY);
+ final String msg = (enabled ? "Enabled" : "Disabled")
+ + " networking for " + packageName + ", appId " + appId;
+ Log.i(TAG, msg);
+ pw.println(msg);
+ return 0;
+ }
+ case "get-package-networking-enabled": {
+ final String packageName = getNextArg();
+ final int rule = getPackageFirewallRule(
+ ConnectivityManager.FIREWALL_CHAIN_OEM_DENY_3, packageName);
+ if (FIREWALL_RULE_ALLOW == rule || FIREWALL_RULE_DEFAULT == rule) {
+ pw.println(packageName + ":" + "allow");
+ } else if (FIREWALL_RULE_DENY == rule) {
+ pw.println(packageName + ":" + "deny");
+ } else {
+ throw new IllegalStateException("Unknown rule " + rule + " for package "
+ + packageName);
+ }
+ return 0;
+ }
case "reevaluate":
// Usage : adb shell cmd connectivity reevaluate <netId>
// If netId is omitted, then reevaluate the default network
@@ -10683,6 +10739,15 @@
pw.println(" Turn airplane mode on or off.");
pw.println(" airplane-mode");
pw.println(" Get airplane mode.");
+ pw.println(" set-chain3-enabled [true|false]");
+ pw.println(" Enable or disable FIREWALL_CHAIN_OEM_DENY_3 for debugging.");
+ pw.println(" get-chain3-enabled");
+ pw.println(" Returns whether FIREWALL_CHAIN_OEM_DENY_3 is enabled.");
+ pw.println(" set-package-networking-enabled [true|false] [package name]");
+ pw.println(" Set the deny bit in FIREWALL_CHAIN_OEM_DENY_3 to package. This has\n"
+ + " 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.");
}
}
@@ -12418,6 +12483,21 @@
}
}
+ private int setPackageFirewallRule(final int chain, final String packageName, final int rule)
+ throws PackageManager.NameNotFoundException {
+ final PackageManager pm = mContext.getPackageManager();
+ final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */));
+ if (appId < Process.FIRST_APPLICATION_UID) {
+ throw new RuntimeException("Can't set package firewall rule for system app "
+ + packageName + " with appId " + appId);
+ }
+ for (final UserHandle uh : mUserManager.getUserHandles(false /* excludeDying */)) {
+ final int uid = uh.getUid(appId);
+ setUidFirewallRule(chain, uid, rule);
+ }
+ return appId;
+ }
+
@Override
public void setUidFirewallRule(final int chain, final int uid, final int rule) {
enforceNetworkStackOrSettingsPermission();
@@ -12436,6 +12516,13 @@
}
}
+ private int getPackageFirewallRule(final int chain, final String packageName)
+ throws PackageManager.NameNotFoundException {
+ final PackageManager pm = mContext.getPackageManager();
+ final int appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0 /* flags */));
+ return getUidFirewallRule(chain, appId);
+ }
+
@Override
public int getUidFirewallRule(final int chain, final int uid) {
enforceNetworkStackOrSettingsPermission();