1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server; 18 19 import static android.Manifest.permission.CONNECTIVITY_INTERNAL; 20 import static android.Manifest.permission.NETWORK_SETTINGS; 21 import static android.Manifest.permission.OBSERVE_NETWORK_POLICY; 22 import static android.Manifest.permission.SHUTDOWN; 23 import static android.net.INetd.FIREWALL_BLACKLIST; 24 import static android.net.INetd.FIREWALL_CHAIN_DOZABLE; 25 import static android.net.INetd.FIREWALL_CHAIN_NONE; 26 import static android.net.INetd.FIREWALL_CHAIN_POWERSAVE; 27 import static android.net.INetd.FIREWALL_CHAIN_STANDBY; 28 import static android.net.INetd.FIREWALL_RULE_ALLOW; 29 import static android.net.INetd.FIREWALL_RULE_DENY; 30 import static android.net.INetd.FIREWALL_WHITELIST; 31 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_DOZABLE; 32 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_POWERSAVE; 33 import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_NAME_STANDBY; 34 import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT; 35 import static android.net.NetworkStats.SET_DEFAULT; 36 import static android.net.NetworkStats.STATS_PER_UID; 37 import static android.net.NetworkStats.TAG_NONE; 38 import static android.net.TrafficStats.UID_TETHERING; 39 40 import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED; 41 42 import android.annotation.NonNull; 43 import android.app.ActivityManager; 44 import android.content.Context; 45 import android.net.ConnectivityManager; 46 import android.net.INetd; 47 import android.net.INetdUnsolicitedEventListener; 48 import android.net.INetworkManagementEventObserver; 49 import android.net.ITetheringStatsProvider; 50 import android.net.InetAddresses; 51 import android.net.InterfaceConfiguration; 52 import android.net.InterfaceConfigurationParcel; 53 import android.net.IpPrefix; 54 import android.net.LinkAddress; 55 import android.net.Network; 56 import android.net.NetworkPolicyManager; 57 import android.net.NetworkStack; 58 import android.net.NetworkStats; 59 import android.net.NetworkUtils; 60 import android.net.RouteInfo; 61 import android.net.TetherStatsParcel; 62 import android.net.UidRange; 63 import android.net.UidRangeParcel; 64 import android.net.shared.NetdUtils; 65 import android.net.shared.RouteUtils; 66 import android.net.shared.RouteUtils.ModifyOperation; 67 import android.net.util.NetdService; 68 import android.os.BatteryStats; 69 import android.os.Binder; 70 import android.os.Handler; 71 import android.os.IBinder; 72 import android.os.INetworkActivityListener; 73 import android.os.INetworkManagementService; 74 import android.os.Process; 75 import android.os.RemoteCallbackList; 76 import android.os.RemoteException; 77 import android.os.ServiceManager; 78 import android.os.ServiceSpecificException; 79 import android.os.StrictMode; 80 import android.os.SystemClock; 81 import android.os.SystemProperties; 82 import android.os.Trace; 83 import android.telephony.DataConnectionRealTimeInfo; 84 import android.text.TextUtils; 85 import android.util.Log; 86 import android.util.Slog; 87 import android.util.SparseBooleanArray; 88 import android.util.SparseIntArray; 89 90 import com.android.internal.annotations.GuardedBy; 91 import com.android.internal.annotations.VisibleForTesting; 92 import com.android.internal.app.IBatteryStats; 93 import com.android.internal.util.DumpUtils; 94 import com.android.internal.util.FrameworkStatsLog; 95 import com.android.internal.util.HexDump; 96 import com.android.internal.util.Preconditions; 97 98 import com.google.android.collect.Maps; 99 100 import java.io.BufferedReader; 101 import java.io.DataInputStream; 102 import java.io.FileDescriptor; 103 import java.io.FileInputStream; 104 import java.io.IOException; 105 import java.io.InputStreamReader; 106 import java.io.PrintWriter; 107 import java.net.InetAddress; 108 import java.net.InterfaceAddress; 109 import java.util.ArrayList; 110 import java.util.Arrays; 111 import java.util.HashMap; 112 import java.util.List; 113 import java.util.Map; 114 import java.util.Objects; 115 116 /** 117 * @hide 118 */ 119 public class NetworkManagementService extends INetworkManagementService.Stub { 120 121 /** 122 * Helper class that encapsulates NetworkManagementService dependencies and makes them 123 * easier to mock in unit tests. 124 */ 125 static class SystemServices { getService(String name)126 public IBinder getService(String name) { 127 return ServiceManager.getService(name); 128 } registerLocalService(NetworkManagementInternal nmi)129 public void registerLocalService(NetworkManagementInternal nmi) { 130 LocalServices.addService(NetworkManagementInternal.class, nmi); 131 } getNetd()132 public INetd getNetd() { 133 return NetdService.get(); 134 } 135 } 136 137 private static final String TAG = "NetworkManagement"; 138 private static final boolean DBG = Log.isLoggable(TAG, Log.DEBUG); 139 140 private static final int MAX_UID_RANGES_PER_COMMAND = 10; 141 142 /** 143 * Name representing {@link #setGlobalAlert(long)} limit when delivered to 144 * {@link INetworkManagementEventObserver#limitReached(String, String)}. 145 */ 146 public static final String LIMIT_GLOBAL_ALERT = "globalAlert"; 147 148 static final int DAEMON_MSG_MOBILE_CONN_REAL_TIME_INFO = 1; 149 150 static final boolean MODIFY_OPERATION_ADD = true; 151 static final boolean MODIFY_OPERATION_REMOVE = false; 152 153 /** 154 * Binder context for this service 155 */ 156 private final Context mContext; 157 158 private final Handler mDaemonHandler; 159 160 private final SystemServices mServices; 161 162 private INetd mNetdService; 163 164 private final NetdUnsolicitedEventListener mNetdUnsolicitedEventListener; 165 166 private IBatteryStats mBatteryStats; 167 168 private final RemoteCallbackList<INetworkManagementEventObserver> mObservers = 169 new RemoteCallbackList<>(); 170 171 @GuardedBy("mTetheringStatsProviders") 172 private final HashMap<ITetheringStatsProvider, String> 173 mTetheringStatsProviders = Maps.newHashMap(); 174 175 /** 176 * If both locks need to be held, then they should be obtained in the order: 177 * first {@link #mQuotaLock} and then {@link #mRulesLock}. 178 */ 179 private final Object mQuotaLock = new Object(); 180 private final Object mRulesLock = new Object(); 181 182 /** Set of interfaces with active quotas. */ 183 @GuardedBy("mQuotaLock") 184 private HashMap<String, Long> mActiveQuotas = Maps.newHashMap(); 185 /** Set of interfaces with active alerts. */ 186 @GuardedBy("mQuotaLock") 187 private HashMap<String, Long> mActiveAlerts = Maps.newHashMap(); 188 /** Set of UIDs blacklisted on metered networks. */ 189 @GuardedBy("mRulesLock") 190 private SparseBooleanArray mUidRejectOnMetered = new SparseBooleanArray(); 191 /** Set of UIDs whitelisted on metered networks. */ 192 @GuardedBy("mRulesLock") 193 private SparseBooleanArray mUidAllowOnMetered = new SparseBooleanArray(); 194 /** Set of UIDs with cleartext penalties. */ 195 @GuardedBy("mQuotaLock") 196 private SparseIntArray mUidCleartextPolicy = new SparseIntArray(); 197 /** Set of UIDs that are to be blocked/allowed by firewall controller. */ 198 @GuardedBy("mRulesLock") 199 private SparseIntArray mUidFirewallRules = new SparseIntArray(); 200 /** 201 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 202 * to application idles. 203 */ 204 @GuardedBy("mRulesLock") 205 private SparseIntArray mUidFirewallStandbyRules = new SparseIntArray(); 206 /** 207 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 208 * to device idles. 209 */ 210 @GuardedBy("mRulesLock") 211 private SparseIntArray mUidFirewallDozableRules = new SparseIntArray(); 212 /** 213 * Set of UIDs that are to be blocked/allowed by firewall controller. This set of Ids matches 214 * to device on power-save mode. 215 */ 216 @GuardedBy("mRulesLock") 217 private SparseIntArray mUidFirewallPowerSaveRules = new SparseIntArray(); 218 /** Set of states for the child firewall chains. True if the chain is active. */ 219 @GuardedBy("mRulesLock") 220 final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray(); 221 222 @GuardedBy("mQuotaLock") 223 private volatile boolean mDataSaverMode; 224 225 private final Object mIdleTimerLock = new Object(); 226 /** Set of interfaces with active idle timers. */ 227 private static class IdleTimerParams { 228 public final int timeout; 229 public final int type; 230 public int networkCount; 231 IdleTimerParams(int timeout, int type)232 IdleTimerParams(int timeout, int type) { 233 this.timeout = timeout; 234 this.type = type; 235 this.networkCount = 1; 236 } 237 } 238 private HashMap<String, IdleTimerParams> mActiveIdleTimers = Maps.newHashMap(); 239 240 private volatile boolean mFirewallEnabled; 241 private volatile boolean mStrictEnabled; 242 243 private boolean mMobileActivityFromRadio = false; 244 private int mLastPowerStateFromRadio = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 245 private int mLastPowerStateFromWifi = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 246 247 private final RemoteCallbackList<INetworkActivityListener> mNetworkActivityListeners = 248 new RemoteCallbackList<>(); 249 private boolean mNetworkActive; 250 251 /** 252 * Constructs a new NetworkManagementService instance 253 * 254 * @param context Binder context for this service 255 */ NetworkManagementService( Context context, SystemServices services)256 private NetworkManagementService( 257 Context context, SystemServices services) { 258 mContext = context; 259 mServices = services; 260 261 mDaemonHandler = new Handler(FgThread.get().getLooper()); 262 263 mNetdUnsolicitedEventListener = new NetdUnsolicitedEventListener(); 264 265 mServices.registerLocalService(new LocalService()); 266 267 synchronized (mTetheringStatsProviders) { 268 mTetheringStatsProviders.put(new NetdTetheringStatsProvider(), "netd"); 269 } 270 } 271 272 @VisibleForTesting NetworkManagementService()273 NetworkManagementService() { 274 mContext = null; 275 mDaemonHandler = null; 276 mServices = null; 277 mNetdUnsolicitedEventListener = null; 278 } 279 create(Context context, SystemServices services)280 static NetworkManagementService create(Context context, SystemServices services) 281 throws InterruptedException { 282 final NetworkManagementService service = 283 new NetworkManagementService(context, services); 284 if (DBG) Slog.d(TAG, "Creating NetworkManagementService"); 285 if (DBG) Slog.d(TAG, "Connecting native netd service"); 286 service.connectNativeNetdService(); 287 if (DBG) Slog.d(TAG, "Connected"); 288 return service; 289 } 290 create(Context context)291 public static NetworkManagementService create(Context context) throws InterruptedException { 292 return create(context, new SystemServices()); 293 } 294 systemReady()295 public void systemReady() { 296 if (DBG) { 297 final long start = System.currentTimeMillis(); 298 prepareNativeDaemon(); 299 final long delta = System.currentTimeMillis() - start; 300 Slog.d(TAG, "Prepared in " + delta + "ms"); 301 return; 302 } else { 303 prepareNativeDaemon(); 304 } 305 } 306 getBatteryStats()307 private IBatteryStats getBatteryStats() { 308 synchronized (this) { 309 if (mBatteryStats != null) { 310 return mBatteryStats; 311 } 312 mBatteryStats = 313 IBatteryStats.Stub.asInterface(mServices.getService(BatteryStats.SERVICE_NAME)); 314 return mBatteryStats; 315 } 316 } 317 318 @Override registerObserver(INetworkManagementEventObserver observer)319 public void registerObserver(INetworkManagementEventObserver observer) { 320 NetworkStack.checkNetworkStackPermission(mContext); 321 mObservers.register(observer); 322 } 323 324 @Override unregisterObserver(INetworkManagementEventObserver observer)325 public void unregisterObserver(INetworkManagementEventObserver observer) { 326 NetworkStack.checkNetworkStackPermission(mContext); 327 mObservers.unregister(observer); 328 } 329 330 @FunctionalInterface 331 private interface NetworkManagementEventCallback { sendCallback(INetworkManagementEventObserver o)332 public void sendCallback(INetworkManagementEventObserver o) throws RemoteException; 333 } 334 invokeForAllObservers(NetworkManagementEventCallback eventCallback)335 private void invokeForAllObservers(NetworkManagementEventCallback eventCallback) { 336 final int length = mObservers.beginBroadcast(); 337 try { 338 for (int i = 0; i < length; i++) { 339 try { 340 eventCallback.sendCallback(mObservers.getBroadcastItem(i)); 341 } catch (RemoteException | RuntimeException e) { 342 } 343 } 344 } finally { 345 mObservers.finishBroadcast(); 346 } 347 } 348 349 /** 350 * Notify our observers of an interface status change 351 */ notifyInterfaceStatusChanged(String iface, boolean up)352 private void notifyInterfaceStatusChanged(String iface, boolean up) { 353 invokeForAllObservers(o -> o.interfaceStatusChanged(iface, up)); 354 } 355 356 /** 357 * Notify our observers of an interface link state change 358 * (typically, an Ethernet cable has been plugged-in or unplugged). 359 */ notifyInterfaceLinkStateChanged(String iface, boolean up)360 private void notifyInterfaceLinkStateChanged(String iface, boolean up) { 361 invokeForAllObservers(o -> o.interfaceLinkStateChanged(iface, up)); 362 } 363 364 /** 365 * Notify our observers of an interface addition. 366 */ notifyInterfaceAdded(String iface)367 private void notifyInterfaceAdded(String iface) { 368 invokeForAllObservers(o -> o.interfaceAdded(iface)); 369 } 370 371 /** 372 * Notify our observers of an interface removal. 373 */ notifyInterfaceRemoved(String iface)374 private void notifyInterfaceRemoved(String iface) { 375 // netd already clears out quota and alerts for removed ifaces; update 376 // our sanity-checking state. 377 mActiveAlerts.remove(iface); 378 mActiveQuotas.remove(iface); 379 invokeForAllObservers(o -> o.interfaceRemoved(iface)); 380 } 381 382 /** 383 * Notify our observers of a limit reached. 384 */ notifyLimitReached(String limitName, String iface)385 private void notifyLimitReached(String limitName, String iface) { 386 invokeForAllObservers(o -> o.limitReached(limitName, iface)); 387 } 388 389 /** 390 * Notify our observers of a change in the data activity state of the interface 391 */ notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, int uid, boolean fromRadio)392 private void notifyInterfaceClassActivity(int type, boolean isActive, long tsNanos, 393 int uid, boolean fromRadio) { 394 final boolean isMobile = ConnectivityManager.isNetworkTypeMobile(type); 395 int powerState = isActive 396 ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH 397 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 398 if (isMobile) { 399 if (!fromRadio) { 400 if (mMobileActivityFromRadio) { 401 // If this call is not coming from a report from the radio itself, but we 402 // have previously received reports from the radio, then we will take the 403 // power state to just be whatever the radio last reported. 404 powerState = mLastPowerStateFromRadio; 405 } 406 } else { 407 mMobileActivityFromRadio = true; 408 } 409 if (mLastPowerStateFromRadio != powerState) { 410 mLastPowerStateFromRadio = powerState; 411 try { 412 getBatteryStats().noteMobileRadioPowerState(powerState, tsNanos, uid); 413 } catch (RemoteException e) { 414 } 415 FrameworkStatsLog.write_non_chained( 416 FrameworkStatsLog.MOBILE_RADIO_POWER_STATE_CHANGED, uid, null, powerState); 417 } 418 } 419 420 if (ConnectivityManager.isNetworkTypeWifi(type)) { 421 if (mLastPowerStateFromWifi != powerState) { 422 mLastPowerStateFromWifi = powerState; 423 try { 424 getBatteryStats().noteWifiRadioPowerState(powerState, tsNanos, uid); 425 } catch (RemoteException e) { 426 } 427 FrameworkStatsLog.write_non_chained( 428 FrameworkStatsLog.WIFI_RADIO_POWER_STATE_CHANGED, uid, null, powerState); 429 } 430 } 431 432 if (!isMobile || fromRadio || !mMobileActivityFromRadio) { 433 // Report the change in data activity. We don't do this if this is a change 434 // on the mobile network, that is not coming from the radio itself, and we 435 // have previously seen change reports from the radio. In that case only 436 // the radio is the authority for the current state. 437 final boolean active = isActive; 438 invokeForAllObservers(o -> o.interfaceClassDataActivityChanged( 439 Integer.toString(type), active, tsNanos)); 440 } 441 442 boolean report = false; 443 synchronized (mIdleTimerLock) { 444 if (mActiveIdleTimers.isEmpty()) { 445 // If there are no idle timers, we are not monitoring activity, so we 446 // are always considered active. 447 isActive = true; 448 } 449 if (mNetworkActive != isActive) { 450 mNetworkActive = isActive; 451 report = isActive; 452 } 453 } 454 if (report) { 455 reportNetworkActive(); 456 } 457 } 458 459 @Override registerTetheringStatsProvider(ITetheringStatsProvider provider, String name)460 public void registerTetheringStatsProvider(ITetheringStatsProvider provider, String name) { 461 NetworkStack.checkNetworkStackPermission(mContext); 462 Objects.requireNonNull(provider); 463 synchronized(mTetheringStatsProviders) { 464 mTetheringStatsProviders.put(provider, name); 465 } 466 } 467 468 @Override unregisterTetheringStatsProvider(ITetheringStatsProvider provider)469 public void unregisterTetheringStatsProvider(ITetheringStatsProvider provider) { 470 NetworkStack.checkNetworkStackPermission(mContext); 471 synchronized(mTetheringStatsProviders) { 472 mTetheringStatsProviders.remove(provider); 473 } 474 } 475 476 @Override tetherLimitReached(ITetheringStatsProvider provider)477 public void tetherLimitReached(ITetheringStatsProvider provider) { 478 NetworkStack.checkNetworkStackPermission(mContext); 479 synchronized(mTetheringStatsProviders) { 480 if (!mTetheringStatsProviders.containsKey(provider)) { 481 return; 482 } 483 // No current code examines the interface parameter in a global alert. Just pass null. 484 mDaemonHandler.post(() -> notifyLimitReached(LIMIT_GLOBAL_ALERT, null)); 485 } 486 } 487 488 // Sync the state of the given chain with the native daemon. syncFirewallChainLocked(int chain, String name)489 private void syncFirewallChainLocked(int chain, String name) { 490 SparseIntArray rules; 491 synchronized (mRulesLock) { 492 final SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 493 // Make a copy of the current rules, and then clear them. This is because 494 // setFirewallUidRuleInternal only pushes down rules to the native daemon if they 495 // are different from the current rules stored in the mUidFirewall*Rules array for 496 // the specified chain. If we don't clear the rules, setFirewallUidRuleInternal 497 // will do nothing. 498 rules = uidFirewallRules.clone(); 499 uidFirewallRules.clear(); 500 } 501 if (rules.size() > 0) { 502 // Now push the rules. setFirewallUidRuleInternal will push each of these down to the 503 // native daemon, and also add them to the mUidFirewall*Rules array for the specified 504 // chain. 505 if (DBG) Slog.d(TAG, "Pushing " + rules.size() + " active firewall " 506 + name + "UID rules"); 507 for (int i = 0; i < rules.size(); i++) { 508 setFirewallUidRuleLocked(chain, rules.keyAt(i), rules.valueAt(i)); 509 } 510 } 511 } 512 connectNativeNetdService()513 private void connectNativeNetdService() { 514 mNetdService = mServices.getNetd(); 515 try { 516 mNetdService.registerUnsolicitedEventListener(mNetdUnsolicitedEventListener); 517 if (DBG) Slog.d(TAG, "Register unsolicited event listener"); 518 } catch (RemoteException | ServiceSpecificException e) { 519 Slog.e(TAG, "Failed to set Netd unsolicited event listener " + e); 520 } 521 } 522 523 /** 524 * Prepare native daemon once connected, enabling modules and pushing any 525 * existing in-memory rules. 526 */ prepareNativeDaemon()527 private void prepareNativeDaemon() { 528 529 // push any existing quota or UID rules 530 synchronized (mQuotaLock) { 531 532 // Netd unconditionally enable bandwidth control 533 SystemProperties.set(PROP_QTAGUID_ENABLED, "1"); 534 535 mStrictEnabled = true; 536 537 setDataSaverModeEnabled(mDataSaverMode); 538 539 int size = mActiveQuotas.size(); 540 if (size > 0) { 541 if (DBG) Slog.d(TAG, "Pushing " + size + " active quota rules"); 542 final HashMap<String, Long> activeQuotas = mActiveQuotas; 543 mActiveQuotas = Maps.newHashMap(); 544 for (Map.Entry<String, Long> entry : activeQuotas.entrySet()) { 545 setInterfaceQuota(entry.getKey(), entry.getValue()); 546 } 547 } 548 549 size = mActiveAlerts.size(); 550 if (size > 0) { 551 if (DBG) Slog.d(TAG, "Pushing " + size + " active alert rules"); 552 final HashMap<String, Long> activeAlerts = mActiveAlerts; 553 mActiveAlerts = Maps.newHashMap(); 554 for (Map.Entry<String, Long> entry : activeAlerts.entrySet()) { 555 setInterfaceAlert(entry.getKey(), entry.getValue()); 556 } 557 } 558 559 SparseBooleanArray uidRejectOnQuota = null; 560 SparseBooleanArray uidAcceptOnQuota = null; 561 synchronized (mRulesLock) { 562 size = mUidRejectOnMetered.size(); 563 if (size > 0) { 564 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered blacklist rules"); 565 uidRejectOnQuota = mUidRejectOnMetered; 566 mUidRejectOnMetered = new SparseBooleanArray(); 567 } 568 569 size = mUidAllowOnMetered.size(); 570 if (size > 0) { 571 if (DBG) Slog.d(TAG, "Pushing " + size + " UIDs to metered whitelist rules"); 572 uidAcceptOnQuota = mUidAllowOnMetered; 573 mUidAllowOnMetered = new SparseBooleanArray(); 574 } 575 } 576 if (uidRejectOnQuota != null) { 577 for (int i = 0; i < uidRejectOnQuota.size(); i++) { 578 setUidMeteredNetworkBlacklist(uidRejectOnQuota.keyAt(i), 579 uidRejectOnQuota.valueAt(i)); 580 } 581 } 582 if (uidAcceptOnQuota != null) { 583 for (int i = 0; i < uidAcceptOnQuota.size(); i++) { 584 setUidMeteredNetworkWhitelist(uidAcceptOnQuota.keyAt(i), 585 uidAcceptOnQuota.valueAt(i)); 586 } 587 } 588 589 size = mUidCleartextPolicy.size(); 590 if (size > 0) { 591 if (DBG) Slog.d(TAG, "Pushing " + size + " active UID cleartext policies"); 592 final SparseIntArray local = mUidCleartextPolicy; 593 mUidCleartextPolicy = new SparseIntArray(); 594 for (int i = 0; i < local.size(); i++) { 595 setUidCleartextNetworkPolicy(local.keyAt(i), local.valueAt(i)); 596 } 597 } 598 599 setFirewallEnabled(mFirewallEnabled); 600 601 syncFirewallChainLocked(FIREWALL_CHAIN_NONE, ""); 602 syncFirewallChainLocked(FIREWALL_CHAIN_STANDBY, "standby "); 603 syncFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, "dozable "); 604 syncFirewallChainLocked(FIREWALL_CHAIN_POWERSAVE, "powersave "); 605 606 final int[] chains = 607 {FIREWALL_CHAIN_STANDBY, FIREWALL_CHAIN_DOZABLE, FIREWALL_CHAIN_POWERSAVE}; 608 for (int chain : chains) { 609 if (getFirewallChainState(chain)) { 610 setFirewallChainEnabled(chain, true); 611 } 612 } 613 } 614 615 616 try { 617 getBatteryStats().noteNetworkStatsEnabled(); 618 } catch (RemoteException e) { 619 } 620 621 } 622 623 /** 624 * Notify our observers of a new or updated interface address. 625 */ notifyAddressUpdated(String iface, LinkAddress address)626 private void notifyAddressUpdated(String iface, LinkAddress address) { 627 invokeForAllObservers(o -> o.addressUpdated(iface, address)); 628 } 629 630 /** 631 * Notify our observers of a deleted interface address. 632 */ notifyAddressRemoved(String iface, LinkAddress address)633 private void notifyAddressRemoved(String iface, LinkAddress address) { 634 invokeForAllObservers(o -> o.addressRemoved(iface, address)); 635 } 636 637 /** 638 * Notify our observers of DNS server information received. 639 */ notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses)640 private void notifyInterfaceDnsServerInfo(String iface, long lifetime, String[] addresses) { 641 invokeForAllObservers(o -> o.interfaceDnsServerInfo(iface, lifetime, addresses)); 642 } 643 644 /** 645 * Notify our observers of a route change. 646 */ notifyRouteChange(boolean updated, RouteInfo route)647 private void notifyRouteChange(boolean updated, RouteInfo route) { 648 if (updated) { 649 invokeForAllObservers(o -> o.routeUpdated(route)); 650 } else { 651 invokeForAllObservers(o -> o.routeRemoved(route)); 652 } 653 } 654 655 private class NetdUnsolicitedEventListener extends INetdUnsolicitedEventListener.Stub { 656 @Override onInterfaceClassActivityChanged(boolean isActive, int label, long timestamp, int uid)657 public void onInterfaceClassActivityChanged(boolean isActive, 658 int label, long timestamp, int uid) throws RemoteException { 659 final long timestampNanos; 660 if (timestamp <= 0) { 661 timestampNanos = SystemClock.elapsedRealtimeNanos(); 662 } else { 663 timestampNanos = timestamp; 664 } 665 mDaemonHandler.post(() -> 666 notifyInterfaceClassActivity(label, isActive, timestampNanos, uid, false)); 667 } 668 669 @Override onQuotaLimitReached(String alertName, String ifName)670 public void onQuotaLimitReached(String alertName, String ifName) 671 throws RemoteException { 672 mDaemonHandler.post(() -> notifyLimitReached(alertName, ifName)); 673 } 674 675 @Override onInterfaceDnsServerInfo(String ifName, long lifetime, String[] servers)676 public void onInterfaceDnsServerInfo(String ifName, 677 long lifetime, String[] servers) throws RemoteException { 678 mDaemonHandler.post(() -> notifyInterfaceDnsServerInfo(ifName, lifetime, servers)); 679 } 680 681 @Override onInterfaceAddressUpdated(String addr, String ifName, int flags, int scope)682 public void onInterfaceAddressUpdated(String addr, 683 String ifName, int flags, int scope) throws RemoteException { 684 final LinkAddress address = new LinkAddress(addr, flags, scope); 685 mDaemonHandler.post(() -> notifyAddressUpdated(ifName, address)); 686 } 687 688 @Override onInterfaceAddressRemoved(String addr, String ifName, int flags, int scope)689 public void onInterfaceAddressRemoved(String addr, 690 String ifName, int flags, int scope) throws RemoteException { 691 final LinkAddress address = new LinkAddress(addr, flags, scope); 692 mDaemonHandler.post(() -> notifyAddressRemoved(ifName, address)); 693 } 694 695 @Override onInterfaceAdded(String ifName)696 public void onInterfaceAdded(String ifName) throws RemoteException { 697 mDaemonHandler.post(() -> notifyInterfaceAdded(ifName)); 698 } 699 700 @Override onInterfaceRemoved(String ifName)701 public void onInterfaceRemoved(String ifName) throws RemoteException { 702 mDaemonHandler.post(() -> notifyInterfaceRemoved(ifName)); 703 } 704 705 @Override onInterfaceChanged(String ifName, boolean up)706 public void onInterfaceChanged(String ifName, boolean up) 707 throws RemoteException { 708 mDaemonHandler.post(() -> notifyInterfaceStatusChanged(ifName, up)); 709 } 710 711 @Override onInterfaceLinkStateChanged(String ifName, boolean up)712 public void onInterfaceLinkStateChanged(String ifName, boolean up) 713 throws RemoteException { 714 mDaemonHandler.post(() -> notifyInterfaceLinkStateChanged(ifName, up)); 715 } 716 717 @Override onRouteChanged(boolean updated, String route, String gateway, String ifName)718 public void onRouteChanged(boolean updated, 719 String route, String gateway, String ifName) throws RemoteException { 720 final RouteInfo processRoute = new RouteInfo(new IpPrefix(route), 721 ("".equals(gateway)) ? null : InetAddresses.parseNumericAddress(gateway), 722 ifName); 723 mDaemonHandler.post(() -> notifyRouteChange(updated, processRoute)); 724 } 725 726 @Override onStrictCleartextDetected(int uid, String hex)727 public void onStrictCleartextDetected(int uid, String hex) throws RemoteException { 728 // Don't need to post to mDaemonHandler because the only thing 729 // that notifyCleartextNetwork does is post to a handler 730 ActivityManager.getService().notifyCleartextNetwork(uid, 731 HexDump.hexStringToByteArray(hex)); 732 } 733 734 @Override getInterfaceVersion()735 public int getInterfaceVersion() { 736 return INetdUnsolicitedEventListener.VERSION; 737 } 738 739 @Override getInterfaceHash()740 public String getInterfaceHash() { 741 return INetdUnsolicitedEventListener.HASH; 742 } 743 } 744 745 // 746 // INetworkManagementService members 747 // 748 @Override listInterfaces()749 public String[] listInterfaces() { 750 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these 751 // APIs. 752 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL); 753 try { 754 return mNetdService.interfaceGetList(); 755 } catch (RemoteException | ServiceSpecificException e) { 756 throw new IllegalStateException(e); 757 } 758 } 759 760 /** 761 * Convert InterfaceConfiguration to InterfaceConfigurationParcel with given ifname. 762 */ toStableParcel(InterfaceConfiguration cfg, String iface)763 private static InterfaceConfigurationParcel toStableParcel(InterfaceConfiguration cfg, 764 String iface) { 765 InterfaceConfigurationParcel cfgParcel = new InterfaceConfigurationParcel(); 766 cfgParcel.ifName = iface; 767 String hwAddr = cfg.getHardwareAddress(); 768 if (!TextUtils.isEmpty(hwAddr)) { 769 cfgParcel.hwAddr = hwAddr; 770 } else { 771 cfgParcel.hwAddr = ""; 772 } 773 cfgParcel.ipv4Addr = cfg.getLinkAddress().getAddress().getHostAddress(); 774 cfgParcel.prefixLength = cfg.getLinkAddress().getPrefixLength(); 775 ArrayList<String> flags = new ArrayList<>(); 776 for (String flag : cfg.getFlags()) { 777 flags.add(flag); 778 } 779 cfgParcel.flags = flags.toArray(new String[0]); 780 781 return cfgParcel; 782 } 783 784 /** 785 * Construct InterfaceConfiguration from InterfaceConfigurationParcel. 786 */ fromStableParcel(InterfaceConfigurationParcel p)787 public static InterfaceConfiguration fromStableParcel(InterfaceConfigurationParcel p) { 788 InterfaceConfiguration cfg = new InterfaceConfiguration(); 789 cfg.setHardwareAddress(p.hwAddr); 790 791 final InetAddress addr = NetworkUtils.numericToInetAddress(p.ipv4Addr); 792 cfg.setLinkAddress(new LinkAddress(addr, p.prefixLength)); 793 for (String flag : p.flags) { 794 cfg.setFlag(flag); 795 } 796 797 return cfg; 798 } 799 800 @Override getInterfaceConfig(String iface)801 public InterfaceConfiguration getInterfaceConfig(String iface) { 802 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these 803 // APIs. 804 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL); 805 final InterfaceConfigurationParcel result; 806 try { 807 result = mNetdService.interfaceGetCfg(iface); 808 } catch (RemoteException | ServiceSpecificException e) { 809 throw new IllegalStateException(e); 810 } 811 812 try { 813 final InterfaceConfiguration cfg = fromStableParcel(result); 814 return cfg; 815 } catch (IllegalArgumentException iae) { 816 throw new IllegalStateException("Invalid InterfaceConfigurationParcel", iae); 817 } 818 } 819 820 @Override setInterfaceConfig(String iface, InterfaceConfiguration cfg)821 public void setInterfaceConfig(String iface, InterfaceConfiguration cfg) { 822 // TODO: Remove CONNECTIVITY_INTERNAL after bluetooth tethering has no longer called these 823 // APIs. 824 NetworkStack.checkNetworkStackPermissionOr(mContext, CONNECTIVITY_INTERNAL); 825 LinkAddress linkAddr = cfg.getLinkAddress(); 826 if (linkAddr == null || linkAddr.getAddress() == null) { 827 throw new IllegalStateException("Null LinkAddress given"); 828 } 829 830 final InterfaceConfigurationParcel cfgParcel = toStableParcel(cfg, iface); 831 832 try { 833 mNetdService.interfaceSetCfg(cfgParcel); 834 } catch (RemoteException | ServiceSpecificException e) { 835 throw new IllegalStateException(e); 836 } 837 } 838 839 @Override setInterfaceDown(String iface)840 public void setInterfaceDown(String iface) { 841 NetworkStack.checkNetworkStackPermission(mContext); 842 final InterfaceConfiguration ifcg = getInterfaceConfig(iface); 843 ifcg.setInterfaceDown(); 844 setInterfaceConfig(iface, ifcg); 845 } 846 847 @Override setInterfaceUp(String iface)848 public void setInterfaceUp(String iface) { 849 NetworkStack.checkNetworkStackPermission(mContext); 850 final InterfaceConfiguration ifcg = getInterfaceConfig(iface); 851 ifcg.setInterfaceUp(); 852 setInterfaceConfig(iface, ifcg); 853 } 854 855 @Override setInterfaceIpv6PrivacyExtensions(String iface, boolean enable)856 public void setInterfaceIpv6PrivacyExtensions(String iface, boolean enable) { 857 NetworkStack.checkNetworkStackPermission(mContext); 858 try { 859 mNetdService.interfaceSetIPv6PrivacyExtensions(iface, enable); 860 } catch (RemoteException | ServiceSpecificException e) { 861 throw new IllegalStateException(e); 862 } 863 } 864 865 /* TODO: This is right now a IPv4 only function. Works for wifi which loses its 866 IPv6 addresses on interface down, but we need to do full clean up here */ 867 @Override clearInterfaceAddresses(String iface)868 public void clearInterfaceAddresses(String iface) { 869 NetworkStack.checkNetworkStackPermission(mContext); 870 try { 871 mNetdService.interfaceClearAddrs(iface); 872 } catch (RemoteException | ServiceSpecificException e) { 873 throw new IllegalStateException(e); 874 } 875 } 876 877 @Override enableIpv6(String iface)878 public void enableIpv6(String iface) { 879 NetworkStack.checkNetworkStackPermission(mContext); 880 try { 881 mNetdService.interfaceSetEnableIPv6(iface, true); 882 } catch (RemoteException | ServiceSpecificException e) { 883 throw new IllegalStateException(e); 884 } 885 } 886 887 @Override setIPv6AddrGenMode(String iface, int mode)888 public void setIPv6AddrGenMode(String iface, int mode) throws ServiceSpecificException { 889 NetworkStack.checkNetworkStackPermission(mContext); 890 try { 891 mNetdService.setIPv6AddrGenMode(iface, mode); 892 } catch (RemoteException e) { 893 throw e.rethrowAsRuntimeException(); 894 } 895 } 896 897 @Override disableIpv6(String iface)898 public void disableIpv6(String iface) { 899 NetworkStack.checkNetworkStackPermission(mContext); 900 try { 901 mNetdService.interfaceSetEnableIPv6(iface, false); 902 } catch (RemoteException | ServiceSpecificException e) { 903 throw new IllegalStateException(e); 904 } 905 } 906 907 @Override addRoute(int netId, RouteInfo route)908 public void addRoute(int netId, RouteInfo route) { 909 NetworkStack.checkNetworkStackPermission(mContext); 910 RouteUtils.modifyRoute(mNetdService, ModifyOperation.ADD, netId, route); 911 } 912 913 @Override removeRoute(int netId, RouteInfo route)914 public void removeRoute(int netId, RouteInfo route) { 915 NetworkStack.checkNetworkStackPermission(mContext); 916 RouteUtils.modifyRoute(mNetdService, ModifyOperation.REMOVE, netId, route); 917 } 918 readRouteList(String filename)919 private ArrayList<String> readRouteList(String filename) { 920 FileInputStream fstream = null; 921 ArrayList<String> list = new ArrayList<>(); 922 923 try { 924 fstream = new FileInputStream(filename); 925 DataInputStream in = new DataInputStream(fstream); 926 BufferedReader br = new BufferedReader(new InputStreamReader(in)); 927 String s; 928 929 // throw away the title line 930 931 while (((s = br.readLine()) != null) && (s.length() != 0)) { 932 list.add(s); 933 } 934 } catch (IOException ex) { 935 // return current list, possibly empty 936 } finally { 937 if (fstream != null) { 938 try { 939 fstream.close(); 940 } catch (IOException ex) {} 941 } 942 } 943 944 return list; 945 } 946 947 @Override setMtu(String iface, int mtu)948 public void setMtu(String iface, int mtu) { 949 NetworkStack.checkNetworkStackPermission(mContext); 950 951 try { 952 mNetdService.interfaceSetMtu(iface, mtu); 953 } catch (RemoteException | ServiceSpecificException e) { 954 throw new IllegalStateException(e); 955 } 956 } 957 958 @Override shutdown()959 public void shutdown() { 960 // TODO: remove from aidl if nobody calls externally 961 mContext.enforceCallingOrSelfPermission(SHUTDOWN, TAG); 962 963 Slog.i(TAG, "Shutting down"); 964 } 965 966 @Override getIpForwardingEnabled()967 public boolean getIpForwardingEnabled() throws IllegalStateException{ 968 NetworkStack.checkNetworkStackPermission(mContext); 969 970 try { 971 final boolean isEnabled = mNetdService.ipfwdEnabled(); 972 return isEnabled; 973 } catch (RemoteException | ServiceSpecificException e) { 974 throw new IllegalStateException(e); 975 } 976 } 977 978 @Override setIpForwardingEnabled(boolean enable)979 public void setIpForwardingEnabled(boolean enable) { 980 NetworkStack.checkNetworkStackPermission(mContext); 981 try { 982 if (enable) { 983 mNetdService.ipfwdEnableForwarding("tethering"); 984 } else { 985 mNetdService.ipfwdDisableForwarding("tethering"); 986 } 987 } catch (RemoteException | ServiceSpecificException e) { 988 throw new IllegalStateException(e); 989 } 990 } 991 992 @Override startTethering(String[] dhcpRange)993 public void startTethering(String[] dhcpRange) { 994 startTetheringWithConfiguration(true, dhcpRange); 995 } 996 997 @Override startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange)998 public void startTetheringWithConfiguration(boolean usingLegacyDnsProxy, String[] dhcpRange) { 999 NetworkStack.checkNetworkStackPermission(mContext); 1000 try { 1001 NetdUtils.tetherStart(mNetdService, usingLegacyDnsProxy, dhcpRange); 1002 } catch (RemoteException | ServiceSpecificException e) { 1003 throw new IllegalStateException(e); 1004 } 1005 } 1006 1007 @Override stopTethering()1008 public void stopTethering() { 1009 NetworkStack.checkNetworkStackPermission(mContext); 1010 try { 1011 mNetdService.tetherStop(); 1012 } catch (RemoteException | ServiceSpecificException e) { 1013 throw new IllegalStateException(e); 1014 } 1015 } 1016 1017 @Override isTetheringStarted()1018 public boolean isTetheringStarted() { 1019 NetworkStack.checkNetworkStackPermission(mContext); 1020 1021 try { 1022 final boolean isEnabled = mNetdService.tetherIsEnabled(); 1023 return isEnabled; 1024 } catch (RemoteException | ServiceSpecificException e) { 1025 throw new IllegalStateException(e); 1026 } 1027 } 1028 1029 @Override tetherInterface(String iface)1030 public void tetherInterface(String iface) { 1031 NetworkStack.checkNetworkStackPermission(mContext); 1032 try { 1033 final LinkAddress addr = getInterfaceConfig(iface).getLinkAddress(); 1034 final IpPrefix dest = new IpPrefix(addr.getAddress(), addr.getPrefixLength()); 1035 NetdUtils.tetherInterface(mNetdService, iface, dest); 1036 } catch (RemoteException | ServiceSpecificException e) { 1037 throw new IllegalStateException(e); 1038 } 1039 } 1040 1041 @Override untetherInterface(String iface)1042 public void untetherInterface(String iface) { 1043 NetworkStack.checkNetworkStackPermission(mContext); 1044 try { 1045 NetdUtils.untetherInterface(mNetdService, iface); 1046 } catch (RemoteException | ServiceSpecificException e) { 1047 throw new IllegalStateException(e); 1048 } 1049 } 1050 1051 @Override listTetheredInterfaces()1052 public String[] listTetheredInterfaces() { 1053 NetworkStack.checkNetworkStackPermission(mContext); 1054 try { 1055 return mNetdService.tetherInterfaceList(); 1056 } catch (RemoteException | ServiceSpecificException e) { 1057 throw new IllegalStateException(e); 1058 } 1059 } 1060 1061 @Override setDnsForwarders(Network network, String[] dns)1062 public void setDnsForwarders(Network network, String[] dns) { 1063 NetworkStack.checkNetworkStackPermission(mContext); 1064 1065 int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET; 1066 1067 try { 1068 mNetdService.tetherDnsSet(netId, dns); 1069 } catch (RemoteException | ServiceSpecificException e) { 1070 throw new IllegalStateException(e); 1071 } 1072 } 1073 1074 @Override getDnsForwarders()1075 public String[] getDnsForwarders() { 1076 NetworkStack.checkNetworkStackPermission(mContext); 1077 try { 1078 return mNetdService.tetherDnsList(); 1079 } catch (RemoteException | ServiceSpecificException e) { 1080 throw new IllegalStateException(e); 1081 } 1082 } 1083 excludeLinkLocal(List<InterfaceAddress> addresses)1084 private List<InterfaceAddress> excludeLinkLocal(List<InterfaceAddress> addresses) { 1085 ArrayList<InterfaceAddress> filtered = new ArrayList<>(addresses.size()); 1086 for (InterfaceAddress ia : addresses) { 1087 if (!ia.getAddress().isLinkLocalAddress()) 1088 filtered.add(ia); 1089 } 1090 return filtered; 1091 } 1092 modifyInterfaceForward(boolean add, String fromIface, String toIface)1093 private void modifyInterfaceForward(boolean add, String fromIface, String toIface) { 1094 try { 1095 if (add) { 1096 mNetdService.ipfwdAddInterfaceForward(fromIface, toIface); 1097 } else { 1098 mNetdService.ipfwdRemoveInterfaceForward(fromIface, toIface); 1099 } 1100 } catch (RemoteException | ServiceSpecificException e) { 1101 throw new IllegalStateException(e); 1102 } 1103 } 1104 1105 @Override startInterfaceForwarding(String fromIface, String toIface)1106 public void startInterfaceForwarding(String fromIface, String toIface) { 1107 NetworkStack.checkNetworkStackPermission(mContext); 1108 modifyInterfaceForward(true, fromIface, toIface); 1109 } 1110 1111 @Override stopInterfaceForwarding(String fromIface, String toIface)1112 public void stopInterfaceForwarding(String fromIface, String toIface) { 1113 NetworkStack.checkNetworkStackPermission(mContext); 1114 modifyInterfaceForward(false, fromIface, toIface); 1115 } 1116 1117 @Override enableNat(String internalInterface, String externalInterface)1118 public void enableNat(String internalInterface, String externalInterface) { 1119 NetworkStack.checkNetworkStackPermission(mContext); 1120 try { 1121 mNetdService.tetherAddForward(internalInterface, externalInterface); 1122 } catch (RemoteException | ServiceSpecificException e) { 1123 throw new IllegalStateException(e); 1124 } 1125 } 1126 1127 @Override disableNat(String internalInterface, String externalInterface)1128 public void disableNat(String internalInterface, String externalInterface) { 1129 NetworkStack.checkNetworkStackPermission(mContext); 1130 try { 1131 mNetdService.tetherRemoveForward(internalInterface, externalInterface); 1132 } catch (RemoteException | ServiceSpecificException e) { 1133 throw new IllegalStateException(e); 1134 } 1135 } 1136 1137 @Override addIdleTimer(String iface, int timeout, final int type)1138 public void addIdleTimer(String iface, int timeout, final int type) { 1139 NetworkStack.checkNetworkStackPermission(mContext); 1140 1141 if (DBG) Slog.d(TAG, "Adding idletimer"); 1142 1143 synchronized (mIdleTimerLock) { 1144 IdleTimerParams params = mActiveIdleTimers.get(iface); 1145 if (params != null) { 1146 // the interface already has idletimer, update network count 1147 params.networkCount++; 1148 return; 1149 } 1150 1151 try { 1152 mNetdService.idletimerAddInterface(iface, timeout, Integer.toString(type)); 1153 } catch (RemoteException | ServiceSpecificException e) { 1154 throw new IllegalStateException(e); 1155 } 1156 mActiveIdleTimers.put(iface, new IdleTimerParams(timeout, type)); 1157 1158 // Networks start up. 1159 if (ConnectivityManager.isNetworkTypeMobile(type)) { 1160 mNetworkActive = false; 1161 } 1162 mDaemonHandler.post(() -> notifyInterfaceClassActivity(type, true, 1163 SystemClock.elapsedRealtimeNanos(), -1, false)); 1164 } 1165 } 1166 1167 @Override removeIdleTimer(String iface)1168 public void removeIdleTimer(String iface) { 1169 NetworkStack.checkNetworkStackPermission(mContext); 1170 1171 if (DBG) Slog.d(TAG, "Removing idletimer"); 1172 1173 synchronized (mIdleTimerLock) { 1174 final IdleTimerParams params = mActiveIdleTimers.get(iface); 1175 if (params == null || --(params.networkCount) > 0) { 1176 return; 1177 } 1178 1179 try { 1180 mNetdService.idletimerRemoveInterface(iface, 1181 params.timeout, Integer.toString(params.type)); 1182 } catch (RemoteException | ServiceSpecificException e) { 1183 throw new IllegalStateException(e); 1184 } 1185 mActiveIdleTimers.remove(iface); 1186 mDaemonHandler.post(() -> notifyInterfaceClassActivity(params.type, false, 1187 SystemClock.elapsedRealtimeNanos(), -1, false)); 1188 } 1189 } 1190 1191 @Override setInterfaceQuota(String iface, long quotaBytes)1192 public void setInterfaceQuota(String iface, long quotaBytes) { 1193 NetworkStack.checkNetworkStackPermission(mContext); 1194 1195 synchronized (mQuotaLock) { 1196 if (mActiveQuotas.containsKey(iface)) { 1197 throw new IllegalStateException("iface " + iface + " already has quota"); 1198 } 1199 1200 try { 1201 // TODO: support quota shared across interfaces 1202 mNetdService.bandwidthSetInterfaceQuota(iface, quotaBytes); 1203 1204 mActiveQuotas.put(iface, quotaBytes); 1205 } catch (RemoteException | ServiceSpecificException e) { 1206 throw new IllegalStateException(e); 1207 } 1208 1209 synchronized (mTetheringStatsProviders) { 1210 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) { 1211 try { 1212 provider.setInterfaceQuota(iface, quotaBytes); 1213 } catch (RemoteException e) { 1214 Log.e(TAG, "Problem setting tethering data limit on provider " + 1215 mTetheringStatsProviders.get(provider) + ": " + e); 1216 } 1217 } 1218 } 1219 } 1220 } 1221 1222 @Override removeInterfaceQuota(String iface)1223 public void removeInterfaceQuota(String iface) { 1224 NetworkStack.checkNetworkStackPermission(mContext); 1225 1226 synchronized (mQuotaLock) { 1227 if (!mActiveQuotas.containsKey(iface)) { 1228 // TODO: eventually consider throwing 1229 return; 1230 } 1231 1232 mActiveQuotas.remove(iface); 1233 mActiveAlerts.remove(iface); 1234 1235 try { 1236 // TODO: support quota shared across interfaces 1237 mNetdService.bandwidthRemoveInterfaceQuota(iface); 1238 } catch (RemoteException | ServiceSpecificException e) { 1239 throw new IllegalStateException(e); 1240 } 1241 1242 synchronized (mTetheringStatsProviders) { 1243 for (ITetheringStatsProvider provider : mTetheringStatsProviders.keySet()) { 1244 try { 1245 provider.setInterfaceQuota(iface, ITetheringStatsProvider.QUOTA_UNLIMITED); 1246 } catch (RemoteException e) { 1247 Log.e(TAG, "Problem removing tethering data limit on provider " + 1248 mTetheringStatsProviders.get(provider) + ": " + e); 1249 } 1250 } 1251 } 1252 } 1253 } 1254 1255 @Override setInterfaceAlert(String iface, long alertBytes)1256 public void setInterfaceAlert(String iface, long alertBytes) { 1257 NetworkStack.checkNetworkStackPermission(mContext); 1258 1259 // quick sanity check 1260 if (!mActiveQuotas.containsKey(iface)) { 1261 throw new IllegalStateException("setting alert requires existing quota on iface"); 1262 } 1263 1264 synchronized (mQuotaLock) { 1265 if (mActiveAlerts.containsKey(iface)) { 1266 throw new IllegalStateException("iface " + iface + " already has alert"); 1267 } 1268 1269 try { 1270 // TODO: support alert shared across interfaces 1271 mNetdService.bandwidthSetInterfaceAlert(iface, alertBytes); 1272 mActiveAlerts.put(iface, alertBytes); 1273 } catch (RemoteException | ServiceSpecificException e) { 1274 throw new IllegalStateException(e); 1275 } 1276 } 1277 } 1278 1279 @Override removeInterfaceAlert(String iface)1280 public void removeInterfaceAlert(String iface) { 1281 NetworkStack.checkNetworkStackPermission(mContext); 1282 1283 synchronized (mQuotaLock) { 1284 if (!mActiveAlerts.containsKey(iface)) { 1285 // TODO: eventually consider throwing 1286 return; 1287 } 1288 1289 try { 1290 // TODO: support alert shared across interfaces 1291 mNetdService.bandwidthRemoveInterfaceAlert(iface); 1292 mActiveAlerts.remove(iface); 1293 } catch (RemoteException | ServiceSpecificException e) { 1294 throw new IllegalStateException(e); 1295 } 1296 } 1297 } 1298 1299 @Override setGlobalAlert(long alertBytes)1300 public void setGlobalAlert(long alertBytes) { 1301 NetworkStack.checkNetworkStackPermission(mContext); 1302 1303 try { 1304 mNetdService.bandwidthSetGlobalAlert(alertBytes); 1305 } catch (RemoteException | ServiceSpecificException e) { 1306 throw new IllegalStateException(e); 1307 } 1308 } 1309 setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable)1310 private void setUidOnMeteredNetworkList(int uid, boolean blacklist, boolean enable) { 1311 NetworkStack.checkNetworkStackPermission(mContext); 1312 1313 synchronized (mQuotaLock) { 1314 boolean oldEnable; 1315 SparseBooleanArray quotaList; 1316 synchronized (mRulesLock) { 1317 quotaList = blacklist ? mUidRejectOnMetered : mUidAllowOnMetered; 1318 oldEnable = quotaList.get(uid, false); 1319 } 1320 if (oldEnable == enable) { 1321 // TODO: eventually consider throwing 1322 return; 1323 } 1324 1325 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "inetd bandwidth"); 1326 try { 1327 if (blacklist) { 1328 if (enable) { 1329 mNetdService.bandwidthAddNaughtyApp(uid); 1330 } else { 1331 mNetdService.bandwidthRemoveNaughtyApp(uid); 1332 } 1333 } else { 1334 if (enable) { 1335 mNetdService.bandwidthAddNiceApp(uid); 1336 } else { 1337 mNetdService.bandwidthRemoveNiceApp(uid); 1338 } 1339 } 1340 synchronized (mRulesLock) { 1341 if (enable) { 1342 quotaList.put(uid, true); 1343 } else { 1344 quotaList.delete(uid); 1345 } 1346 } 1347 } catch (RemoteException | ServiceSpecificException e) { 1348 throw new IllegalStateException(e); 1349 } finally { 1350 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1351 } 1352 } 1353 } 1354 1355 @Override setUidMeteredNetworkBlacklist(int uid, boolean enable)1356 public void setUidMeteredNetworkBlacklist(int uid, boolean enable) { 1357 setUidOnMeteredNetworkList(uid, true, enable); 1358 } 1359 1360 @Override setUidMeteredNetworkWhitelist(int uid, boolean enable)1361 public void setUidMeteredNetworkWhitelist(int uid, boolean enable) { 1362 setUidOnMeteredNetworkList(uid, false, enable); 1363 } 1364 1365 @Override setDataSaverModeEnabled(boolean enable)1366 public boolean setDataSaverModeEnabled(boolean enable) { 1367 mContext.enforceCallingOrSelfPermission(NETWORK_SETTINGS, TAG); 1368 1369 if (DBG) Log.d(TAG, "setDataSaverMode: " + enable); 1370 synchronized (mQuotaLock) { 1371 if (mDataSaverMode == enable) { 1372 Log.w(TAG, "setDataSaverMode(): already " + mDataSaverMode); 1373 return true; 1374 } 1375 Trace.traceBegin(Trace.TRACE_TAG_NETWORK, "bandwidthEnableDataSaver"); 1376 try { 1377 final boolean changed = mNetdService.bandwidthEnableDataSaver(enable); 1378 if (changed) { 1379 mDataSaverMode = enable; 1380 } else { 1381 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command silently failed"); 1382 } 1383 return changed; 1384 } catch (RemoteException e) { 1385 Log.w(TAG, "setDataSaverMode(" + enable + "): netd command failed", e); 1386 return false; 1387 } finally { 1388 Trace.traceEnd(Trace.TRACE_TAG_NETWORK); 1389 } 1390 } 1391 } 1392 makeUidRangeParcel(int start, int stop)1393 private static UidRangeParcel makeUidRangeParcel(int start, int stop) { 1394 UidRangeParcel range = new UidRangeParcel(); 1395 range.start = start; 1396 range.stop = stop; 1397 return range; 1398 } 1399 toStableParcels(UidRange[] ranges)1400 private static UidRangeParcel[] toStableParcels(UidRange[] ranges) { 1401 UidRangeParcel[] stableRanges = new UidRangeParcel[ranges.length]; 1402 for (int i = 0; i < ranges.length; i++) { 1403 stableRanges[i] = makeUidRangeParcel(ranges[i].start, ranges[i].stop); 1404 } 1405 return stableRanges; 1406 } 1407 1408 @Override setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges)1409 public void setAllowOnlyVpnForUids(boolean add, UidRange[] uidRanges) 1410 throws ServiceSpecificException { 1411 NetworkStack.checkNetworkStackPermission(mContext); 1412 try { 1413 mNetdService.networkRejectNonSecureVpn(add, toStableParcels(uidRanges)); 1414 } catch (ServiceSpecificException e) { 1415 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" 1416 + ": netd command failed", e); 1417 throw e; 1418 } catch (RemoteException e) { 1419 Log.w(TAG, "setAllowOnlyVpnForUids(" + add + ", " + Arrays.toString(uidRanges) + ")" 1420 + ": netd command failed", e); 1421 throw e.rethrowAsRuntimeException(); 1422 } 1423 } 1424 applyUidCleartextNetworkPolicy(int uid, int policy)1425 private void applyUidCleartextNetworkPolicy(int uid, int policy) { 1426 final int policyValue; 1427 switch (policy) { 1428 case StrictMode.NETWORK_POLICY_ACCEPT: 1429 policyValue = INetd.PENALTY_POLICY_ACCEPT; 1430 break; 1431 case StrictMode.NETWORK_POLICY_LOG: 1432 policyValue = INetd.PENALTY_POLICY_LOG; 1433 break; 1434 case StrictMode.NETWORK_POLICY_REJECT: 1435 policyValue = INetd.PENALTY_POLICY_REJECT; 1436 break; 1437 default: 1438 throw new IllegalArgumentException("Unknown policy " + policy); 1439 } 1440 1441 try { 1442 mNetdService.strictUidCleartextPenalty(uid, policyValue); 1443 mUidCleartextPolicy.put(uid, policy); 1444 } catch (RemoteException | ServiceSpecificException e) { 1445 throw new IllegalStateException(e); 1446 } 1447 } 1448 1449 @Override setUidCleartextNetworkPolicy(int uid, int policy)1450 public void setUidCleartextNetworkPolicy(int uid, int policy) { 1451 if (Binder.getCallingUid() != uid) { 1452 NetworkStack.checkNetworkStackPermission(mContext); 1453 } 1454 1455 synchronized (mQuotaLock) { 1456 final int oldPolicy = mUidCleartextPolicy.get(uid, StrictMode.NETWORK_POLICY_ACCEPT); 1457 if (oldPolicy == policy) { 1458 // This also ensures we won't needlessly apply an ACCEPT policy if we've just 1459 // enabled strict and the underlying iptables rules are empty. 1460 return; 1461 } 1462 1463 // TODO: remove this code after removing prepareNativeDaemon() 1464 if (!mStrictEnabled) { 1465 // Module isn't enabled yet; stash the requested policy away to 1466 // apply later once the daemon is connected. 1467 mUidCleartextPolicy.put(uid, policy); 1468 return; 1469 } 1470 1471 // netd does not keep state on strict mode policies, and cannot replace a non-accept 1472 // policy without deleting it first. Rather than add state to netd, just always send 1473 // it an accept policy when switching between two non-accept policies. 1474 // TODO: consider keeping state in netd so we can simplify this code. 1475 if (oldPolicy != StrictMode.NETWORK_POLICY_ACCEPT && 1476 policy != StrictMode.NETWORK_POLICY_ACCEPT) { 1477 applyUidCleartextNetworkPolicy(uid, StrictMode.NETWORK_POLICY_ACCEPT); 1478 } 1479 1480 applyUidCleartextNetworkPolicy(uid, policy); 1481 } 1482 } 1483 1484 @Override isBandwidthControlEnabled()1485 public boolean isBandwidthControlEnabled() { 1486 return true; 1487 } 1488 1489 private class NetdTetheringStatsProvider extends ITetheringStatsProvider.Stub { 1490 @Override getTetherStats(int how)1491 public NetworkStats getTetherStats(int how) { 1492 // We only need to return per-UID stats. Per-device stats are already counted by 1493 // interface counters. 1494 if (how != STATS_PER_UID) { 1495 return new NetworkStats(SystemClock.elapsedRealtime(), 0); 1496 } 1497 1498 final TetherStatsParcel[] tetherStatsVec; 1499 try { 1500 tetherStatsVec = mNetdService.tetherGetStats(); 1501 } catch (RemoteException | ServiceSpecificException e) { 1502 throw new IllegalStateException("problem parsing tethering stats: ", e); 1503 } 1504 1505 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1506 tetherStatsVec.length); 1507 final NetworkStats.Entry entry = new NetworkStats.Entry(); 1508 1509 for (TetherStatsParcel tetherStats : tetherStatsVec) { 1510 try { 1511 entry.iface = tetherStats.iface; 1512 entry.uid = UID_TETHERING; 1513 entry.set = SET_DEFAULT; 1514 entry.tag = TAG_NONE; 1515 entry.rxBytes = tetherStats.rxBytes; 1516 entry.rxPackets = tetherStats.rxPackets; 1517 entry.txBytes = tetherStats.txBytes; 1518 entry.txPackets = tetherStats.txPackets; 1519 stats.combineValues(entry); 1520 } catch (ArrayIndexOutOfBoundsException e) { 1521 throw new IllegalStateException("invalid tethering stats " + e); 1522 } 1523 } 1524 1525 return stats; 1526 } 1527 1528 @Override setInterfaceQuota(String iface, long quotaBytes)1529 public void setInterfaceQuota(String iface, long quotaBytes) { 1530 // Do nothing. netd is already informed of quota changes in setInterfaceQuota. 1531 } 1532 } 1533 1534 @Override getNetworkStatsTethering(int how)1535 public NetworkStats getNetworkStatsTethering(int how) { 1536 NetworkStack.checkNetworkStackPermission(mContext); 1537 1538 final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 1); 1539 synchronized (mTetheringStatsProviders) { 1540 for (ITetheringStatsProvider provider: mTetheringStatsProviders.keySet()) { 1541 try { 1542 stats.combineAllValues(provider.getTetherStats(how)); 1543 } catch (RemoteException e) { 1544 Log.e(TAG, "Problem reading tethering stats from " + 1545 mTetheringStatsProviders.get(provider) + ": " + e); 1546 } 1547 } 1548 } 1549 return stats; 1550 } 1551 1552 @Override addVpnUidRanges(int netId, UidRange[] ranges)1553 public void addVpnUidRanges(int netId, UidRange[] ranges) { 1554 NetworkStack.checkNetworkStackPermission(mContext); 1555 1556 try { 1557 mNetdService.networkAddUidRanges(netId, toStableParcels(ranges)); 1558 } catch (RemoteException | ServiceSpecificException e) { 1559 throw new IllegalStateException(e); 1560 } 1561 } 1562 1563 @Override removeVpnUidRanges(int netId, UidRange[] ranges)1564 public void removeVpnUidRanges(int netId, UidRange[] ranges) { 1565 NetworkStack.checkNetworkStackPermission(mContext); 1566 try { 1567 mNetdService.networkRemoveUidRanges(netId, toStableParcels(ranges)); 1568 } catch (RemoteException | ServiceSpecificException e) { 1569 throw new IllegalStateException(e); 1570 } 1571 } 1572 1573 @Override setFirewallEnabled(boolean enabled)1574 public void setFirewallEnabled(boolean enabled) { 1575 enforceSystemUid(); 1576 try { 1577 mNetdService.firewallSetFirewallType( 1578 enabled ? INetd.FIREWALL_WHITELIST : INetd.FIREWALL_BLACKLIST); 1579 mFirewallEnabled = enabled; 1580 } catch (RemoteException | ServiceSpecificException e) { 1581 throw new IllegalStateException(e); 1582 } 1583 } 1584 1585 @Override isFirewallEnabled()1586 public boolean isFirewallEnabled() { 1587 enforceSystemUid(); 1588 return mFirewallEnabled; 1589 } 1590 1591 @Override setFirewallInterfaceRule(String iface, boolean allow)1592 public void setFirewallInterfaceRule(String iface, boolean allow) { 1593 enforceSystemUid(); 1594 Preconditions.checkState(mFirewallEnabled); 1595 try { 1596 mNetdService.firewallSetInterfaceRule(iface, 1597 allow ? INetd.FIREWALL_RULE_ALLOW : INetd.FIREWALL_RULE_DENY); 1598 } catch (RemoteException | ServiceSpecificException e) { 1599 throw new IllegalStateException(e); 1600 } 1601 } 1602 closeSocketsForFirewallChainLocked(int chain, String chainName)1603 private void closeSocketsForFirewallChainLocked(int chain, String chainName) { 1604 // UID ranges to close sockets on. 1605 UidRangeParcel[] ranges; 1606 // UID ranges whose sockets we won't touch. 1607 int[] exemptUids; 1608 1609 int numUids = 0; 1610 if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName); 1611 if (getFirewallType(chain) == FIREWALL_WHITELIST) { 1612 // Close all sockets on all non-system UIDs... 1613 ranges = new UidRangeParcel[] { 1614 // TODO: is there a better way of finding all existing users? If so, we could 1615 // specify their ranges here. 1616 makeUidRangeParcel(Process.FIRST_APPLICATION_UID, Integer.MAX_VALUE), 1617 }; 1618 // ... except for the UIDs that have allow rules. 1619 synchronized (mRulesLock) { 1620 final SparseIntArray rules = getUidFirewallRulesLR(chain); 1621 exemptUids = new int[rules.size()]; 1622 for (int i = 0; i < exemptUids.length; i++) { 1623 if (rules.valueAt(i) == FIREWALL_RULE_ALLOW) { 1624 exemptUids[numUids] = rules.keyAt(i); 1625 numUids++; 1626 } 1627 } 1628 } 1629 // Normally, whitelist chains only contain deny rules, so numUids == exemptUids.length. 1630 // But the code does not guarantee this in any way, and at least in one case - if we add 1631 // a UID rule to the firewall, and then disable the firewall - the chains can contain 1632 // the wrong type of rule. In this case, don't close connections that we shouldn't. 1633 // 1634 // TODO: tighten up this code by ensuring we never set the wrong type of rule, and 1635 // fix setFirewallEnabled to grab mQuotaLock and clear rules. 1636 if (numUids != exemptUids.length) { 1637 exemptUids = Arrays.copyOf(exemptUids, numUids); 1638 } 1639 } else { 1640 // Close sockets for every UID that has a deny rule... 1641 synchronized (mRulesLock) { 1642 final SparseIntArray rules = getUidFirewallRulesLR(chain); 1643 ranges = new UidRangeParcel[rules.size()]; 1644 for (int i = 0; i < ranges.length; i++) { 1645 if (rules.valueAt(i) == FIREWALL_RULE_DENY) { 1646 int uid = rules.keyAt(i); 1647 ranges[numUids] = makeUidRangeParcel(uid, uid); 1648 numUids++; 1649 } 1650 } 1651 } 1652 // As above; usually numUids == ranges.length, but not always. 1653 if (numUids != ranges.length) { 1654 ranges = Arrays.copyOf(ranges, numUids); 1655 } 1656 // ... with no exceptions. 1657 exemptUids = new int[0]; 1658 } 1659 1660 try { 1661 mNetdService.socketDestroy(ranges, exemptUids); 1662 } catch(RemoteException | ServiceSpecificException e) { 1663 Slog.e(TAG, "Error closing sockets after enabling chain " + chainName + ": " + e); 1664 } 1665 } 1666 1667 @Override setFirewallChainEnabled(int chain, boolean enable)1668 public void setFirewallChainEnabled(int chain, boolean enable) { 1669 enforceSystemUid(); 1670 synchronized (mQuotaLock) { 1671 synchronized (mRulesLock) { 1672 if (getFirewallChainState(chain) == enable) { 1673 // All is the same, nothing to do. This relies on the fact that netd has child 1674 // chains default detached. 1675 return; 1676 } 1677 setFirewallChainState(chain, enable); 1678 } 1679 1680 final String chainName = getFirewallChainName(chain); 1681 if (chain == FIREWALL_CHAIN_NONE) { 1682 throw new IllegalArgumentException("Bad child chain: " + chainName); 1683 } 1684 1685 try { 1686 mNetdService.firewallEnableChildChain(chain, enable); 1687 } catch (RemoteException | ServiceSpecificException e) { 1688 throw new IllegalStateException(e); 1689 } 1690 1691 // Close any sockets that were opened by the affected UIDs. This has to be done after 1692 // disabling network connectivity, in case they react to the socket close by reopening 1693 // the connection and race with the iptables commands that enable the firewall. All 1694 // whitelist and blacklist chains allow RSTs through. 1695 if (enable) { 1696 closeSocketsForFirewallChainLocked(chain, chainName); 1697 } 1698 } 1699 } 1700 getFirewallChainName(int chain)1701 private String getFirewallChainName(int chain) { 1702 switch (chain) { 1703 case FIREWALL_CHAIN_STANDBY: 1704 return FIREWALL_CHAIN_NAME_STANDBY; 1705 case FIREWALL_CHAIN_DOZABLE: 1706 return FIREWALL_CHAIN_NAME_DOZABLE; 1707 case FIREWALL_CHAIN_POWERSAVE: 1708 return FIREWALL_CHAIN_NAME_POWERSAVE; 1709 default: 1710 throw new IllegalArgumentException("Bad child chain: " + chain); 1711 } 1712 } 1713 getFirewallType(int chain)1714 private int getFirewallType(int chain) { 1715 switch (chain) { 1716 case FIREWALL_CHAIN_STANDBY: 1717 return FIREWALL_BLACKLIST; 1718 case FIREWALL_CHAIN_DOZABLE: 1719 return FIREWALL_WHITELIST; 1720 case FIREWALL_CHAIN_POWERSAVE: 1721 return FIREWALL_WHITELIST; 1722 default: 1723 return isFirewallEnabled() ? FIREWALL_WHITELIST : FIREWALL_BLACKLIST; 1724 } 1725 } 1726 1727 @Override setFirewallUidRules(int chain, int[] uids, int[] rules)1728 public void setFirewallUidRules(int chain, int[] uids, int[] rules) { 1729 enforceSystemUid(); 1730 synchronized (mQuotaLock) { 1731 synchronized (mRulesLock) { 1732 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 1733 SparseIntArray newRules = new SparseIntArray(); 1734 // apply new set of rules 1735 for (int index = uids.length - 1; index >= 0; --index) { 1736 int uid = uids[index]; 1737 int rule = rules[index]; 1738 updateFirewallUidRuleLocked(chain, uid, rule); 1739 newRules.put(uid, rule); 1740 } 1741 // collect the rules to remove. 1742 SparseIntArray rulesToRemove = new SparseIntArray(); 1743 for (int index = uidFirewallRules.size() - 1; index >= 0; --index) { 1744 int uid = uidFirewallRules.keyAt(index); 1745 if (newRules.indexOfKey(uid) < 0) { 1746 rulesToRemove.put(uid, FIREWALL_RULE_DEFAULT); 1747 } 1748 } 1749 // remove dead rules 1750 for (int index = rulesToRemove.size() - 1; index >= 0; --index) { 1751 int uid = rulesToRemove.keyAt(index); 1752 updateFirewallUidRuleLocked(chain, uid, FIREWALL_RULE_DEFAULT); 1753 } 1754 } 1755 try { 1756 switch (chain) { 1757 case FIREWALL_CHAIN_DOZABLE: 1758 mNetdService.firewallReplaceUidChain("fw_dozable", true, uids); 1759 break; 1760 case FIREWALL_CHAIN_STANDBY: 1761 mNetdService.firewallReplaceUidChain("fw_standby", false, uids); 1762 break; 1763 case FIREWALL_CHAIN_POWERSAVE: 1764 mNetdService.firewallReplaceUidChain("fw_powersave", true, uids); 1765 break; 1766 case FIREWALL_CHAIN_NONE: 1767 default: 1768 Slog.d(TAG, "setFirewallUidRules() called on invalid chain: " + chain); 1769 } 1770 } catch (RemoteException e) { 1771 Slog.w(TAG, "Error flushing firewall chain " + chain, e); 1772 } 1773 } 1774 } 1775 1776 @Override setFirewallUidRule(int chain, int uid, int rule)1777 public void setFirewallUidRule(int chain, int uid, int rule) { 1778 enforceSystemUid(); 1779 synchronized (mQuotaLock) { 1780 setFirewallUidRuleLocked(chain, uid, rule); 1781 } 1782 } 1783 setFirewallUidRuleLocked(int chain, int uid, int rule)1784 private void setFirewallUidRuleLocked(int chain, int uid, int rule) { 1785 if (updateFirewallUidRuleLocked(chain, uid, rule)) { 1786 final int ruleType = getFirewallRuleType(chain, rule); 1787 try { 1788 mNetdService.firewallSetUidRule(chain, uid, ruleType); 1789 } catch (RemoteException | ServiceSpecificException e) { 1790 throw new IllegalStateException(e); 1791 } 1792 } 1793 } 1794 1795 // TODO: now that netd supports batching, NMS should not keep these data structures anymore... updateFirewallUidRuleLocked(int chain, int uid, int rule)1796 private boolean updateFirewallUidRuleLocked(int chain, int uid, int rule) { 1797 synchronized (mRulesLock) { 1798 SparseIntArray uidFirewallRules = getUidFirewallRulesLR(chain); 1799 1800 final int oldUidFirewallRule = uidFirewallRules.get(uid, FIREWALL_RULE_DEFAULT); 1801 if (DBG) { 1802 Slog.d(TAG, "oldRule = " + oldUidFirewallRule 1803 + ", newRule=" + rule + " for uid=" + uid + " on chain " + chain); 1804 } 1805 if (oldUidFirewallRule == rule) { 1806 if (DBG) Slog.d(TAG, "!!!!! Skipping change"); 1807 // TODO: eventually consider throwing 1808 return false; 1809 } 1810 1811 String ruleName = getFirewallRuleName(chain, rule); 1812 String oldRuleName = getFirewallRuleName(chain, oldUidFirewallRule); 1813 1814 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { 1815 uidFirewallRules.delete(uid); 1816 } else { 1817 uidFirewallRules.put(uid, rule); 1818 } 1819 return !ruleName.equals(oldRuleName); 1820 } 1821 } 1822 getFirewallRuleName(int chain, int rule)1823 private @NonNull String getFirewallRuleName(int chain, int rule) { 1824 String ruleName; 1825 if (getFirewallType(chain) == FIREWALL_WHITELIST) { 1826 if (rule == FIREWALL_RULE_ALLOW) { 1827 ruleName = "allow"; 1828 } else { 1829 ruleName = "deny"; 1830 } 1831 } else { // Blacklist mode 1832 if (rule == FIREWALL_RULE_DENY) { 1833 ruleName = "deny"; 1834 } else { 1835 ruleName = "allow"; 1836 } 1837 } 1838 return ruleName; 1839 } 1840 1841 @GuardedBy("mRulesLock") getUidFirewallRulesLR(int chain)1842 private @NonNull SparseIntArray getUidFirewallRulesLR(int chain) { 1843 switch (chain) { 1844 case FIREWALL_CHAIN_STANDBY: 1845 return mUidFirewallStandbyRules; 1846 case FIREWALL_CHAIN_DOZABLE: 1847 return mUidFirewallDozableRules; 1848 case FIREWALL_CHAIN_POWERSAVE: 1849 return mUidFirewallPowerSaveRules; 1850 case FIREWALL_CHAIN_NONE: 1851 return mUidFirewallRules; 1852 default: 1853 throw new IllegalArgumentException("Unknown chain:" + chain); 1854 } 1855 } 1856 getFirewallRuleType(int chain, int rule)1857 private int getFirewallRuleType(int chain, int rule) { 1858 if (rule == NetworkPolicyManager.FIREWALL_RULE_DEFAULT) { 1859 return getFirewallType(chain) == FIREWALL_WHITELIST 1860 ? INetd.FIREWALL_RULE_DENY : INetd.FIREWALL_RULE_ALLOW; 1861 } 1862 return rule; 1863 } 1864 enforceSystemUid()1865 private static void enforceSystemUid() { 1866 final int uid = Binder.getCallingUid(); 1867 if (uid != Process.SYSTEM_UID) { 1868 throw new SecurityException("Only available to AID_SYSTEM"); 1869 } 1870 } 1871 1872 @Override registerNetworkActivityListener(INetworkActivityListener listener)1873 public void registerNetworkActivityListener(INetworkActivityListener listener) { 1874 mNetworkActivityListeners.register(listener); 1875 } 1876 1877 @Override unregisterNetworkActivityListener(INetworkActivityListener listener)1878 public void unregisterNetworkActivityListener(INetworkActivityListener listener) { 1879 mNetworkActivityListeners.unregister(listener); 1880 } 1881 1882 @Override isNetworkActive()1883 public boolean isNetworkActive() { 1884 synchronized (mNetworkActivityListeners) { 1885 return mNetworkActive || mActiveIdleTimers.isEmpty(); 1886 } 1887 } 1888 reportNetworkActive()1889 private void reportNetworkActive() { 1890 final int length = mNetworkActivityListeners.beginBroadcast(); 1891 try { 1892 for (int i = 0; i < length; i++) { 1893 try { 1894 mNetworkActivityListeners.getBroadcastItem(i).onNetworkActive(); 1895 } catch (RemoteException | RuntimeException e) { 1896 } 1897 } 1898 } finally { 1899 mNetworkActivityListeners.finishBroadcast(); 1900 } 1901 } 1902 1903 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1904 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1905 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return; 1906 1907 pw.print("mMobileActivityFromRadio="); pw.print(mMobileActivityFromRadio); 1908 pw.print(" mLastPowerStateFromRadio="); pw.println(mLastPowerStateFromRadio); 1909 pw.print("mNetworkActive="); pw.println(mNetworkActive); 1910 1911 synchronized (mQuotaLock) { 1912 pw.print("Active quota ifaces: "); pw.println(mActiveQuotas.toString()); 1913 pw.print("Active alert ifaces: "); pw.println(mActiveAlerts.toString()); 1914 pw.print("Data saver mode: "); pw.println(mDataSaverMode); 1915 synchronized (mRulesLock) { 1916 dumpUidRuleOnQuotaLocked(pw, "blacklist", mUidRejectOnMetered); 1917 dumpUidRuleOnQuotaLocked(pw, "whitelist", mUidAllowOnMetered); 1918 } 1919 } 1920 1921 synchronized (mRulesLock) { 1922 dumpUidFirewallRule(pw, "", mUidFirewallRules); 1923 1924 pw.print("UID firewall standby chain enabled: "); pw.println( 1925 getFirewallChainState(FIREWALL_CHAIN_STANDBY)); 1926 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_STANDBY, mUidFirewallStandbyRules); 1927 1928 pw.print("UID firewall dozable chain enabled: "); pw.println( 1929 getFirewallChainState(FIREWALL_CHAIN_DOZABLE)); 1930 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_DOZABLE, mUidFirewallDozableRules); 1931 1932 pw.println("UID firewall powersave chain enabled: " + 1933 getFirewallChainState(FIREWALL_CHAIN_POWERSAVE)); 1934 dumpUidFirewallRule(pw, FIREWALL_CHAIN_NAME_POWERSAVE, mUidFirewallPowerSaveRules); 1935 } 1936 1937 synchronized (mIdleTimerLock) { 1938 pw.println("Idle timers:"); 1939 for (HashMap.Entry<String, IdleTimerParams> ent : mActiveIdleTimers.entrySet()) { 1940 pw.print(" "); pw.print(ent.getKey()); pw.println(":"); 1941 IdleTimerParams params = ent.getValue(); 1942 pw.print(" timeout="); pw.print(params.timeout); 1943 pw.print(" type="); pw.print(params.type); 1944 pw.print(" networkCount="); pw.println(params.networkCount); 1945 } 1946 } 1947 1948 pw.print("Firewall enabled: "); pw.println(mFirewallEnabled); 1949 pw.print("Netd service status: " ); 1950 if (mNetdService == null) { 1951 pw.println("disconnected"); 1952 } else { 1953 try { 1954 final boolean alive = mNetdService.isAlive(); 1955 pw.println(alive ? "alive": "dead"); 1956 } catch (RemoteException e) { 1957 pw.println("unreachable"); 1958 } 1959 } 1960 } 1961 dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list)1962 private void dumpUidRuleOnQuotaLocked(PrintWriter pw, String name, SparseBooleanArray list) { 1963 pw.print("UID bandwith control "); 1964 pw.print(name); 1965 pw.print(" rule: ["); 1966 final int size = list.size(); 1967 for (int i = 0; i < size; i++) { 1968 pw.print(list.keyAt(i)); 1969 if (i < size - 1) pw.print(","); 1970 } 1971 pw.println("]"); 1972 } 1973 dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules)1974 private void dumpUidFirewallRule(PrintWriter pw, String name, SparseIntArray rules) { 1975 pw.print("UID firewall "); 1976 pw.print(name); 1977 pw.print(" rule: ["); 1978 final int size = rules.size(); 1979 for (int i = 0; i < size; i++) { 1980 pw.print(rules.keyAt(i)); 1981 pw.print(":"); 1982 pw.print(rules.valueAt(i)); 1983 if (i < size - 1) pw.print(","); 1984 } 1985 pw.println("]"); 1986 } 1987 1988 @Override addInterfaceToNetwork(String iface, int netId)1989 public void addInterfaceToNetwork(String iface, int netId) { 1990 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, netId, iface); 1991 } 1992 1993 @Override removeInterfaceFromNetwork(String iface, int netId)1994 public void removeInterfaceFromNetwork(String iface, int netId) { 1995 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, netId, iface); 1996 } 1997 modifyInterfaceInNetwork(boolean add, int netId, String iface)1998 private void modifyInterfaceInNetwork(boolean add, int netId, String iface) { 1999 NetworkStack.checkNetworkStackPermission(mContext); 2000 try { 2001 if (add) { 2002 mNetdService.networkAddInterface(netId, iface); 2003 } else { 2004 mNetdService.networkRemoveInterface(netId, iface); 2005 } 2006 } catch (RemoteException | ServiceSpecificException e) { 2007 throw new IllegalStateException(e); 2008 } 2009 } 2010 2011 @Override addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid)2012 public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) { 2013 NetworkStack.checkNetworkStackPermission(mContext); 2014 2015 final LinkAddress la = routeInfo.getDestinationLinkAddress(); 2016 final String ifName = routeInfo.getInterface(); 2017 final String dst = la.toString(); 2018 final String nextHop; 2019 2020 if (routeInfo.hasGateway()) { 2021 nextHop = routeInfo.getGateway().getHostAddress(); 2022 } else { 2023 nextHop = ""; 2024 } 2025 try { 2026 mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid); 2027 } catch (RemoteException | ServiceSpecificException e) { 2028 throw new IllegalStateException(e); 2029 } 2030 } 2031 2032 @Override setDefaultNetId(int netId)2033 public void setDefaultNetId(int netId) { 2034 NetworkStack.checkNetworkStackPermission(mContext); 2035 2036 try { 2037 mNetdService.networkSetDefault(netId); 2038 } catch (RemoteException | ServiceSpecificException e) { 2039 throw new IllegalStateException(e); 2040 } 2041 } 2042 2043 @Override clearDefaultNetId()2044 public void clearDefaultNetId() { 2045 NetworkStack.checkNetworkStackPermission(mContext); 2046 2047 try { 2048 mNetdService.networkClearDefault(); 2049 } catch (RemoteException | ServiceSpecificException e) { 2050 throw new IllegalStateException(e); 2051 } 2052 } 2053 2054 @Override setNetworkPermission(int netId, int permission)2055 public void setNetworkPermission(int netId, int permission) { 2056 NetworkStack.checkNetworkStackPermission(mContext); 2057 2058 try { 2059 mNetdService.networkSetPermissionForNetwork(netId, permission); 2060 } catch (RemoteException | ServiceSpecificException e) { 2061 throw new IllegalStateException(e); 2062 } 2063 } 2064 2065 @Override allowProtect(int uid)2066 public void allowProtect(int uid) { 2067 NetworkStack.checkNetworkStackPermission(mContext); 2068 2069 try { 2070 mNetdService.networkSetProtectAllow(uid); 2071 } catch (RemoteException | ServiceSpecificException e) { 2072 throw new IllegalStateException(e); 2073 } 2074 } 2075 2076 @Override denyProtect(int uid)2077 public void denyProtect(int uid) { 2078 NetworkStack.checkNetworkStackPermission(mContext); 2079 2080 try { 2081 mNetdService.networkSetProtectDeny(uid); 2082 } catch (RemoteException | ServiceSpecificException e) { 2083 throw new IllegalStateException(e); 2084 } 2085 } 2086 2087 @Override addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes)2088 public void addInterfaceToLocalNetwork(String iface, List<RouteInfo> routes) { 2089 modifyInterfaceInNetwork(MODIFY_OPERATION_ADD, INetd.LOCAL_NET_ID, iface); 2090 // modifyInterfaceInNetwork already check calling permission. 2091 RouteUtils.addRoutesToLocalNetwork(mNetdService, iface, routes); 2092 } 2093 2094 @Override removeInterfaceFromLocalNetwork(String iface)2095 public void removeInterfaceFromLocalNetwork(String iface) { 2096 modifyInterfaceInNetwork(MODIFY_OPERATION_REMOVE, INetd.LOCAL_NET_ID, iface); 2097 } 2098 2099 @Override removeRoutesFromLocalNetwork(List<RouteInfo> routes)2100 public int removeRoutesFromLocalNetwork(List<RouteInfo> routes) { 2101 NetworkStack.checkNetworkStackPermission(mContext); 2102 return RouteUtils.removeRoutesFromLocalNetwork(mNetdService, routes); 2103 } 2104 2105 @Override isNetworkRestricted(int uid)2106 public boolean isNetworkRestricted(int uid) { 2107 mContext.enforceCallingOrSelfPermission(OBSERVE_NETWORK_POLICY, TAG); 2108 return isNetworkRestrictedInternal(uid); 2109 } 2110 isNetworkRestrictedInternal(int uid)2111 private boolean isNetworkRestrictedInternal(int uid) { 2112 synchronized (mRulesLock) { 2113 if (getFirewallChainState(FIREWALL_CHAIN_STANDBY) 2114 && mUidFirewallStandbyRules.get(uid) == FIREWALL_RULE_DENY) { 2115 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of app standby mode"); 2116 return true; 2117 } 2118 if (getFirewallChainState(FIREWALL_CHAIN_DOZABLE) 2119 && mUidFirewallDozableRules.get(uid) != FIREWALL_RULE_ALLOW) { 2120 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of device idle mode"); 2121 return true; 2122 } 2123 if (getFirewallChainState(FIREWALL_CHAIN_POWERSAVE) 2124 && mUidFirewallPowerSaveRules.get(uid) != FIREWALL_RULE_ALLOW) { 2125 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of power saver mode"); 2126 return true; 2127 } 2128 if (mUidRejectOnMetered.get(uid)) { 2129 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of no metered data" 2130 + " in the background"); 2131 return true; 2132 } 2133 if (mDataSaverMode && !mUidAllowOnMetered.get(uid)) { 2134 if (DBG) Slog.d(TAG, "Uid " + uid + " restricted because of data saver mode"); 2135 return true; 2136 } 2137 return false; 2138 } 2139 } 2140 setFirewallChainState(int chain, boolean state)2141 private void setFirewallChainState(int chain, boolean state) { 2142 synchronized (mRulesLock) { 2143 mFirewallChainStates.put(chain, state); 2144 } 2145 } 2146 getFirewallChainState(int chain)2147 private boolean getFirewallChainState(int chain) { 2148 synchronized (mRulesLock) { 2149 return mFirewallChainStates.get(chain); 2150 } 2151 } 2152 2153 @VisibleForTesting 2154 class LocalService extends NetworkManagementInternal { 2155 @Override isNetworkRestrictedForUid(int uid)2156 public boolean isNetworkRestrictedForUid(int uid) { 2157 return isNetworkRestrictedInternal(uid); 2158 } 2159 } 2160 2161 @VisibleForTesting getInjector()2162 Injector getInjector() { 2163 return new Injector(); 2164 } 2165 2166 @VisibleForTesting 2167 class Injector { setDataSaverMode(boolean dataSaverMode)2168 void setDataSaverMode(boolean dataSaverMode) { 2169 mDataSaverMode = dataSaverMode; 2170 } 2171 setFirewallChainState(int chain, boolean state)2172 void setFirewallChainState(int chain, boolean state) { 2173 NetworkManagementService.this.setFirewallChainState(chain, state); 2174 } 2175 setFirewallRule(int chain, int uid, int rule)2176 void setFirewallRule(int chain, int uid, int rule) { 2177 synchronized (mRulesLock) { 2178 getUidFirewallRulesLR(chain).put(uid, rule); 2179 } 2180 } 2181 setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable)2182 void setUidOnMeteredNetworkList(boolean blacklist, int uid, boolean enable) { 2183 synchronized (mRulesLock) { 2184 if (blacklist) { 2185 mUidRejectOnMetered.put(uid, enable); 2186 } else { 2187 mUidAllowOnMetered.put(uid, enable); 2188 } 2189 } 2190 } 2191 reset()2192 void reset() { 2193 synchronized (mRulesLock) { 2194 setDataSaverMode(false); 2195 final int[] chains = { 2196 FIREWALL_CHAIN_DOZABLE, 2197 FIREWALL_CHAIN_STANDBY, 2198 FIREWALL_CHAIN_POWERSAVE 2199 }; 2200 for (int chain : chains) { 2201 setFirewallChainState(chain, false); 2202 getUidFirewallRulesLR(chain).clear(); 2203 } 2204 mUidAllowOnMetered.clear(); 2205 mUidRejectOnMetered.clear(); 2206 } 2207 } 2208 } 2209 } 2210