Loading cmds/installd/InstalldNativeService.cpp +102 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <sys/file.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/mount.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/statvfs.h> Loading Loading @@ -86,6 +87,9 @@ static constexpr const mode_t kRollbackFolderMode = 0700; static constexpr const char* kCpPath = "/system/bin/cp"; static constexpr const char* kXattrDefault = "user.default"; static constexpr const char* kDataMirrorCePath = "/data_mirror/data_ce"; static constexpr const char* kDataMirrorDePath = "/data_mirror/data_de"; static constexpr const int MIN_RESTRICTED_HOME_SDK_VERSION = 24; // > M static constexpr const char* PKG_LIB_POSTFIX = "/lib"; Loading @@ -99,6 +103,13 @@ static constexpr size_t kSha256Size = 32; static constexpr const char* kPropApkVerityMode = "ro.apk_verity.mode"; static constexpr const char* kFuseProp = "persist.sys.fuse"; /** * Property to control if app data isolation is enabled. */ static constexpr const char* kAppDataIsolationEnabledProperty = "persist.zygote.app_data_isolation"; static std::atomic<bool> sAppDataIsolationEnabled(false); namespace { constexpr const char* kDump = "android.permission.DUMP"; Loading Loading @@ -258,6 +269,8 @@ status_t InstalldNativeService::start() { sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool(); ps->giveThreadPoolName(); sAppDataIsolationEnabled = android::base::GetBoolProperty( kAppDataIsolationEnabledProperty, false); return android::OK; } Loading Loading @@ -450,10 +463,13 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s // And return the CE inode of the top-level data directory so we can // clear contents while CE storage is locked if ((_aidl_return != nullptr) && get_path_inode(path, reinterpret_cast<ino_t*>(_aidl_return)) != 0) { if (_aidl_return != nullptr) { ino_t result; if (get_path_inode(path, &result) != 0) { return error("Failed to get_path_inode for " + path); } *_aidl_return = static_cast<uint64_t>(result); } } if (flags & FLAG_STORAGE_DE) { auto path = create_data_user_de_package_path(uuid_, userId, pkgname); Loading Loading @@ -2613,6 +2629,89 @@ binder::Status InstalldNativeService::invalidateMounts() { return ok(); } // Mount volume's CE and DE storage to mirror binder::Status InstalldNativeService::onPrivateVolumeMounted( const std::unique_ptr<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (!sAppDataIsolationEnabled) { return ok(); } if (!uuid) { return error("Should not happen, mounting uuid == null"); } const char* uuid_ = uuid->c_str(); // Mount CE mirror std::string mirrorVolCePath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_)); std::lock_guard<std::recursive_mutex> lock(mLock); if (fs_prepare_dir(mirrorVolCePath.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { return error("Failed to create CE mirror"); } auto cePath = StringPrintf("%s/user_ce", create_data_path(uuid_).c_str()); if (TEMP_FAILURE_RETRY(mount(cePath.c_str(), mirrorVolCePath.c_str(), NULL, MS_NOSUID | MS_NODEV | MS_NOATIME | MS_BIND | MS_NOEXEC, nullptr)) == -1) { return error("Failed to mount " + mirrorVolCePath); } // Mount DE mirror std::string mirrorVolDePath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_)); if (fs_prepare_dir(mirrorVolDePath.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { return error("Failed to create DE mirror"); } auto dePath = StringPrintf("%s/user_de", create_data_path(uuid_).c_str()); if (TEMP_FAILURE_RETRY(mount(dePath.c_str(), mirrorVolDePath.c_str(), NULL, MS_NOSUID | MS_NODEV | MS_NOATIME | MS_BIND | MS_NOEXEC, nullptr)) == -1) { return error("Failed to mount " + mirrorVolDePath); } return ok(); } // Unmount volume's CE and DE storage from mirror binder::Status InstalldNativeService::onPrivateVolumeRemoved( const std::unique_ptr<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (!sAppDataIsolationEnabled) { return ok(); } if (!uuid) { // It happens when private volume failed to mount. LOG(INFO) << "Ignore unmount uuid=null"; return ok(); } const char* uuid_ = uuid->c_str(); binder::Status res = ok(); std::string mirrorCeVolPath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_)); std::string mirrorDeVolPath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_)); // Unmount CE storage std::lock_guard<std::recursive_mutex> lock(mLock); if (TEMP_FAILURE_RETRY(umount(mirrorCeVolPath.c_str())) != 0) { if (errno != ENOENT) { res = error(StringPrintf("Failed to umount %s %s", mirrorCeVolPath.c_str(), strerror(errno))); } } if (delete_dir_contents_and_dir(mirrorCeVolPath, true) != 0) { res = error("Failed to delete " + mirrorCeVolPath); } // Unmount DE storage if (TEMP_FAILURE_RETRY(umount(mirrorDeVolPath.c_str())) != 0) { if (errno != ENOENT) { res = error(StringPrintf("Failed to umount %s %s", mirrorDeVolPath.c_str(), strerror(errno))); } } if (delete_dir_contents_and_dir(mirrorDeVolPath, true) != 0) { res = error("Failed to delete " + mirrorDeVolPath); } return res; } std::string InstalldNativeService::findDataMediaPath( const std::unique_ptr<std::string>& uuid, userid_t userid) { std::lock_guard<std::recursive_mutex> lock(mMountsLock); Loading cmds/installd/InstalldNativeService.h +2 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,8 @@ public: binder::Status invalidateMounts(); binder::Status isQuotaSupported(const std::unique_ptr<std::string>& volumeUuid, bool* _aidl_return); binder::Status onPrivateVolumeMounted(const std::unique_ptr<std::string>& volumeUuid); binder::Status onPrivateVolumeRemoved(const std::unique_ptr<std::string>& volumeUuid); binder::Status prepareAppProfile(const std::string& packageName, int32_t userId, int32_t appId, const std::string& profileName, Loading cmds/installd/QuotaUtils.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,10 @@ bool InvalidateQuotaMounts() { std::getline(in, target, ' '); std::getline(in, ignored); if (target.compare(0, 13, "/data_mirror/") == 0) { continue; } if (source.compare(0, 11, "/dev/block/") == 0) { struct dqblk dq; if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0, Loading cmds/installd/binder/android/os/IInstalld.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,8 @@ interface IInstalld { int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags); void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, int userId, long ceSnapshotInode, int snapshotId, int storageFlags); void onPrivateVolumeMounted(@nullable @utf8InCpp String volumeUuid); void onPrivateVolumeRemoved(@nullable @utf8InCpp String volumeUuid); void migrateLegacyObbData(); Loading Loading
cmds/installd/InstalldNativeService.cpp +102 −3 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <sys/file.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <sys/mount.h> #include <sys/resource.h> #include <sys/stat.h> #include <sys/statvfs.h> Loading Loading @@ -86,6 +87,9 @@ static constexpr const mode_t kRollbackFolderMode = 0700; static constexpr const char* kCpPath = "/system/bin/cp"; static constexpr const char* kXattrDefault = "user.default"; static constexpr const char* kDataMirrorCePath = "/data_mirror/data_ce"; static constexpr const char* kDataMirrorDePath = "/data_mirror/data_de"; static constexpr const int MIN_RESTRICTED_HOME_SDK_VERSION = 24; // > M static constexpr const char* PKG_LIB_POSTFIX = "/lib"; Loading @@ -99,6 +103,13 @@ static constexpr size_t kSha256Size = 32; static constexpr const char* kPropApkVerityMode = "ro.apk_verity.mode"; static constexpr const char* kFuseProp = "persist.sys.fuse"; /** * Property to control if app data isolation is enabled. */ static constexpr const char* kAppDataIsolationEnabledProperty = "persist.zygote.app_data_isolation"; static std::atomic<bool> sAppDataIsolationEnabled(false); namespace { constexpr const char* kDump = "android.permission.DUMP"; Loading Loading @@ -258,6 +269,8 @@ status_t InstalldNativeService::start() { sp<ProcessState> ps(ProcessState::self()); ps->startThreadPool(); ps->giveThreadPoolName(); sAppDataIsolationEnabled = android::base::GetBoolProperty( kAppDataIsolationEnabledProperty, false); return android::OK; } Loading Loading @@ -450,10 +463,13 @@ binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::s // And return the CE inode of the top-level data directory so we can // clear contents while CE storage is locked if ((_aidl_return != nullptr) && get_path_inode(path, reinterpret_cast<ino_t*>(_aidl_return)) != 0) { if (_aidl_return != nullptr) { ino_t result; if (get_path_inode(path, &result) != 0) { return error("Failed to get_path_inode for " + path); } *_aidl_return = static_cast<uint64_t>(result); } } if (flags & FLAG_STORAGE_DE) { auto path = create_data_user_de_package_path(uuid_, userId, pkgname); Loading Loading @@ -2613,6 +2629,89 @@ binder::Status InstalldNativeService::invalidateMounts() { return ok(); } // Mount volume's CE and DE storage to mirror binder::Status InstalldNativeService::onPrivateVolumeMounted( const std::unique_ptr<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (!sAppDataIsolationEnabled) { return ok(); } if (!uuid) { return error("Should not happen, mounting uuid == null"); } const char* uuid_ = uuid->c_str(); // Mount CE mirror std::string mirrorVolCePath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_)); std::lock_guard<std::recursive_mutex> lock(mLock); if (fs_prepare_dir(mirrorVolCePath.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { return error("Failed to create CE mirror"); } auto cePath = StringPrintf("%s/user_ce", create_data_path(uuid_).c_str()); if (TEMP_FAILURE_RETRY(mount(cePath.c_str(), mirrorVolCePath.c_str(), NULL, MS_NOSUID | MS_NODEV | MS_NOATIME | MS_BIND | MS_NOEXEC, nullptr)) == -1) { return error("Failed to mount " + mirrorVolCePath); } // Mount DE mirror std::string mirrorVolDePath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_)); if (fs_prepare_dir(mirrorVolDePath.c_str(), 0700, AID_ROOT, AID_ROOT) != 0) { return error("Failed to create DE mirror"); } auto dePath = StringPrintf("%s/user_de", create_data_path(uuid_).c_str()); if (TEMP_FAILURE_RETRY(mount(dePath.c_str(), mirrorVolDePath.c_str(), NULL, MS_NOSUID | MS_NODEV | MS_NOATIME | MS_BIND | MS_NOEXEC, nullptr)) == -1) { return error("Failed to mount " + mirrorVolDePath); } return ok(); } // Unmount volume's CE and DE storage from mirror binder::Status InstalldNativeService::onPrivateVolumeRemoved( const std::unique_ptr<std::string>& uuid) { ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); if (!sAppDataIsolationEnabled) { return ok(); } if (!uuid) { // It happens when private volume failed to mount. LOG(INFO) << "Ignore unmount uuid=null"; return ok(); } const char* uuid_ = uuid->c_str(); binder::Status res = ok(); std::string mirrorCeVolPath(StringPrintf("%s/%s", kDataMirrorCePath, uuid_)); std::string mirrorDeVolPath(StringPrintf("%s/%s", kDataMirrorDePath, uuid_)); // Unmount CE storage std::lock_guard<std::recursive_mutex> lock(mLock); if (TEMP_FAILURE_RETRY(umount(mirrorCeVolPath.c_str())) != 0) { if (errno != ENOENT) { res = error(StringPrintf("Failed to umount %s %s", mirrorCeVolPath.c_str(), strerror(errno))); } } if (delete_dir_contents_and_dir(mirrorCeVolPath, true) != 0) { res = error("Failed to delete " + mirrorCeVolPath); } // Unmount DE storage if (TEMP_FAILURE_RETRY(umount(mirrorDeVolPath.c_str())) != 0) { if (errno != ENOENT) { res = error(StringPrintf("Failed to umount %s %s", mirrorDeVolPath.c_str(), strerror(errno))); } } if (delete_dir_contents_and_dir(mirrorDeVolPath, true) != 0) { res = error("Failed to delete " + mirrorDeVolPath); } return res; } std::string InstalldNativeService::findDataMediaPath( const std::unique_ptr<std::string>& uuid, userid_t userid) { std::lock_guard<std::recursive_mutex> lock(mMountsLock); Loading
cmds/installd/InstalldNativeService.h +2 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,8 @@ public: binder::Status invalidateMounts(); binder::Status isQuotaSupported(const std::unique_ptr<std::string>& volumeUuid, bool* _aidl_return); binder::Status onPrivateVolumeMounted(const std::unique_ptr<std::string>& volumeUuid); binder::Status onPrivateVolumeRemoved(const std::unique_ptr<std::string>& volumeUuid); binder::Status prepareAppProfile(const std::string& packageName, int32_t userId, int32_t appId, const std::string& profileName, Loading
cmds/installd/QuotaUtils.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,10 @@ bool InvalidateQuotaMounts() { std::getline(in, target, ' '); std::getline(in, ignored); if (target.compare(0, 13, "/data_mirror/") == 0) { continue; } if (source.compare(0, 11, "/dev/block/") == 0) { struct dqblk dq; if (quotactl(QCMD(Q_GETQUOTA, USRQUOTA), source.c_str(), 0, Loading
cmds/installd/binder/android/os/IInstalld.aidl +2 −0 Original line number Diff line number Diff line Loading @@ -109,6 +109,8 @@ interface IInstalld { int appId, @utf8InCpp String seInfo, int user, int snapshotId, int storageflags); void destroyAppDataSnapshot(@nullable @utf8InCpp String uuid, @utf8InCpp String packageName, int userId, long ceSnapshotInode, int snapshotId, int storageFlags); void onPrivateVolumeMounted(@nullable @utf8InCpp String volumeUuid); void onPrivateVolumeRemoved(@nullable @utf8InCpp String volumeUuid); void migrateLegacyObbData(); Loading