diff options
| author | 2020-03-23 15:47:33 +0100 | |
|---|---|---|
| committer | 2020-03-23 16:27:24 +0100 | |
| commit | 0f522bfebf43c214ccf0d940a810058e9f8c0f2c (patch) | |
| tree | 2d7773baa36e7110e77fbb41945d1de39d46f3ff | |
| parent | b4decfc142806b45adf273865aefdcfbc58b5375 (diff) | |
Add (hidden) fixupAppDir() API.
On devices without sdcardfs, filesystem permissions aren't magically
fixed up. This is problematic mostly in application-private directories,
which are owned by the application itself; if another process with
elevated permissions creates a file in these directories, the UID will
be wrong, and the owning package won't be able to access the files.
Allow processes that modify application-private directories (eg
DownloadManager) to ask the framework to fix up permissions on their
behalf.
Bug: 151986170
Test: WIP
Change-Id: Ic30f708d25d7702ec3a4569ee6ddf100732d89d1
| -rw-r--r-- | core/java/android/os/storage/IStorageManager.aidl | 1 | ||||
| -rw-r--r-- | core/java/android/os/storage/StorageManager.java | 30 | ||||
| -rw-r--r-- | services/core/java/com/android/server/StorageManagerService.java | 20 |
3 files changed, 51 insertions, 0 deletions
diff --git a/core/java/android/os/storage/IStorageManager.aidl b/core/java/android/os/storage/IStorageManager.aidl index bbc936d76e1c..99bdfd1fc103 100644 --- a/core/java/android/os/storage/IStorageManager.aidl +++ b/core/java/android/os/storage/IStorageManager.aidl @@ -194,4 +194,5 @@ interface IStorageManager { boolean needsCheckpoint() = 86; void abortChanges(in String message, boolean retry) = 87; void clearUserKeyAuth(int userId, int serialNumber, in byte[] token, in byte[] secret) = 88; + void fixupAppDir(in String path) = 89; } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 1454aac66d21..a68cc3dfe0e4 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -2470,6 +2470,36 @@ public class StorageManager { } } + /** + * Asks StorageManager to fixup the permissions of an application-private directory. + * + * On devices without sdcardfs, filesystem permissions aren't magically fixed up. This + * is problematic mostly in application-private directories, which are owned by the + * application itself; if another process with elevated permissions creates a file + * in these directories, the UID will be wrong, and the owning package won't be able + * to access the files. + * + * This API can be used to recursively fix up the permissions on the passed in path. + * The default platform user of this API is the DownloadProvider, which can download + * things in application-private directories on their behalf. + * + * This API doesn't require any special permissions, because it merely changes the + * permissions of a directory to what they should anyway be. + * + * @param path the path for which we should fix up the permissions + * + * @hide + */ + public void fixupAppDir(@NonNull File path) { + try { + mStorageManager.fixupAppDir(path.getCanonicalPath()); + } catch (IOException e) { + Log.e(TAG, "Failed to get canonical path for " + path.getPath(), e); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** {@hide} */ private static void setCacheBehavior(File path, String name, boolean enabled) throws IOException { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index b7d050a25484..7b5a05dad27e 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -156,6 +156,7 @@ import com.android.internal.util.Preconditions; import com.android.internal.widget.LockPatternUtils; import com.android.server.SystemService.TargetUser; import com.android.server.pm.Installer; +import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.storage.AppFuseBridge; import com.android.server.storage.StorageSessionController; import com.android.server.storage.StorageSessionController.ExternalStorageServiceException; @@ -3196,6 +3197,25 @@ class StorageManagerService extends IStorageManager.Stub } } + @Override + public void fixupAppDir(String path) { + final Matcher matcher = KNOWN_APP_DIR_PATHS.matcher(path); + if (matcher.matches()) { + AndroidPackage pkg = mPmInternal.getPackage(matcher.group(3)); + if (pkg != null) { + try { + mVold.fixupAppDir(path + "/", pkg.getUid()); + } catch (RemoteException | ServiceSpecificException e) { + Log.e(TAG, "Failed to fixup app dir for " + pkg.getPackageName(), e); + } + } else { + Log.e(TAG, "Can't find package belonging to " + path); + } + } else { + Log.e(TAG, "Path " + path + " is not a valid application-specific directory"); + } + } + /** Not thread safe */ class AppFuseMountScope extends AppFuseBridge.MountScope { private boolean mMounted = false; |