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

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

View File

@@ -2043,12 +2043,21 @@ public class ConnectivityManager {
public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) { public boolean requestRouteToHostAddress(int networkType, InetAddress hostAddress) {
checkLegacyRoutingApiAccess(); checkLegacyRoutingApiAccess();
try { try {
return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress()); return mService.requestRouteToHostAddress(networkType, hostAddress.getAddress(),
mContext.getOpPackageName(), getAttributionTag());
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); 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, * 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 * applications should not use the network if the application is not in the
@@ -2239,14 +2248,30 @@ public class ConnectivityManager {
* services.jar, possibly in com.android.server.net. */ * services.jar, possibly in com.android.server.net. */
/** {@hide} */ /** {@hide} */
public static final void enforceChangePermission(Context context) { public static final void enforceChangePermission(Context context,
String callingPkg, String callingAttributionTag) {
int uid = Binder.getCallingUid(); int uid = Binder.getCallingUid();
Settings.checkAndNoteChangeNetworkStateOperation(context, uid, Settings checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg,
.getPackageNameForUid(context, uid), true /* throwException */); 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} */ /** {@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(context, "Context cannot be null");
Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null"); Preconditions.checkNotNull(callingPkg, "callingPkg cannot be null");
@@ -2260,11 +2285,25 @@ public class ConnectivityManager {
int uid = Binder.getCallingUid(); int uid = Binder.getCallingUid();
// If callingPkg's uid is not same as Binder.getCallingUid(), // If callingPkg's uid is not same as Binder.getCallingUid(),
// AppOpsService throws SecurityException. // AppOpsService throws SecurityException.
Settings.checkAndNoteWriteSettingsOperation(context, uid, callingPkg, checkAndNoteWriteSettingsOperation(context, uid, callingPkg,
true /* throwException */); 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 * @deprecated - use getSystemService. This is a kludge to support static access in certain
* situations where a Context pointer is unavailable. * situations where a Context pointer is unavailable.
@@ -3705,7 +3744,8 @@ public class ConnectivityManager {
need, messenger, binder, callingPackageName); need, messenger, binder, callingPackageName);
} else { } else {
request = mService.requestNetwork( request = mService.requestNetwork(
need, messenger, timeoutMs, binder, legacyType, callingPackageName); need, messenger, timeoutMs, binder, legacyType, callingPackageName,
getAttributionTag());
} }
if (request != null) { if (request != null) {
sCallbacks.put(request, callback); sCallbacks.put(request, callback);
@@ -3981,7 +4021,8 @@ public class ConnectivityManager {
checkPendingIntentNotNull(operation); checkPendingIntentNotNull(operation);
try { try {
mService.pendingRequestForNetwork( mService.pendingRequestForNetwork(
request.networkCapabilities, operation, mContext.getOpPackageName()); request.networkCapabilities, operation, mContext.getOpPackageName(),
getAttributionTag());
} catch (RemoteException e) { } catch (RemoteException e) {
throw e.rethrowFromSystemServer(); throw e.rethrowFromSystemServer();
} catch (ServiceSpecificException e) { } catch (ServiceSpecificException e) {

View File

@@ -77,7 +77,8 @@ interface IConnectivityManager
NetworkQuotaInfo getActiveNetworkQuotaInfo(); NetworkQuotaInfo getActiveNetworkQuotaInfo();
boolean isActiveNetworkMetered(); boolean isActiveNetworkMetered();
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress); boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress,
String callingPackageName, String callingAttributionTag);
@UnsupportedAppUsage(maxTargetSdk = 29, @UnsupportedAppUsage(maxTargetSdk = 29,
publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative") publicAlternatives = "Use {@code TetheringManager#getLastTetherError} as alternative")
@@ -168,10 +169,10 @@ interface IConnectivityManager
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities, NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
in Messenger messenger, int timeoutSec, in IBinder binder, int legacy, in Messenger messenger, int timeoutSec, in IBinder binder, int legacy,
String callingPackageName); String callingPackageName, String callingAttributionTag);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities, NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation, String callingPackageName); in PendingIntent operation, String callingPackageName, String callingAttributionTag);
void releasePendingNetworkRequest(in PendingIntent operation); 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 * @return {@code true} on success, {@code false} on failure
*/ */
@Override @Override
public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress) { public boolean requestRouteToHostAddress(int networkType, byte[] hostAddress,
String callingPackageName, String callingAttributionTag) {
if (disallowedBecauseSystemCaller()) { if (disallowedBecauseSystemCaller()) {
return false; return false;
} }
enforceChangePermission(); enforceChangePermission(callingPackageName, callingAttributionTag);
if (mProtectedNetworks.contains(networkType)) { if (mProtectedNetworks.contains(networkType)) {
enforceConnectivityRestrictedNetworksPermission(); enforceConnectivityRestrictedNetworksPermission();
} }
@@ -2077,8 +2078,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
"ConnectivityService"); "ConnectivityService");
} }
private void enforceChangePermission() { private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
ConnectivityManager.enforceChangePermission(mContext); ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag);
} }
private void enforceSettingsPermission() { private void enforceSettingsPermission() {
@@ -5439,7 +5440,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override @Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities, public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Messenger messenger, int timeoutMs, IBinder binder, int legacyType, Messenger messenger, int timeoutMs, IBinder binder, int legacyType,
@NonNull String callingPackageName) { @NonNull String callingPackageName, @Nullable String callingAttributionTag) {
if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) { if (legacyType != TYPE_NONE && !checkNetworkStackPermission()) {
if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) { if (checkUnsupportedStartingFrom(Build.VERSION_CODES.M, callingPackageName)) {
throw new SecurityException("Insufficient permissions to specify legacy type"); throw new SecurityException("Insufficient permissions to specify legacy type");
@@ -5457,7 +5458,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceAccessPermission(); enforceAccessPermission();
} else { } else {
networkCapabilities = new NetworkCapabilities(networkCapabilities); 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 // 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 // of the app when the request is filed, but we never change the request if the app
// changes network state. http://b/29964605 // changes network state. http://b/29964605
@@ -5492,11 +5494,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
return networkRequest; return networkRequest;
} }
private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities) { private void enforceNetworkRequestPermissions(NetworkCapabilities networkCapabilities,
String callingPackageName, String callingAttributionTag) {
if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) { if (networkCapabilities.hasCapability(NET_CAPABILITY_NOT_RESTRICTED) == false) {
enforceConnectivityRestrictedNetworksPermission(); enforceConnectivityRestrictedNetworksPermission();
} else { } else {
enforceChangePermission(); enforceChangePermission(callingPackageName, callingAttributionTag);
} }
} }
@@ -5547,11 +5550,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override @Override
public NetworkRequest pendingRequestForNetwork(NetworkCapabilities networkCapabilities, 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."); Objects.requireNonNull(operation, "PendingIntent cannot be null.");
final int callingUid = Binder.getCallingUid(); final int callingUid = Binder.getCallingUid();
networkCapabilities = new NetworkCapabilities(networkCapabilities); networkCapabilities = new NetworkCapabilities(networkCapabilities);
enforceNetworkRequestPermissions(networkCapabilities); enforceNetworkRequestPermissions(networkCapabilities, callingPackageName,
callingAttributionTag);
enforceMeteredApnPolicy(networkCapabilities); enforceMeteredApnPolicy(networkCapabilities);
ensureRequestableCapabilities(networkCapabilities); ensureRequestableCapabilities(networkCapabilities);
ensureSufficientPermissionsForRequest(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.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.any; import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
@@ -213,7 +214,7 @@ public class ConnectivityManagerTest {
// register callback // register callback
when(mService.requestNetwork( when(mService.requestNetwork(
any(), captor.capture(), anyInt(), any(), anyInt(), any())) any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
.thenReturn(request); .thenReturn(request);
manager.requestNetwork(request, callback, handler); manager.requestNetwork(request, callback, handler);
@@ -242,7 +243,7 @@ public class ConnectivityManagerTest {
// register callback // register callback
when(mService.requestNetwork( when(mService.requestNetwork(
any(), captor.capture(), anyInt(), any(), anyInt(), any())) any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
.thenReturn(req1); .thenReturn(req1);
manager.requestNetwork(req1, callback, handler); manager.requestNetwork(req1, callback, handler);
@@ -261,7 +262,7 @@ public class ConnectivityManagerTest {
// callback can be registered again // callback can be registered again
when(mService.requestNetwork( when(mService.requestNetwork(
any(), captor.capture(), anyInt(), any(), anyInt(), any())) any(), captor.capture(), anyInt(), any(), anyInt(), any(), nullable(String.class)))
.thenReturn(req2); .thenReturn(req2);
manager.requestNetwork(req2, callback, handler); manager.requestNetwork(req2, callback, handler);
@@ -285,8 +286,8 @@ public class ConnectivityManagerTest {
info.targetSdkVersion = VERSION_CODES.N_MR1 + 1; info.targetSdkVersion = VERSION_CODES.N_MR1 + 1;
when(mCtx.getApplicationInfo()).thenReturn(info); when(mCtx.getApplicationInfo()).thenReturn(info);
when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any())) when(mService.requestNetwork(any(), any(), anyInt(), any(), anyInt(), any(),
.thenReturn(request); nullable(String.class))).thenReturn(request);
Handler handler = new Handler(Looper.getMainLooper()); Handler handler = new Handler(Looper.getMainLooper());
manager.requestNetwork(request, callback, handler); manager.requestNetwork(request, callback, handler);

View File

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