diff options
| author | 2020-01-29 18:45:52 +0000 | |
|---|---|---|
| committer | 2020-01-30 14:27:13 +0000 | |
| commit | b0dffde3b73588f3f4d1307148b594ff86f21e11 (patch) | |
| tree | 05b975d9b7056c4c88f1bdabae18d5459e1694ac | |
| parent | f6e58c9f531d3861a79612c130f5161c59bf84c4 (diff) | |
Kill app when OP_MANAGE_EXTERNAL_STORAGE is denied.
When an app requests the special access permission to be able to manage
external storage, and it is denied, we need to kill the app, in order to
lose the external_storage gid it may have that allows it access to
unreliable USB OTG volumes.
When the app op is granted, we don't kill the app to pickup the new
gid because it may result in bad UX especially since that gid is only
useful to access unreliable USB OTGs that are rarely present.
The next time the app is restarted, it will get the external_storage
gid and will be able to access any mounted USB OTG volumes.
Bug: 144914977
Test: Copy paste of I73c5ce56ee24e5c864d7c9280b83fc3854701a97
Change-Id: I5cb13dc9c51cb8b4e942e529b4a1c7dac180cace
| -rw-r--r-- | services/core/java/com/android/server/StorageManagerService.java | 43 |
1 files changed, 30 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index a04f25b0d20c..e17dde9a766e 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -24,6 +24,7 @@ import static android.Manifest.permission.WRITE_MEDIA_STORAGE; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.OP_LEGACY_STORAGE; +import static android.app.AppOpsManager.OP_MANAGE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_READ_EXTERNAL_STORAGE; import static android.app.AppOpsManager.OP_REQUEST_INSTALL_PACKAGES; import static android.app.AppOpsManager.OP_WRITE_EXTERNAL_STORAGE; @@ -4320,21 +4321,37 @@ class StorageManagerService extends IStorageManager.Stub return true; } - public void onAppOpsChanged(int code, int uid, - @Nullable String packageName, int mode) { - if (code == OP_REQUEST_INSTALL_PACKAGES && mIsFuseEnabled) { - // When using FUSE, we basically have no other choice but to kill the app - // after the app op is either granted or rejected. - final IActivityManager am = ActivityManager.getService(); - try { - am.killApplication(packageName, - UserHandle.getAppId(uid), - UserHandle.USER_ALL, AppOpsManager.opToName(code) + " changed."); - } catch (RemoteException e) { - } + private void killAppForOpChange(int code, int uid, String packageName) { + final IActivityManager am = ActivityManager.getService(); + try { + am.killApplication(packageName, + UserHandle.getAppId(uid), + UserHandle.USER_ALL, AppOpsManager.opToName(code) + " changed."); + } catch (RemoteException e) { + } + } - return; + public void onAppOpsChanged(int code, int uid, @Nullable String packageName, int mode) { + if (mIsFuseEnabled) { + // When using FUSE, we may need to kill the app if the op changes + switch(code) { + case OP_REQUEST_INSTALL_PACKAGES: + // Always kill regardless of op change, to remount apps /storage + killAppForOpChange(code, uid, packageName); + return; + case OP_MANAGE_EXTERNAL_STORAGE: + if (mode != MODE_ALLOWED) { + // Only kill if op is denied, to lose external_storage gid + // Killing when op is granted to pickup the gid automatically, results + // in a bad UX, especially since the gid only gives access to unreliable + // volumes, USB OTGs that are rarely mounted. The app will get the + // external_storage gid on next organic restart. + killAppForOpChange(code, uid, packageName); + return; + } + } } + if (mode == MODE_ALLOWED && (code == OP_READ_EXTERNAL_STORAGE || code == OP_WRITE_EXTERNAL_STORAGE || code == OP_REQUEST_INSTALL_PACKAGES)) { |