am 7fb07438: am 674f85af: Merge "Only allow System apps to make VPN exempt routes" into klp-dev
* commit '7fb074389370ac93afc5830189371dc3ec26265c': Only allow System apps to make VPN exempt routes
This commit is contained in:
@@ -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;
|
||||
@@ -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;
|
||||
@@ -412,6 +415,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
|
||||
private SettingsObserver mSettingsObserver;
|
||||
|
||||
private AppOpsManager mAppOpsManager;
|
||||
|
||||
NetworkConfig[] mNetConfigs;
|
||||
int mNetworksDefined;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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
|
||||
*
|
||||
@@ -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);
|
||||
@@ -1588,18 +1657,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,
|
||||
|
||||
Reference in New Issue
Block a user