summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Martijn Coenen <maco@google.com> 2020-03-23 15:47:33 +0100
committer Martijn Coenen <maco@google.com> 2020-03-23 16:27:24 +0100
commit0f522bfebf43c214ccf0d940a810058e9f8c0f2c (patch)
tree2d7773baa36e7110e77fbb41945d1de39d46f3ff
parentb4decfc142806b45adf273865aefdcfbc58b5375 (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.aidl1
-rw-r--r--core/java/android/os/storage/StorageManager.java30
-rw-r--r--services/core/java/com/android/server/StorageManagerService.java20
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;