Implement Settings#checkAndNoteChangeNetworkStateOperation on CS

Connectivity is becoming a mainline module in S and
ConnectivityManager#enforceChangePermission is using
Settings#checkAndNoteChangeNetworkStateOperation for performing a
strict and comprehensive check of whether a calling package is
allowed to change the state of network. However, Mainline modules
are not allowed to use non-formal APIs, fortunately CS is the
only caller of this ConnectivityManager#enforceChangePermission.
Thus, implement the Settings API on ConnectivityService and remove
the ConnectivityManager#enforceChangePermission and
Settings#checkAndNoteChangeNetworkStateOperation.

Bug: 178565313
Test: atest FrameworksNetTests
Change-Id: I6f03398c1735b89470ad5bdbe3a036929daeb53c
This commit is contained in:
paulhu
2021-02-22 15:40:43 +08:00
committed by Paul Hu
parent 98580a2e82
commit 694c8a9935
3 changed files with 38 additions and 50 deletions

View File

@@ -16566,30 +16566,6 @@ public final class Settings {
AppOpsManager.OP_WRITE_SETTINGS, PM_WRITE_SETTINGS, true); AppOpsManager.OP_WRITE_SETTINGS, PM_WRITE_SETTINGS, true);
} }
/**
* Performs a strict and comprehensive check of whether a calling package is allowed to
* change the state of network, as the condition differs for pre-M, M+, and
* privileged/preinstalled apps. The caller is expected to have either the
* CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
* permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
* can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
* permission and cannot be revoked. See http://b/23597341
*
* Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
* of this app will be updated to the current time.
* @hide
*/
public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid,
String callingPackage, String callingAttributionTag, boolean throwException) {
if (context.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
== PackageManager.PERMISSION_GRANTED) {
return true;
}
return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid,
callingPackage, callingAttributionTag, throwException,
AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, true);
}
/** /**
* Performs a strict and comprehensive check of whether a calling package is allowed to * Performs a strict and comprehensive check of whether a calling package is allowed to
* draw on top of other apps, as the conditions differs for pre-M, M+, and * draw on top of other apps, as the conditions differs for pre-M, M+, and

View File

@@ -2297,31 +2297,6 @@ public class ConnectivityManager {
} }
} }
/* 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 void enforceChangePermission(Context context,
String callingPkg, String callingAttributionTag) {
int uid = Binder.getCallingUid();
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,
callingAttributionTag, throwException);
}
/** /**
* Check if the package is a allowed to write settings. This also accounts that such an access * Check if the package is a allowed to write settings. This also accounts that such an access
* happened. * happened.

View File

@@ -2189,8 +2189,45 @@ public class ConnectivityService extends IConnectivityManager.Stub
"ConnectivityService"); "ConnectivityService");
} }
/**
* Performs a strict and comprehensive check of whether a calling package is allowed to
* change the state of network, as the condition differs for pre-M, M+, and
* privileged/preinstalled apps. The caller is expected to have either the
* CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
* permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
* can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
* permission and cannot be revoked. See http://b/23597341
*
* Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
* of this app will be updated to the current time.
*/
private void enforceChangePermission(String callingPkg, String callingAttributionTag) { private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag); if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
== PackageManager.PERMISSION_GRANTED) {
return;
}
if (callingPkg == null) {
throw new SecurityException("Calling package name is null.");
}
final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
final int uid = mDeps.getCallingUid();
final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
callingPkg, callingAttributionTag, null /* message */);
if (mode == AppOpsManager.MODE_ALLOWED) {
return;
}
if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
return;
}
throw new SecurityException(callingPkg + " was not granted either of these permissions:"
+ android.Manifest.permission.CHANGE_NETWORK_STATE + ","
+ android.Manifest.permission.WRITE_SETTINGS + ".");
} }
private void enforceSettingsPermission() { private void enforceSettingsPermission() {