diff options
| author | 2019-04-28 12:52:37 -0600 | |
|---|---|---|
| committer | 2019-04-28 12:52:43 -0600 | |
| commit | c4bf993c512b81ad4fa0a1b4e3bf885920a9d374 (patch) | |
| tree | ffe21591dc4df8641ba8d2fbd4d485d9528478c0 | |
| parent | bf70e9ccdfb1070e07fefa11af86ed0f98b945c9 (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.java | 46 |
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} */ |