Check location permission for ConnDiags last.
This CL updates ConnectivityService to check location permissions for ConnectivityDiagnostics callbacks last in the permission check process. This minimizes misattribution of location access for networks that an app is not administering. This CL also updates ConnectivityDiagnosticsManager documentation to clearly state that location permissions are required in order to receive callbacks. Bug: 187310575 Test: atest ConnectivityDiagnosticsManagerTest Test: atest ConnectivityServiceTest Change-Id: I2dbeddac6273e2392ccaeae51a1c7776d6d3da75
This commit is contained in:
@@ -9175,6 +9175,34 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return results;
|
||||
}
|
||||
|
||||
private boolean hasLocationPermission(String packageName, int uid) {
|
||||
// LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
|
||||
// and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
|
||||
// call in a try-catch.
|
||||
try {
|
||||
if (!mLocationPermissionChecker.checkLocationPermission(
|
||||
packageName, null /* featureId */, uid, null /* message */)) {
|
||||
return false;
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean ownsVpnRunningOverNetwork(int uid, Network network) {
|
||||
for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
|
||||
if (virtual.supportsUnderlyingNetworks()
|
||||
&& virtual.networkCapabilities.getOwnerUid() == uid
|
||||
&& CollectionUtils.contains(virtual.declaredUnderlyingNetworks, network)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean checkConnectivityDiagnosticsPermissions(
|
||||
int callbackPid, int callbackUid, NetworkAgentInfo nai, String callbackPackageName) {
|
||||
@@ -9182,29 +9210,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
return true;
|
||||
}
|
||||
|
||||
// LocationPermissionChecker#checkLocationPermission can throw SecurityException if the uid
|
||||
// and package name don't match. Throwing on the CS thread is not acceptable, so wrap the
|
||||
// call in a try-catch.
|
||||
try {
|
||||
if (!mLocationPermissionChecker.checkLocationPermission(
|
||||
callbackPackageName, null /* featureId */, callbackUid, null /* message */)) {
|
||||
return false;
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
// Administrator UIDs also contains the Owner UID
|
||||
final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
|
||||
if (!CollectionUtils.contains(administratorUids, callbackUid)
|
||||
&& !ownsVpnRunningOverNetwork(callbackUid, nai.network)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (NetworkAgentInfo virtual : mNetworkAgentInfos) {
|
||||
if (virtual.supportsUnderlyingNetworks()
|
||||
&& virtual.networkCapabilities.getOwnerUid() == callbackUid
|
||||
&& CollectionUtils.contains(virtual.declaredUnderlyingNetworks, nai.network)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Administrator UIDs also contains the Owner UID
|
||||
final int[] administratorUids = nai.networkCapabilities.getAdministratorUids();
|
||||
return CollectionUtils.contains(administratorUids, callbackUid);
|
||||
return hasLocationPermission(callbackPackageName, callbackUid);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user