Merge "Only allow Download authority/MTP/installers to write in Android/."
This commit is contained in:
committed by
Android (Google) Code Review
commit
3fa3890183
@@ -88,6 +88,12 @@ public class Process {
|
||||
@UnsupportedAppUsage
|
||||
public static final int DRM_UID = 1019;
|
||||
|
||||
/**
|
||||
* Defines the GID for the group that allows write access to the internal media storage.
|
||||
* @hide
|
||||
*/
|
||||
public static final int SDCARD_RW_GID = 1015;
|
||||
|
||||
/**
|
||||
* Defines the UID/GID for the group that controls VPN services.
|
||||
* @hide
|
||||
|
||||
@@ -594,6 +594,8 @@ public class ZygoteProcess {
|
||||
argsForZygote.add("--mount-external-legacy");
|
||||
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_PASS_THROUGH) {
|
||||
argsForZygote.add("--mount-external-pass-through");
|
||||
} else if (mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
|
||||
argsForZygote.add("--mount-external-android-writable");
|
||||
}
|
||||
|
||||
argsForZygote.add("--target-sdk-version=" + targetSdkVersion);
|
||||
|
||||
@@ -145,6 +145,11 @@ public final class Zygote {
|
||||
/** The lower file system should be bind mounted directly on external storage */
|
||||
public static final int MOUNT_EXTERNAL_PASS_THROUGH = IVold.REMOUNT_MODE_PASS_THROUGH;
|
||||
|
||||
/** Use the regular scoped storage filesystem, but Android/ should be writable.
|
||||
* Used to support the applications hosting DownloadManager and the MTP server.
|
||||
*/
|
||||
public static final int MOUNT_EXTERNAL_ANDROID_WRITABLE = IVold.REMOUNT_MODE_ANDROID_WRITABLE;
|
||||
|
||||
/** Number of bytes sent to the Zygote over USAP pipes or the pool event FD */
|
||||
static final int USAP_MANAGEMENT_MESSAGE_BYTES = 8;
|
||||
|
||||
|
||||
@@ -376,6 +376,8 @@ class ZygoteArguments {
|
||||
mMountExternal = Zygote.MOUNT_EXTERNAL_LEGACY;
|
||||
} else if (arg.equals("--mount-external-pass-through")) {
|
||||
mMountExternal = Zygote.MOUNT_EXTERNAL_PASS_THROUGH;
|
||||
} else if (arg.equals("--mount-external-android-writable")) {
|
||||
mMountExternal = Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
|
||||
} else if (arg.equals("--query-abi-list")) {
|
||||
mAbiListQuery = true;
|
||||
} else if (arg.equals("--get-pid")) {
|
||||
|
||||
@@ -319,7 +319,8 @@ enum MountExternalKind {
|
||||
MOUNT_EXTERNAL_INSTALLER = 5,
|
||||
MOUNT_EXTERNAL_FULL = 6,
|
||||
MOUNT_EXTERNAL_PASS_THROUGH = 7,
|
||||
MOUNT_EXTERNAL_COUNT = 8
|
||||
MOUNT_EXTERNAL_ANDROID_WRITABLE = 8,
|
||||
MOUNT_EXTERNAL_COUNT = 9
|
||||
};
|
||||
|
||||
// The order of entries here must be kept in sync with MountExternalKind enum values.
|
||||
@@ -331,6 +332,8 @@ static const std::array<const std::string, MOUNT_EXTERNAL_COUNT> ExternalStorage
|
||||
"/mnt/runtime/write", // MOUNT_EXTERNAL_LEGACY
|
||||
"/mnt/runtime/write", // MOUNT_EXTERNAL_INSTALLER
|
||||
"/mnt/runtime/full", // MOUNT_EXTERNAL_FULL
|
||||
"/mnt/runtime/full", // MOUNT_EXTERNAL_PASS_THROUGH (only used w/ FUSE)
|
||||
"/mnt/runtime/full", // MOUNT_EXTERNAL_ANDROID_WRITABLE (only used w/ FUSE)
|
||||
};
|
||||
|
||||
// Must match values in com.android.internal.os.Zygote.
|
||||
@@ -755,12 +758,7 @@ static void MountEmulatedStorage(uid_t uid, jint mount_mode,
|
||||
multiuser_get_uid(user_id, AID_EVERYBODY), fail_fn);
|
||||
|
||||
if (isFuse) {
|
||||
if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH || mount_mode ==
|
||||
MOUNT_EXTERNAL_INSTALLER || mount_mode == MOUNT_EXTERNAL_FULL) {
|
||||
// For now, MediaProvider, installers and "full" get the pass_through mount
|
||||
// view, which is currently identical to the sdcardfs write view.
|
||||
//
|
||||
// TODO(b/146189163): scope down MOUNT_EXTERNAL_INSTALLER
|
||||
if (mount_mode == MOUNT_EXTERNAL_PASS_THROUGH) {
|
||||
BindMount(pass_through_source, "/storage", fail_fn);
|
||||
} else {
|
||||
BindMount(user_source, "/storage", fail_fn);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server;
|
||||
|
||||
import static android.Manifest.permission.ACCESS_MTP;
|
||||
import static android.Manifest.permission.INSTALL_PACKAGES;
|
||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
@@ -111,6 +112,7 @@ import android.os.storage.StorageVolume;
|
||||
import android.os.storage.VolumeInfo;
|
||||
import android.os.storage.VolumeRecord;
|
||||
import android.provider.DeviceConfig;
|
||||
import android.provider.Downloads;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings;
|
||||
import android.sysprop.VoldProperties;
|
||||
@@ -367,6 +369,8 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
|
||||
private volatile int mMediaStoreAuthorityAppId = -1;
|
||||
|
||||
private volatile int mDownloadsAuthorityAppId = -1;
|
||||
|
||||
private volatile int mCurrentUserId = UserHandle.USER_SYSTEM;
|
||||
|
||||
private final Installer mInstaller;
|
||||
@@ -1788,6 +1792,15 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
mMediaStoreAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
|
||||
}
|
||||
|
||||
provider = mPmInternal.resolveContentProvider(
|
||||
Downloads.Impl.AUTHORITY, PackageManager.MATCH_DIRECT_BOOT_AWARE
|
||||
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
|
||||
UserHandle.getUserId(UserHandle.USER_SYSTEM));
|
||||
|
||||
if (provider != null) {
|
||||
mDownloadsAuthorityAppId = UserHandle.getAppId(provider.applicationInfo.uid);
|
||||
}
|
||||
|
||||
try {
|
||||
mIAppOpsService.startWatchingMode(OP_REQUEST_INSTALL_PACKAGES, null, mAppOpsCallback);
|
||||
mIAppOpsService.startWatchingMode(OP_LEGACY_STORAGE, null, mAppOpsCallback);
|
||||
@@ -3881,6 +3894,19 @@ class StorageManagerService extends IStorageManager.Stub
|
||||
return Zygote.MOUNT_EXTERNAL_PASS_THROUGH;
|
||||
}
|
||||
|
||||
if (mIsFuseEnabled && mDownloadsAuthorityAppId == UserHandle.getAppId(uid)) {
|
||||
// DownloadManager can write in app-private directories on behalf of apps;
|
||||
// give it write access to Android/
|
||||
return Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
|
||||
}
|
||||
|
||||
final boolean hasMtp = mIPackageManager.checkUidPermission(ACCESS_MTP, uid) ==
|
||||
PERMISSION_GRANTED;
|
||||
if (mIsFuseEnabled && hasMtp) {
|
||||
// The process hosting the MTP server should be able to write in Android/
|
||||
return Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE;
|
||||
}
|
||||
|
||||
// Determine if caller is holding runtime permission
|
||||
final boolean hasRead = StorageManager.checkPermissionAndCheckOp(mContext, false, 0,
|
||||
uid, packageName, READ_EXTERNAL_STORAGE, OP_READ_EXTERNAL_STORAGE);
|
||||
|
||||
@@ -1555,20 +1555,27 @@ public final class ProcessList {
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowAsRuntimeException();
|
||||
}
|
||||
|
||||
int numGids = 3;
|
||||
if (mountExternal == Zygote.MOUNT_EXTERNAL_INSTALLER
|
||||
|| mountExternal == Zygote.MOUNT_EXTERNAL_ANDROID_WRITABLE) {
|
||||
numGids++;
|
||||
}
|
||||
/*
|
||||
* Add shared application and profile GIDs so applications can share some
|
||||
* resources like shared libraries and access user-wide resources
|
||||
*/
|
||||
if (ArrayUtils.isEmpty(permGids)) {
|
||||
gids = new int[3];
|
||||
gids = new int[numGids];
|
||||
} else {
|
||||
gids = new int[permGids.length + 3];
|
||||
System.arraycopy(permGids, 0, gids, 3, permGids.length);
|
||||
gids = new int[permGids.length + numGids];
|
||||
System.arraycopy(permGids, 0, gids, numGids, permGids.length);
|
||||
}
|
||||
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
|
||||
gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid));
|
||||
gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid));
|
||||
if (numGids > 3) {
|
||||
gids[3] = Process.SDCARD_RW_GID;
|
||||
}
|
||||
|
||||
// Replace any invalid GIDs
|
||||
if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2];
|
||||
|
||||
Reference in New Issue
Block a user