Merge "Set attributionTag for noteOp(WRITE_SETTINGS) calls" am: da8697a48b

Change-Id: I3ddd8954cf8443f549f7965cc43f2600bf92a80b
This commit is contained in:
Philip P. Moltmann
2020-04-22 15:09:28 +00:00
committed by Automerger Merge Worker
5 changed files with 84 additions and 28 deletions

View File

@@ -2044,12 +2044,21 @@ public class ConnectivityManager {
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
checkLegacyRoutingApiAccess();
try {
return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress());
return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress(),
mContext.getOpPackageName(), getAttributionTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
* @return the context's attribution tag
*/
// TODO: Remove method and replace with direct call once R code is pushed to AOSP
private @Nullable String getAttributionTag() {
return null;
}
/**
* Returns the value of the setting for background data usage. If false,
* applications should not use the network if the application is not in the
@@ -2240,14 +2249,30 @@ public class ConnectivityManager {
* services.jar, possibly in com.android.server.net. */
/** {@hide} */
public static final void enforceChangePermission(Context context) {
public static final void enforceChangePermission(Context context,
String callingPkg, String callingAttributionTag) {
int uid = Binder.getCallingUid();
Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings
.getPackageNameForUid(context, uid), true /* throwException */);
checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg,
callingAttributionTag, true /* throwException */);
}
/**
* Check if the package is a allowed to change the network state. This also accounts that such
* an access happened.
*
* @return {@code true} iff the package is allowed to change the network state.
*/
// TODO: Remove method and replace with direct call once R code is pushed to AOSP
private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context,
int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag,
boolean throwException) {
return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage,
throwException);
}
/** {@hide} */
public static final void enforceTetherChangePermission(Context context, String callingPkg) {
public static final void enforceTetherChangePermission(Context context, String callingPkg,
String callingAttributionTag) {
Preconditions.checkNotNull(context, "Context cannot be null");
Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null");
@@ -2261,11 +2286,25 @@ public class ConnectivityManager {
int uid = Binder.getCallingUid();
// If callingPkg's uid is not same as Binder.getCallingUid(),
// AppOpsService throws SecurityException.
Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPkg,
true /* throwException */);
checkAndNoteWriteSettingsOperation(context, uid, callingPkg,
callingAttributionTag, true /* throwException */);
}
}
/**
* Check if the package is a allowed to write settings. This also accounts that such an access
* happened.
*
* @return {@code true} iff the package is allowed to write settings.
*/
// TODO: Remove method and replace with direct call once R code is pushed to AOSP
private static boolean checkAndNoteWriteSettingsOperation(@NonNull Context context, int uid,
@NonNull String callingPackage, @Nullable String callingAttributionTag,
boolean throwException) {
return Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPackage,
throwException);
}
/**
* @deprecated - use getSystemService. This is a kludge to support static access in certain
* situations where a Context pointer is unavailable.
@@ -3706,7 +3745,8 @@ public class ConnectivityManager {
need, messenger, binder, callingPackageName);
} else {
request = mService.requestNetwork(
need, messenger, timeoutMs, binder, legacyType, callingPackageName);
need, messenger, timeoutMs, binder, legacyType, callingPackageName,
getAttributionTag());
}
if (request != null) {
sCallbacks.put(request, callback);
@@ -3982,7 +4022,8 @@ public class ConnectivityManager {
checkPendingIntentNotNull(operation);
try {
mService.pendingRequestForNetwork(
request.networkCapabilities, operation, mContext.getOpPackageName());
request.networkCapabilities, operation, mContext.getOpPackageName(),
getAttributionTag());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
} catch (ServiceSpecificException e) {

View File

@@ -77,7 +77,8 @@ interface IConnectivityManager
NetworkQuotaInfo getActiveNetworkQuotaInfo();
boolean isActiveNetworkMetered();
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress,
String callingPackageName, String callingAttributionTag);
@UnsupportedAppUsage(maxTargetSdk = 29,
publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative")
@@ -168,10 +169,10 @@ interface IConnectivityManager
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
String callingPackageName);
String callingPackageName, String callingAttributionTag);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation, String callingPackageName);
in PendingIntent operation, String callingPackageName, String callingAttributionTag);
void releasePendingNetworkRequest(in PendingIntent operation);

View File

@@ -1819,11 +1819,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
* @return {@code true} on success, {@code false} on failure
*/
@Override
public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) {
public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
String callingPackageName, String callingAttributionTag) {
if (disallowedBecauseSystemCaller()) {
return false;
}
enforceChangePermission();
enforceChangePermission(callingPackageName, callingAttributionTag);
if (mProtectedNetworks.contains(networkType)) {
enforceConnectivityRestrictedNetworksPermission();
}
@@ -2077,8 +2078,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
"ConnectivityService");
}
private void enforceChangePermission() {
ConnectivityManager.enforceChangePermission(mContext);
private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag);
}
private void enforceSettingsPermission() {
@@ -5430,7 +5431,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
@NonNull String callingPackageName) {
@NonNull String callingPackageName, @Nullable String callingAttributionTag) {
if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
throw new SecurityException("Insufficient permissions to specify legacy type");
@@ -5448,7 +5449,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceAccessPermission();
} else {
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
callingAttributionTag);
// TODO: this is incorrect. We mark the request as metered or not depending on the state
// of the app when the request is filed, but we never change the request if the app
// changes network state. http://b/29964605
@@ -5483,11 +5485,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
return networkRequest;
}
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) {
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
String callingPackageName, String callingAttributionTag) {
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
enforceConnectivityRestrictedNetworksPermission();
} else {
enforceChangePermission();
enforceChangePermission(callingPackageName, callingAttributionTag);
}
}
@@ -5538,11 +5541,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities,
PendingIntent operation, @NonNull String callingPackageName) {
PendingIntent operation, @NonNull String callingPackageName,
@Nullable String callingAttributionTag) {
Objects.requireNonNull(operation, "PendingIntent cannot be null.");
final int callingUid = Binder.getCallingUid();
networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
callingAttributionTag);
enforceMeteredApnPolicy(networkCapabilities);
ensureRequestableCapabilities(networkCapabilities);
ensureSufficientPermissionsForRequest(networkCapabilities,

View File

@@ -36,6 +36,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
@@ -213,7 +214,7 @@ public class ConnectivityManagerTest {
// register callback
when(mService.requestNetwork(
any(), captor.capture(), anyInt(), any(), anyInt(), any()))
any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
.thenReturn(request);
manager.requestNetwork(request, callback, handler);
@@ -242,7 +243,7 @@ public class ConnectivityManagerTest {
// register callback
when(mService.requestNetwork(
any(), captor.capture(), anyInt(), any(), anyInt(), any()))
any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
.thenReturn(req1);
manager.requestNetwork(req1, callback, handler);
@@ -261,7 +262,7 @@ public class ConnectivityManagerTest {
// callback can be registered again
when(mService.requestNetwork(
any(), captor.capture(), anyInt(), any(), anyInt(), any()))
any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
.thenReturn(req2);
manager.requestNetwork(req2, callback, handler);
@@ -285,8 +286,8 @@ public class ConnectivityManagerTest {
info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
when(mCtx.getApplicationInfo()).thenReturn(info);
when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any()))
.thenReturn(request);
when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any(),
nullable(String.class))).thenReturn(request);
Handler handler = new Handler(Looper.getMainLooper());
manager.requestNetwork(request, callback, handler);

View File

@@ -3049,6 +3049,13 @@ public class ConnectivityServiceTest {
assertNoCallbacks(cEmpty1, cEmpty2, cEmpty3, cEmpty4, cFoo, cBar);
}
/**
* @return the context's attribution tag
*/
private String getAttributionTag() {
return null;
}
@Test
public void testInvalidNetworkSpecifier() {
assertThrows(IllegalArgumentException.class, () -> {
@@ -3061,7 +3068,8 @@ public class ConnectivityServiceTest {
networkCapabilities.addTransportType(TRANSPORT_WIFI)
.setNetworkSpecifier(new MatchAllNetworkSpecifier());
mService.requestNetwork(networkCapabilities, null, 0, null,
ConnectivityManager.TYPE_WIFI, mContext.getPackageName());
ConnectivityManager.TYPE_WIFI, mContext.getPackageName(),
getAttributionTag());
});
class NonParcelableSpecifier extends NetworkSpecifier {