summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@android.com> 2019-04-28 12:52:37 -0600
committer Jeff Sharkey <jsharkey@android.com> 2019-04-28 12:52:43 -0600
commitc4bf993c512b81ad4fa0a1b4e3bf885920a9d374 (patch)
treeffe21591dc4df8641ba8d2fbd4d485d9528478c0
parentbf70e9ccdfb1070e07fefa11af86ed0f98b945c9 (diff)
Block write access to media for non-owners.
The new security model in Q requires that apps can't directly write to media they don't own. They can still gain write access using RecoverableSecurityException. Bug: 130367350 Test: atest --test-mapping packages/providers/MediaProvider Change-Id: I1fea108aeee63caa2579187be73ba2f27f2bb932
-rw-r--r--core/java/android/os/storage/StorageManager.java46
1 files changed, 34 insertions, 12 deletions
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index 080ff7301ed2..b9fc186e1c1e 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -18,6 +18,7 @@ package android.os.storage;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
+import static android.app.AppOpsManager.OP_LEGACY_STORAGE;
import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE;
import static android.app.AppOpsManager.OP_READ_MEDIA_AUDIO;
import static android.app.AppOpsManager.OP_READ_MEDIA_IMAGES;
@@ -1721,6 +1722,33 @@ public class StorageManager {
return checkPermissionAndAppOp(mContext, enforce, pid, uid, packageName, permission, op);
}
+ private boolean noteAppOpAllowingLegacy(boolean enforce,
+ int pid, int uid, String packageName, int op) {
+ final int mode = mAppOps.noteOpNoThrow(op, uid, packageName);
+ switch (mode) {
+ case AppOpsManager.MODE_ALLOWED:
+ return true;
+ case AppOpsManager.MODE_DEFAULT:
+ case AppOpsManager.MODE_IGNORED:
+ case AppOpsManager.MODE_ERRORED:
+ // Legacy apps technically have the access granted by this op,
+ // even when the op is denied
+ if ((mAppOps.checkOpNoThrow(OP_LEGACY_STORAGE, uid,
+ packageName) == AppOpsManager.MODE_ALLOWED)) return true;
+
+ if (enforce) {
+ throw new SecurityException("Op " + AppOpsManager.opToName(op) + " "
+ + AppOpsManager.modeToName(mode) + " for package " + packageName);
+ } else {
+ return false;
+ }
+ default:
+ throw new IllegalStateException(
+ AppOpsManager.opToName(op) + " has unknown mode "
+ + AppOpsManager.modeToName(mode));
+ }
+ }
+
// Callers must hold both the old and new permissions, so that we can
// handle obscure cases like when an app targets Q but was installed on
// a device that was originally running on P before being upgraded to Q.
@@ -1730,8 +1758,7 @@ public class StorageManager {
int pid, int uid, String packageName) {
if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
- mAppOps.noteOpNoThrow(OP_READ_MEDIA_AUDIO, uid, packageName);
- return true;
+ return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_AUDIO);
}
/** {@hide} */
@@ -1739,8 +1766,7 @@ public class StorageManager {
int pid, int uid, String packageName) {
if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
- mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_AUDIO, uid, packageName);
- return true;
+ return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_AUDIO);
}
/** {@hide} */
@@ -1748,8 +1774,7 @@ public class StorageManager {
int pid, int uid, String packageName) {
if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
- mAppOps.noteOpNoThrow(OP_READ_MEDIA_VIDEO, uid, packageName);
- return true;
+ return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_VIDEO);
}
/** {@hide} */
@@ -1757,8 +1782,7 @@ public class StorageManager {
int pid, int uid, String packageName) {
if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
- mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_VIDEO, uid, packageName);
- return true;
+ return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_VIDEO);
}
/** {@hide} */
@@ -1766,8 +1790,7 @@ public class StorageManager {
int pid, int uid, String packageName) {
if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE)) return false;
- mAppOps.noteOpNoThrow(OP_READ_MEDIA_IMAGES, uid, packageName);
- return true;
+ return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_READ_MEDIA_IMAGES);
}
/** {@hide} */
@@ -1775,8 +1798,7 @@ public class StorageManager {
int pid, int uid, String packageName) {
if (!checkPermissionAndAppOp(enforce, pid, uid, packageName,
WRITE_EXTERNAL_STORAGE, OP_WRITE_EXTERNAL_STORAGE)) return false;
- mAppOps.noteOpNoThrow(OP_WRITE_MEDIA_IMAGES, uid, packageName);
- return true;
+ return noteAppOpAllowingLegacy(enforce, pid, uid, packageName, OP_WRITE_MEDIA_IMAGES);
}
/** {@hide} */