Loading services/java/com/android/server/ConnectivityService.java +70 −6 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import android.app.AlarmManager; import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; Loading @@ -43,7 +44,9 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; Loading Loading @@ -412,6 +415,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { private SettingsObserver mSettingsObserver; private AppOpsManager mAppOpsManager; NetworkConfig[] mNetConfigs; int mNetworksDefined; Loading Loading @@ -695,6 +700,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { filter = new IntentFilter(); filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION); mContext.registerReceiver(mProvisioningReceiver, filter); mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); } /** Loading Loading @@ -1526,6 +1533,40 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } /** * Check if the address falls into any of currently running VPN's route's. */ private boolean isAddressUnderVpn(InetAddress address) { synchronized (mVpns) { synchronized (mRoutesLock) { int uid = UserHandle.getCallingUserId(); Vpn vpn = mVpns.get(uid); if (vpn == null) { return false; } // Check if an exemption exists for this address. for (LinkAddress destination : mExemptAddresses) { if (!NetworkUtils.addressTypeMatches(address, destination.getAddress())) { continue; } int prefix = destination.getNetworkPrefixLength(); InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix); InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(), prefix); if (addrMasked.equals(destMasked)) { return false; } } // Finally check if the address is covered by the VPN. return vpn.isAddressCovered(address); } } } /** * @deprecated use requestRouteToHostAddress instead * Loading Loading @@ -1562,6 +1603,34 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (mProtectedNetworks.contains(networkType)) { enforceConnectivityInternalPermission(); } boolean exempt; InetAddress addr; try { addr = InetAddress.getByAddress(hostAddress); } catch (UnknownHostException e) { if (DBG) log("requestRouteToHostAddress got " + e.toString()); return false; } // System apps may request routes bypassing the VPN to keep other networks working. if (Binder.getCallingUid() == Process.SYSTEM_UID) { exempt = true; } else { mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName); try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName, 0); exempt = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } catch (NameNotFoundException e) { throw new IllegalArgumentException("Failed to find calling package details", e); } } // Non-exempt routeToHost's can only be added if the host is not covered by the VPN. // This can be either because the VPN's routes do not cover the destination or a // system application added an exemption that covers this destination. if (!exempt && isAddressUnderVpn(addr)) { return false; } if (!ConnectivityManager.isNetworkTypeValid(networkType)) { if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); Loading @@ -1585,18 +1654,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { } final long token = Binder.clearCallingIdentity(); try { InetAddress addr = InetAddress.getByAddress(hostAddress); LinkProperties lp = tracker.getLinkProperties(); boolean ok = addRouteToAddress(lp, addr, EXEMPT); boolean ok = addRouteToAddress(lp, addr, exempt); if (DBG) log("requestRouteToHostAddress ok=" + ok); return ok; } catch (UnknownHostException e) { if (DBG) log("requestRouteToHostAddress got " + e.toString()); } finally { Binder.restoreCallingIdentity(token); } if (DBG) log("requestRouteToHostAddress X bottom return false"); return false; } private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable, Loading services/java/com/android/server/connectivity/Vpn.java +14 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.net.LinkProperties; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.NetworkInfo; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.NetworkInfo.DetailedState; import android.os.Binder; Loading Loading @@ -77,6 +78,7 @@ import com.android.server.net.BaseNetworkObserver; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Inet4Address; import java.net.InetAddress; import java.nio.charset.StandardCharsets; Loading Loading @@ -435,6 +437,18 @@ public class Vpn extends BaseNetworkStateTracker { return tun; } /** * Check if a given address is covered by the VPN's routing rules. */ public boolean isAddressCovered(InetAddress address) { synchronized (Vpn.this) { if (!isRunningLocked()) { return false; } return RouteInfo.selectBestRoute(mConfig.routes, address) != null; } } private boolean isRunningLocked() { return mVpnUsers != null; } Loading Loading
services/java/com/android/server/ConnectivityService.java +70 −6 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL; import static android.net.NetworkPolicyManager.RULE_REJECT_METERED; import android.app.AlarmManager; import android.app.AppOpsManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; Loading @@ -43,7 +44,9 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; Loading Loading @@ -412,6 +415,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { private SettingsObserver mSettingsObserver; private AppOpsManager mAppOpsManager; NetworkConfig[] mNetConfigs; int mNetworksDefined; Loading Loading @@ -695,6 +700,8 @@ public class ConnectivityService extends IConnectivityManager.Stub { filter = new IntentFilter(); filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION); mContext.registerReceiver(mProvisioningReceiver, filter); mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); } /** Loading Loading @@ -1526,6 +1533,40 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } /** * Check if the address falls into any of currently running VPN's route's. */ private boolean isAddressUnderVpn(InetAddress address) { synchronized (mVpns) { synchronized (mRoutesLock) { int uid = UserHandle.getCallingUserId(); Vpn vpn = mVpns.get(uid); if (vpn == null) { return false; } // Check if an exemption exists for this address. for (LinkAddress destination : mExemptAddresses) { if (!NetworkUtils.addressTypeMatches(address, destination.getAddress())) { continue; } int prefix = destination.getNetworkPrefixLength(); InetAddress addrMasked = NetworkUtils.getNetworkPart(address, prefix); InetAddress destMasked = NetworkUtils.getNetworkPart(destination.getAddress(), prefix); if (addrMasked.equals(destMasked)) { return false; } } // Finally check if the address is covered by the VPN. return vpn.isAddressCovered(address); } } } /** * @deprecated use requestRouteToHostAddress instead * Loading Loading @@ -1562,6 +1603,34 @@ public class ConnectivityService extends IConnectivityManager.Stub { if (mProtectedNetworks.contains(networkType)) { enforceConnectivityInternalPermission(); } boolean exempt; InetAddress addr; try { addr = InetAddress.getByAddress(hostAddress); } catch (UnknownHostException e) { if (DBG) log("requestRouteToHostAddress got " + e.toString()); return false; } // System apps may request routes bypassing the VPN to keep other networks working. if (Binder.getCallingUid() == Process.SYSTEM_UID) { exempt = true; } else { mAppOpsManager.checkPackage(Binder.getCallingUid(), packageName); try { ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(packageName, 0); exempt = (info.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } catch (NameNotFoundException e) { throw new IllegalArgumentException("Failed to find calling package details", e); } } // Non-exempt routeToHost's can only be added if the host is not covered by the VPN. // This can be either because the VPN's routes do not cover the destination or a // system application added an exemption that covers this destination. if (!exempt && isAddressUnderVpn(addr)) { return false; } if (!ConnectivityManager.isNetworkTypeValid(networkType)) { if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType); Loading @@ -1585,18 +1654,13 @@ public class ConnectivityService extends IConnectivityManager.Stub { } final long token = Binder.clearCallingIdentity(); try { InetAddress addr = InetAddress.getByAddress(hostAddress); LinkProperties lp = tracker.getLinkProperties(); boolean ok = addRouteToAddress(lp, addr, EXEMPT); boolean ok = addRouteToAddress(lp, addr, exempt); if (DBG) log("requestRouteToHostAddress ok=" + ok); return ok; } catch (UnknownHostException e) { if (DBG) log("requestRouteToHostAddress got " + e.toString()); } finally { Binder.restoreCallingIdentity(token); } if (DBG) log("requestRouteToHostAddress X bottom return false"); return false; } private boolean addRoute(LinkProperties p, RouteInfo r, boolean toDefaultTable, Loading
services/java/com/android/server/connectivity/Vpn.java +14 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ import android.net.LinkProperties; import android.net.LocalSocket; import android.net.LocalSocketAddress; import android.net.NetworkInfo; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.NetworkInfo.DetailedState; import android.os.Binder; Loading Loading @@ -77,6 +78,7 @@ import com.android.server.net.BaseNetworkObserver; import java.io.File; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.Inet4Address; import java.net.InetAddress; import java.nio.charset.StandardCharsets; Loading Loading @@ -435,6 +437,18 @@ public class Vpn extends BaseNetworkStateTracker { return tun; } /** * Check if a given address is covered by the VPN's routing rules. */ public boolean isAddressCovered(InetAddress address) { synchronized (Vpn.this) { if (!isRunningLocked()) { return false; } return RouteInfo.selectBestRoute(mConfig.routes, address) != null; } } private boolean isRunningLocked() { return mVpnUsers != null; } Loading