Restrict access to background networks to CHANGE_NETWORK_STATE.
am: b8d9f52adb
Change-Id: Iaf4ccd24298f680cab39bf9b87604eb16bc53aa5
This commit is contained in:
@@ -1825,6 +1825,16 @@ public class ConnectivityManager {
|
|||||||
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: These permissions checks don't belong in client-side code. Move them to
|
||||||
|
* services.jar, possibly in com.android.server.net. */
|
||||||
|
|
||||||
|
/** {@hide} */
|
||||||
|
public static final boolean checkChangePermission(Context context) {
|
||||||
|
int uid = Binder.getCallingUid();
|
||||||
|
return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
|
||||||
|
.getPackageNameForUid(context, uid), false /* throwException */);
|
||||||
|
}
|
||||||
|
|
||||||
/** {@hide} */
|
/** {@hide} */
|
||||||
public static final void enforceChangePermission(Context context) {
|
public static final void enforceChangePermission(Context context) {
|
||||||
int uid = Binder.getCallingUid();
|
int uid = Binder.getCallingUid();
|
||||||
|
|||||||
@@ -4330,8 +4330,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
enforceAccessPermission();
|
enforceAccessPermission();
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkRequest networkRequest = new NetworkRequest(
|
NetworkCapabilities nc = new NetworkCapabilities(networkCapabilities);
|
||||||
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(),
|
if (!ConnectivityManager.checkChangePermission(mContext)) {
|
||||||
|
// Apps without the CHANGE_NETWORK_STATE permission can't use background networks, so
|
||||||
|
// make all their listens include NET_CAPABILITY_FOREGROUND. That way, they will get
|
||||||
|
// onLost and onAvailable callbacks when networks move in and out of the background.
|
||||||
|
// There is no need to do this for requests because an app without CHANGE_NETWORK_STATE
|
||||||
|
// can't request networks.
|
||||||
|
nc.addCapability(NET_CAPABILITY_FOREGROUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
|
||||||
NetworkRequest.Type.LISTEN);
|
NetworkRequest.Type.LISTEN);
|
||||||
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
|
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder);
|
||||||
if (VDBG) log("listenForNetwork for " + nri);
|
if (VDBG) log("listenForNetwork for " + nri);
|
||||||
@@ -4646,6 +4655,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
mNumDnsEntries = last;
|
mNumDnsEntries = last;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getNetworkPermission(NetworkCapabilities nc) {
|
||||||
|
// TODO: make these permission strings AIDL constants instead.
|
||||||
|
if (!nc.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
|
||||||
|
return NetworkManagementService.PERMISSION_SYSTEM;
|
||||||
|
}
|
||||||
|
if (!nc.hasCapability(NET_CAPABILITY_FOREGROUND)) {
|
||||||
|
return NetworkManagementService.PERMISSION_NETWORK;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the NetworkCapabilities for {@code networkAgent} to {@code networkCapabilities}
|
* Update the NetworkCapabilities for {@code networkAgent} to {@code networkCapabilities}
|
||||||
* augmented with any stateful capabilities implied from {@code networkAgent}
|
* augmented with any stateful capabilities implied from {@code networkAgent}
|
||||||
@@ -4684,12 +4704,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
|
|
||||||
if (Objects.equals(nai.networkCapabilities, networkCapabilities)) return;
|
if (Objects.equals(nai.networkCapabilities, networkCapabilities)) return;
|
||||||
|
|
||||||
if (nai.networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) !=
|
final String oldPermission = getNetworkPermission(nai.networkCapabilities);
|
||||||
networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED)) {
|
final String newPermission = getNetworkPermission(networkCapabilities);
|
||||||
|
if (!Objects.equals(oldPermission, newPermission) && nai.created && !nai.isVPN()) {
|
||||||
try {
|
try {
|
||||||
mNetd.setNetworkPermission(nai.network.netId,
|
mNetd.setNetworkPermission(nai.network.netId, newPermission);
|
||||||
networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) ?
|
|
||||||
null : NetworkManagementService.PERMISSION_SYSTEM);
|
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
loge("Exception in setNetworkPermission: " + e);
|
loge("Exception in setNetworkPermission: " + e);
|
||||||
}
|
}
|
||||||
@@ -5259,9 +5278,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
!networkAgent.networkMisc.allowBypass));
|
!networkAgent.networkMisc.allowBypass));
|
||||||
} else {
|
} else {
|
||||||
mNetd.createPhysicalNetwork(networkAgent.network.netId,
|
mNetd.createPhysicalNetwork(networkAgent.network.netId,
|
||||||
networkAgent.networkCapabilities.hasCapability(
|
getNetworkPermission(networkAgent.networkCapabilities));
|
||||||
NET_CAPABILITY_NOT_RESTRICTED) ?
|
|
||||||
null : NetworkManagementService.PERMISSION_SYSTEM);
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
loge("Error creating network " + networkAgent.network.netId + ": "
|
loge("Error creating network " + networkAgent.network.netId + ": "
|
||||||
|
|||||||
Reference in New Issue
Block a user