Loading core/java/android/os/storage/StorageManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IVold; import java.util.Set; /** * Mount service local interface. * Loading Loading @@ -97,6 +99,12 @@ public abstract class StorageManagerInternal { void onReset(IVold vold); } /** * Check if fuse is running in target user, if it's running then setup its obb directories. * TODO: System server should store a list of active pids that obb is not mounted and use it. */ public abstract void prepareObbDirs(int userId, Set<String> packageList, String processName); /** * Add a listener to listen to reset event in StorageManagerService. * Loading core/jni/com_android_internal_os_Zygote.cpp +102 −0 Original line number Diff line number Diff line Loading @@ -105,10 +105,12 @@ namespace { using namespace std::placeholders; using android::String8; using android::base::ReadFileToString; using android::base::StringAppendF; using android::base::StringPrintf; using android::base::WriteStringToFile; using android::base::GetBoolProperty; using android::base::GetProperty; #define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \ append(StringPrintf(__VA_ARGS__)) Loading Loading @@ -174,6 +176,12 @@ static constexpr int DEFAULT_DATA_DIR_PERMISSION = 0751; static const std::string ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.zygote.app_data_isolation"; /** * Property to enable app data isolation for sdcard obb or data in vold. */ static const std::string ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.sys.vold_app_data_isolation_enabled"; static constexpr const uint64_t UPPER_HALF_WORD_MASK = 0xFFFF'FFFF'0000'0000; static constexpr const uint64_t LOWER_HALF_WORD_MASK = 0x0000'0000'FFFF'FFFF; Loading Loading @@ -603,6 +611,15 @@ static void EnableDebugger() { } } static bool IsFilesystemSupported(const std::string& fsType) { std::string supported; if (!ReadFileToString("/proc/filesystems", &supported)) { ALOGE("Failed to read supported filesystems"); return false; } return supported.find(fsType + "\n") != std::string::npos; } static void PreApplicationInit() { // The child process sets this to indicate it's not the zygote. android_mallopt(M_SET_ZYGOTE_CHILD, nullptr, 0); Loading Loading @@ -782,6 +799,31 @@ static void MountAppDataTmpFs(const std::string& target_dir, } } static void BindMountObbPackage(std::string_view package_name, int userId, fail_fn_t fail_fn) { // TODO(148772775): Pass primary volume name from zygote argument to here std::string source; if (IsFilesystemSupported("sdcardfs")) { source = StringPrintf("/mnt/runtime/default/emulated/%d/Android/obb/%s", userId, package_name.data()); } else { source = StringPrintf("/mnt/pass_through/%d/emulated/%d/Android/obb/%s", userId, userId, package_name.data()); } std::string target( StringPrintf("/storage/emulated/%d/Android/obb/%s", userId, package_name.data())); if (access(source.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Cannot access source %s: %s", source.c_str(), strerror(errno))); } if (access(target.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Cannot access target %s: %s", target.c_str(), strerror(errno))); } BindMount(source, target, fail_fn); } // Create a private mount namespace and bind mount appropriate emulated // storage for the given user. static void MountEmulatedStorage(uid_t uid, jint mount_mode, Loading Loading @@ -1504,6 +1546,60 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list, } } // Bind mount all obb directories that are visible to this app. // If app data isolation is not enabled for this process, bind mount the whole obb // directory instead. static void BindMountAppObbDirs(JNIEnv* env, jobjectArray pkg_data_info_list, uid_t uid, const char* process_name, jstring managed_nice_name, fail_fn_t fail_fn) { auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1); const userid_t user_id = multiuser_get_user_id(uid); // If FUSE is not ready for this user, skip it // TODO(148772775): Pass primary volume name from zygote argument to here std::string tmp = GetProperty("vold.fuse_running_users", ""); std::istringstream fuse_running_users(tmp); bool user_found = false; std::string s; std::string user_id_str = std::to_string(user_id); while (!user_found && std::getline(fuse_running_users, s, ',')) { if (user_id_str == s) { user_found = true; } } if (!user_found) { ALOGI("User %d is not running fuse yet, fuse_running_users=%s", user_id, tmp.c_str()); return; } // Fuse is ready, so we can start using fuse path. int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0; if (size == 0) { // App data isolation is not enabled for this process, so we bind mount to whole obb/ dir. std::string source; if (IsFilesystemSupported("sdcardfs")) { source = StringPrintf("/mnt/runtime/default/emulated/%d/Android/obb", user_id); } else { source = StringPrintf("/mnt/pass_through/%d/emulated/%d/Android/obb", user_id, user_id); } std::string target(StringPrintf("/storage/emulated/%d/Android/obb", user_id)); if (access(source.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Error accessing %s: %s", source.c_str(), strerror(errno))); } BindMount(source, target, fail_fn); return; } // Bind mount each package obb directory for (int i = 0; i < size; i += 3) { jstring package_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i)); std::string packageName = extract_fn(package_str).value(); BindMountObbPackage(packageName, user_id, fail_fn); } } // Utility routine to specialize a zygote child process. static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, Loading Loading @@ -1552,6 +1648,12 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, isolateJitProfile(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn); } if ((mount_external != MOUNT_EXTERNAL_INSTALLER) && GetBoolProperty(kPropFuse, false) && GetBoolProperty(ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false)) { BindMountAppObbDirs(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn); } // If this zygote isn't root, it won't be able to create a process group, // since the directory is owned by root. if (!is_system_server && getuid() == 0) { Loading services/core/java/com/android/server/StorageManagerService.java +38 −2 Original line number Diff line number Diff line Loading @@ -2120,8 +2120,6 @@ class StorageManagerService extends IStorageManager.Stub private void unmount(VolumeInfo vol) { try { mVold.unmount(vol.id); mStorageSessionController.onVolumeUnmount(vol); try { if (vol.type == VolumeInfo.TYPE_PRIVATE) { mInstaller.onPrivateVolumeRemoved(vol.getFsUuid()); Loading @@ -2129,6 +2127,8 @@ class StorageManagerService extends IStorageManager.Stub } catch (Installer.InstallerException e) { Slog.e(TAG, "Failed unmount mirror data", e); } mVold.unmount(vol.id); mStorageSessionController.onVolumeUnmount(vol); } catch (Exception e) { Slog.wtf(TAG, e); } Loading Loading @@ -4346,6 +4346,42 @@ class StorageManagerService extends IStorageManager.Stub mPolicies.add(policy); } /** * Check if fuse is running in target user, if it's running then setup its obb directories. * TODO: System server should store a list of active pids that obb is not mounted and use it. */ @Override public void prepareObbDirs(int userId, Set<String> packageList, String processName) { String fuseRunningUsersList = SystemProperties.get("vold.fuse_running_users", ""); String[] fuseRunningUsers = fuseRunningUsersList.split(","); boolean fuseReady = false; String targetUserId = String.valueOf(userId); for (String user : fuseRunningUsers) { if (targetUserId.equals(user)) { fuseReady = true; } } if (fuseReady) { try { final IVold vold = IVold.Stub.asInterface( ServiceManager.getServiceOrThrow("vold")); for (String pkg : packageList) { final String obbDir = String.format("/storage/emulated/%d/Android/obb", userId); final String packageObbDir = String.format("%s/%s/", obbDir, pkg); // Create package obb dir if it doesn't exist. File file = new File(packageObbDir); if (!file.exists()) { vold.setupAppDir(packageObbDir, mPmInternal.getPackage(pkg).getUid()); } } } catch (ServiceManager.ServiceNotFoundException | RemoteException e) { Slog.e(TAG, "Unable to create obb directories for " + processName, e); } } } @Override public void onExternalStoragePolicyChanged(int uid, String packageName) { final int mountMode = getExternalStorageMountMode(uid, packageName); Loading services/core/java/com/android/server/am/ProcessList.java +18 −1 Original line number Diff line number Diff line Loading @@ -80,11 +80,13 @@ import android.os.Bundle; import android.os.DropBoxManager; import android.os.Handler; import android.os.IBinder; import android.os.IVold; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; Loading Loading @@ -142,10 +144,14 @@ import java.util.Map; public final class ProcessList { static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; // A device config to control the minimum target SDK to enable app data isolation // A system property to control if app data isolation is enabled. static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.zygote.app_data_isolation"; // A system property to control if obb app data isolation is enabled in vold. static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.sys.vold_app_data_isolation_enabled"; // A device config to control the minimum target SDK to enable app data isolation static final String ANDROID_APP_DATA_ISOLATION_MIN_SDK = "android_app_data_isolation_min_sdk"; Loading Loading @@ -379,6 +385,8 @@ public final class ProcessList { private boolean mAppDataIsolationEnabled = false; private boolean mVoldAppDataIsolationEnabled = false; private ArrayList<String> mAppDataIsolationWhitelistedApps; /** Loading Loading @@ -691,6 +699,8 @@ public final class ProcessList { // want some apps enabled while some apps disabled mAppDataIsolationEnabled = SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true); mVoldAppDataIsolationEnabled = SystemProperties.getBoolean( ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false); mAppDataIsolationWhitelistedApps = new ArrayList<>( SystemConfig.getInstance().getAppDataIsolationWhitelistedApps()); Loading Loading @@ -2113,6 +2123,13 @@ public final class ProcessList { app.info.packageName, app.userId); pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, sharedPackages.length == 0 ? new String[]{app.info.packageName} : sharedPackages, uid); if (mVoldAppDataIsolationEnabled) { StorageManagerInternal storageManagerInternal = LocalServices.getService( StorageManagerInternal.class); storageManagerInternal.prepareObbDirs(UserHandle.getUserId(uid), pkgDataInfoMap.keySet(), app.processName); } } else { pkgDataInfoMap = null; } Loading Loading
core/java/android/os/storage/StorageManagerInternal.java +8 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.IVold; import java.util.Set; /** * Mount service local interface. * Loading Loading @@ -97,6 +99,12 @@ public abstract class StorageManagerInternal { void onReset(IVold vold); } /** * Check if fuse is running in target user, if it's running then setup its obb directories. * TODO: System server should store a list of active pids that obb is not mounted and use it. */ public abstract void prepareObbDirs(int userId, Set<String> packageList, String processName); /** * Add a listener to listen to reset event in StorageManagerService. * Loading
core/jni/com_android_internal_os_Zygote.cpp +102 −0 Original line number Diff line number Diff line Loading @@ -105,10 +105,12 @@ namespace { using namespace std::placeholders; using android::String8; using android::base::ReadFileToString; using android::base::StringAppendF; using android::base::StringPrintf; using android::base::WriteStringToFile; using android::base::GetBoolProperty; using android::base::GetProperty; #define CREATE_ERROR(...) StringPrintf("%s:%d: ", __FILE__, __LINE__). \ append(StringPrintf(__VA_ARGS__)) Loading Loading @@ -174,6 +176,12 @@ static constexpr int DEFAULT_DATA_DIR_PERMISSION = 0751; static const std::string ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.zygote.app_data_isolation"; /** * Property to enable app data isolation for sdcard obb or data in vold. */ static const std::string ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.sys.vold_app_data_isolation_enabled"; static constexpr const uint64_t UPPER_HALF_WORD_MASK = 0xFFFF'FFFF'0000'0000; static constexpr const uint64_t LOWER_HALF_WORD_MASK = 0x0000'0000'FFFF'FFFF; Loading Loading @@ -603,6 +611,15 @@ static void EnableDebugger() { } } static bool IsFilesystemSupported(const std::string& fsType) { std::string supported; if (!ReadFileToString("/proc/filesystems", &supported)) { ALOGE("Failed to read supported filesystems"); return false; } return supported.find(fsType + "\n") != std::string::npos; } static void PreApplicationInit() { // The child process sets this to indicate it's not the zygote. android_mallopt(M_SET_ZYGOTE_CHILD, nullptr, 0); Loading Loading @@ -782,6 +799,31 @@ static void MountAppDataTmpFs(const std::string& target_dir, } } static void BindMountObbPackage(std::string_view package_name, int userId, fail_fn_t fail_fn) { // TODO(148772775): Pass primary volume name from zygote argument to here std::string source; if (IsFilesystemSupported("sdcardfs")) { source = StringPrintf("/mnt/runtime/default/emulated/%d/Android/obb/%s", userId, package_name.data()); } else { source = StringPrintf("/mnt/pass_through/%d/emulated/%d/Android/obb/%s", userId, userId, package_name.data()); } std::string target( StringPrintf("/storage/emulated/%d/Android/obb/%s", userId, package_name.data())); if (access(source.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Cannot access source %s: %s", source.c_str(), strerror(errno))); } if (access(target.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Cannot access target %s: %s", target.c_str(), strerror(errno))); } BindMount(source, target, fail_fn); } // Create a private mount namespace and bind mount appropriate emulated // storage for the given user. static void MountEmulatedStorage(uid_t uid, jint mount_mode, Loading Loading @@ -1504,6 +1546,60 @@ static void isolateJitProfile(JNIEnv* env, jobjectArray pkg_data_info_list, } } // Bind mount all obb directories that are visible to this app. // If app data isolation is not enabled for this process, bind mount the whole obb // directory instead. static void BindMountAppObbDirs(JNIEnv* env, jobjectArray pkg_data_info_list, uid_t uid, const char* process_name, jstring managed_nice_name, fail_fn_t fail_fn) { auto extract_fn = std::bind(ExtractJString, env, process_name, managed_nice_name, _1); const userid_t user_id = multiuser_get_user_id(uid); // If FUSE is not ready for this user, skip it // TODO(148772775): Pass primary volume name from zygote argument to here std::string tmp = GetProperty("vold.fuse_running_users", ""); std::istringstream fuse_running_users(tmp); bool user_found = false; std::string s; std::string user_id_str = std::to_string(user_id); while (!user_found && std::getline(fuse_running_users, s, ',')) { if (user_id_str == s) { user_found = true; } } if (!user_found) { ALOGI("User %d is not running fuse yet, fuse_running_users=%s", user_id, tmp.c_str()); return; } // Fuse is ready, so we can start using fuse path. int size = (pkg_data_info_list != nullptr) ? env->GetArrayLength(pkg_data_info_list) : 0; if (size == 0) { // App data isolation is not enabled for this process, so we bind mount to whole obb/ dir. std::string source; if (IsFilesystemSupported("sdcardfs")) { source = StringPrintf("/mnt/runtime/default/emulated/%d/Android/obb", user_id); } else { source = StringPrintf("/mnt/pass_through/%d/emulated/%d/Android/obb", user_id, user_id); } std::string target(StringPrintf("/storage/emulated/%d/Android/obb", user_id)); if (access(source.c_str(), F_OK) != 0) { fail_fn(CREATE_ERROR("Error accessing %s: %s", source.c_str(), strerror(errno))); } BindMount(source, target, fail_fn); return; } // Bind mount each package obb directory for (int i = 0; i < size; i += 3) { jstring package_str = (jstring) (env->GetObjectArrayElement(pkg_data_info_list, i)); std::string packageName = extract_fn(package_str).value(); BindMountObbPackage(packageName, user_id, fail_fn); } } // Utility routine to specialize a zygote child process. static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, jint runtime_flags, jobjectArray rlimits, Loading Loading @@ -1552,6 +1648,12 @@ static void SpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray gids, isolateJitProfile(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn); } if ((mount_external != MOUNT_EXTERNAL_INSTALLER) && GetBoolProperty(kPropFuse, false) && GetBoolProperty(ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false)) { BindMountAppObbDirs(env, pkg_data_info_list, uid, process_name, managed_nice_name, fail_fn); } // If this zygote isn't root, it won't be able to create a process group, // since the directory is owned by root. if (!is_system_server && getuid() == 0) { Loading
services/core/java/com/android/server/StorageManagerService.java +38 −2 Original line number Diff line number Diff line Loading @@ -2120,8 +2120,6 @@ class StorageManagerService extends IStorageManager.Stub private void unmount(VolumeInfo vol) { try { mVold.unmount(vol.id); mStorageSessionController.onVolumeUnmount(vol); try { if (vol.type == VolumeInfo.TYPE_PRIVATE) { mInstaller.onPrivateVolumeRemoved(vol.getFsUuid()); Loading @@ -2129,6 +2127,8 @@ class StorageManagerService extends IStorageManager.Stub } catch (Installer.InstallerException e) { Slog.e(TAG, "Failed unmount mirror data", e); } mVold.unmount(vol.id); mStorageSessionController.onVolumeUnmount(vol); } catch (Exception e) { Slog.wtf(TAG, e); } Loading Loading @@ -4346,6 +4346,42 @@ class StorageManagerService extends IStorageManager.Stub mPolicies.add(policy); } /** * Check if fuse is running in target user, if it's running then setup its obb directories. * TODO: System server should store a list of active pids that obb is not mounted and use it. */ @Override public void prepareObbDirs(int userId, Set<String> packageList, String processName) { String fuseRunningUsersList = SystemProperties.get("vold.fuse_running_users", ""); String[] fuseRunningUsers = fuseRunningUsersList.split(","); boolean fuseReady = false; String targetUserId = String.valueOf(userId); for (String user : fuseRunningUsers) { if (targetUserId.equals(user)) { fuseReady = true; } } if (fuseReady) { try { final IVold vold = IVold.Stub.asInterface( ServiceManager.getServiceOrThrow("vold")); for (String pkg : packageList) { final String obbDir = String.format("/storage/emulated/%d/Android/obb", userId); final String packageObbDir = String.format("%s/%s/", obbDir, pkg); // Create package obb dir if it doesn't exist. File file = new File(packageObbDir); if (!file.exists()) { vold.setupAppDir(packageObbDir, mPmInternal.getPackage(pkg).getUid()); } } } catch (ServiceManager.ServiceNotFoundException | RemoteException e) { Slog.e(TAG, "Unable to create obb directories for " + processName, e); } } } @Override public void onExternalStoragePolicyChanged(int uid, String packageName) { final int mountMode = getExternalStorageMountMode(uid, packageName); Loading
services/core/java/com/android/server/am/ProcessList.java +18 −1 Original line number Diff line number Diff line Loading @@ -80,11 +80,13 @@ import android.os.Bundle; import android.os.DropBoxManager; import android.os.Handler; import android.os.IBinder; import android.os.IVold; import android.os.Looper; import android.os.Message; import android.os.PowerManager; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.StrictMode; import android.os.SystemClock; import android.os.SystemProperties; Loading Loading @@ -142,10 +144,14 @@ import java.util.Map; public final class ProcessList { static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; // A device config to control the minimum target SDK to enable app data isolation // A system property to control if app data isolation is enabled. static final String ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.zygote.app_data_isolation"; // A system property to control if obb app data isolation is enabled in vold. static final String ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY = "persist.sys.vold_app_data_isolation_enabled"; // A device config to control the minimum target SDK to enable app data isolation static final String ANDROID_APP_DATA_ISOLATION_MIN_SDK = "android_app_data_isolation_min_sdk"; Loading Loading @@ -379,6 +385,8 @@ public final class ProcessList { private boolean mAppDataIsolationEnabled = false; private boolean mVoldAppDataIsolationEnabled = false; private ArrayList<String> mAppDataIsolationWhitelistedApps; /** Loading Loading @@ -691,6 +699,8 @@ public final class ProcessList { // want some apps enabled while some apps disabled mAppDataIsolationEnabled = SystemProperties.getBoolean(ANDROID_APP_DATA_ISOLATION_ENABLED_PROPERTY, true); mVoldAppDataIsolationEnabled = SystemProperties.getBoolean( ANDROID_VOLD_APP_DATA_ISOLATION_ENABLED_PROPERTY, false); mAppDataIsolationWhitelistedApps = new ArrayList<>( SystemConfig.getInstance().getAppDataIsolationWhitelistedApps()); Loading Loading @@ -2113,6 +2123,13 @@ public final class ProcessList { app.info.packageName, app.userId); pkgDataInfoMap = getPackageAppDataInfoMap(pmInt, sharedPackages.length == 0 ? new String[]{app.info.packageName} : sharedPackages, uid); if (mVoldAppDataIsolationEnabled) { StorageManagerInternal storageManagerInternal = LocalServices.getService( StorageManagerInternal.class); storageManagerInternal.prepareObbDirs(UserHandle.getUserId(uid), pkgDataInfoMap.keySet(), app.processName); } } else { pkgDataInfoMap = null; } Loading