Merge "Fix READ/WRITE operation access issues on Restricted appOps." into udc-dev am: bc17b89638
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/27214657
Change-Id: I2a41d8701a4b5075b10152b740cdb602493345cd
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/core/java/android/app/AppOpInfo.java b/core/java/android/app/AppOpInfo.java
index 5268ec4..a0f0cca 100644
--- a/core/java/android/app/AppOpInfo.java
+++ b/core/java/android/app/AppOpInfo.java
@@ -88,7 +88,7 @@
/**
* This specifies whether each option is only allowed to be read
- * by apps with manage appops permission.
+ * by apps with privileged appops permission.
*/
public final boolean restrictRead;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index ccd83f7..2ec5453 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -2985,7 +2985,7 @@
}
/**
- * Retrieve whether the op can be read by apps with manage appops permission.
+ * Retrieve whether the op can be read by apps with privileged appops permission.
* @hide
*/
public static boolean opRestrictsRead(int op) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 33655f7..e2388e2 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -1430,16 +1430,26 @@
private ArrayList<AppOpsManager.OpEntry> collectOps(Ops pkgOps, int[] ops) {
ArrayList<AppOpsManager.OpEntry> resOps = null;
+ boolean shouldReturnRestrictedAppOps = mContext.checkPermission(
+ Manifest.permission.GET_APP_OPS_STATS,
+ Binder.getCallingPid(), Binder.getCallingUid())
+ == PackageManager.PERMISSION_GRANTED;
if (ops == null) {
resOps = new ArrayList<>();
- for (int j=0; j<pkgOps.size(); j++) {
+ for (int j = 0; j < pkgOps.size(); j++) {
Op curOp = pkgOps.valueAt(j);
+ if (opRestrictsRead(curOp.op) && !shouldReturnRestrictedAppOps) {
+ continue;
+ }
resOps.add(getOpEntryForResult(curOp));
}
} else {
- for (int j=0; j<ops.length; j++) {
+ for (int j = 0; j < ops.length; j++) {
Op curOp = pkgOps.get(ops[j]);
if (curOp != null) {
+ if (opRestrictsRead(curOp.op) && !shouldReturnRestrictedAppOps) {
+ continue;
+ }
if (resOps == null) {
resOps = new ArrayList<>();
}
@@ -3615,10 +3625,21 @@
private void verifyIncomingOp(int op) {
if (op >= 0 && op < AppOpsManager._NUM_OP) {
- // Enforce manage appops permission if it's a restricted read op.
+ // Enforce privileged appops permission if it's a restricted read op.
if (opRestrictsRead(op)) {
- mContext.enforcePermission(Manifest.permission.MANAGE_APPOPS,
- Binder.getCallingPid(), Binder.getCallingUid(), "verifyIncomingOp");
+ if (!(mContext.checkPermission(Manifest.permission.MANAGE_APPOPS,
+ Binder.getCallingPid(), Binder.getCallingUid())
+ == PackageManager.PERMISSION_GRANTED || mContext.checkPermission(
+ Manifest.permission.GET_APP_OPS_STATS,
+ Binder.getCallingPid(), Binder.getCallingUid())
+ == PackageManager.PERMISSION_GRANTED || mContext.checkPermission(
+ Manifest.permission.MANAGE_APP_OPS_MODES,
+ Binder.getCallingPid(), Binder.getCallingUid())
+ == PackageManager.PERMISSION_GRANTED)) {
+ throw new SecurityException("verifyIncomingOp: uid " + Binder.getCallingUid()
+ + " does not have any of {MANAGE_APPOPS, GET_APP_OPS_STATS, "
+ + "MANAGE_APP_OPS_MODES}");
+ }
}
return;
}