diff options
| author | 2022-03-21 12:37:19 +0000 | |
|---|---|---|
| committer | 2022-03-21 12:37:19 +0000 | |
| commit | c8474c6880350ed86a1aa61d57bc3ee6f68a32fd (patch) | |
| tree | 9fab613a9ee50f16a4216088525754c3479c3faf | |
| parent | 68b7cdca84ebe4e104d04ae4c245396e6affe681 (diff) | |
| parent | 8bf940fea2bbb46ae20e08a67cf55a9afb0b6c7b (diff) | |
Merge "Move sdk data to target volume when moving app data" am: 8bf940fea2
Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/2031824
Change-Id: I4a8cc7d19c1d613c706f6f5588bec1ebed10c9ea
| -rw-r--r-- | cmds/installd/InstalldNativeService.cpp | 90 | ||||
| -rw-r--r-- | cmds/installd/InstalldNativeService.h | 22 |
2 files changed, 100 insertions, 12 deletions
diff --git a/cmds/installd/InstalldNativeService.cpp b/cmds/installd/InstalldNativeService.cpp index c5860e83c3..9949d22bbd 100644 --- a/cmds/installd/InstalldNativeService.cpp +++ b/cmds/installd/InstalldNativeService.cpp @@ -756,8 +756,7 @@ binder::Status InstalldNativeService::createSdkSandboxDataPackageDirectory( const char* uuid_ = uuid ? uuid->c_str() : nullptr; constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; - for (int i = 0; i < 2; i++) { - int currentFlag = storageFlags[i]; + for (int currentFlag : storageFlags) { if ((flags & currentFlag) == 0) { continue; } @@ -847,7 +846,6 @@ binder::Status InstalldNativeService::createAppDataBatched( binder::Status InstalldNativeService::reconcileSdkData( const android::os::ReconcileSdkDataArgs& args) { - ENFORCE_UID(AID_SYSTEM); // Locking is performed depeer in the callstack. return reconcileSdkData(args.uuid, args.packageName, args.sdkPackageNames, args.randomSuffixes, @@ -870,6 +868,7 @@ binder::Status InstalldNativeService::reconcileSdkData( const std::vector<std::string>& sdkPackageNames, const std::vector<std::string>& randomSuffixes, int userId, int appId, int previousAppId, const std::string& seInfo, int flags) { + ENFORCE_UID(AID_SYSTEM); CHECK_ARGUMENT_UUID(uuid); CHECK_ARGUMENT_PACKAGE_NAME(packageName); for (const auto& sdkPackageName : sdkPackageNames) { @@ -1772,6 +1771,36 @@ binder::Status InstalldNativeService::moveCompleteApp(const std::optional<std::s } } + // Copy sdk data for all known users + for (auto userId : users) { + LOCK_USER(); + + constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; + for (int currentFlag : storageFlags) { + const bool isCeData = currentFlag == FLAG_STORAGE_CE; + + const auto from = create_data_misc_sdk_sandbox_package_path(from_uuid, isCeData, userId, + package_name); + if (access(from.c_str(), F_OK) != 0) { + LOG(INFO) << "Missing source " << from; + continue; + } + const auto to = create_data_misc_sdk_sandbox_path(to_uuid, isCeData, userId); + + const int rc = copy_directory_recursive(from.c_str(), to.c_str()); + if (rc != 0) { + res = error(rc, "Failed copying " + from + " to " + to); + goto fail; + } + } + + if (!restoreconSdkDataLocked(toUuid, packageName, userId, FLAG_STORAGE_CE | FLAG_STORAGE_DE, + appId, seInfo) + .isOk()) { + res = error("Failed to restorecon"); + goto fail; + } + } // We let the framework scan the new location and persist that before // deleting the data in the old location; this ordering ensures that // we can recover from things like battery pulls. @@ -1799,6 +1828,18 @@ fail: } } } + for (auto userId : users) { + LOCK_USER(); + constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; + for (int currentFlag : storageFlags) { + const bool isCeData = currentFlag == FLAG_STORAGE_CE; + const auto to = create_data_misc_sdk_sandbox_package_path(to_uuid, isCeData, userId, + package_name); + if (delete_dir_contents(to.c_str(), 1, nullptr) != 0) { + LOG(WARNING) << "Failed to rollback " << to; + } + } + } return res; } @@ -3130,6 +3171,49 @@ binder::Status InstalldNativeService::restoreconAppDataLocked( return res; } +binder::Status InstalldNativeService::restoreconSdkDataLocked( + const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, + int32_t flags, int32_t appId, const std::string& seInfo) { + ENFORCE_UID(AID_SYSTEM); + CHECK_ARGUMENT_UUID(uuid); + CHECK_ARGUMENT_PACKAGE_NAME(packageName); + + binder::Status res = ok(); + + // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here. + unsigned int seflags = SELINUX_ANDROID_RESTORECON_RECURSE; + const char* uuid_ = uuid ? uuid->c_str() : nullptr; + const char* pkgName = packageName.c_str(); + const char* seinfo = seInfo.c_str(); + + uid_t uid = multiuser_get_sdk_sandbox_uid(userId, appId); + constexpr int storageFlags[2] = {FLAG_STORAGE_CE, FLAG_STORAGE_DE}; + for (int currentFlag : storageFlags) { + if ((flags & currentFlag) == 0) { + continue; + } + const bool isCeData = (currentFlag == FLAG_STORAGE_CE); + const auto packagePath = + create_data_misc_sdk_sandbox_package_path(uuid_, isCeData, userId, pkgName); + if (access(packagePath.c_str(), F_OK) != 0) { + LOG(INFO) << "Missing source " << packagePath; + continue; + } + const auto subDirHandler = [&packagePath, &seinfo, &uid, &seflags, + &res](const std::string& subDir) { + const auto& fullpath = packagePath + "/" + subDir; + if (selinux_android_restorecon_pkgdir(fullpath.c_str(), seinfo, uid, seflags) < 0) { + res = error("restorecon failed for " + fullpath); + } + }; + const auto ec = foreach_subdir(packagePath, subDirHandler); + if (ec != 0) { + res = error("Failed to restorecon for subdirs of " + packagePath); + } + } + return res; +} + binder::Status InstalldNativeService::createOatDir(const std::string& oatDir, const std::string& instructionSet) { ENFORCE_UID(AID_SYSTEM); diff --git a/cmds/installd/InstalldNativeService.h b/cmds/installd/InstalldNativeService.h index a6b8bfa013..7a9038ed79 100644 --- a/cmds/installd/InstalldNativeService.h +++ b/cmds/installd/InstalldNativeService.h @@ -63,9 +63,7 @@ public: binder::Status restoreconAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags, int32_t appId, const std::string& seInfo); - binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid, - const std::string& packageName, int32_t userId, - int32_t flags, int32_t appId, const std::string& seInfo); + binder::Status migrateAppData(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); binder::Status clearAppData(const std::optional<std::string>& uuid, @@ -205,13 +203,10 @@ private: int32_t flags, int32_t appId, int32_t previousAppId, const std::string& seInfo, int32_t targetSdkVersion, int64_t* _aidl_return); + binder::Status restoreconAppDataLocked(const std::optional<std::string>& uuid, + const std::string& packageName, int32_t userId, + int32_t flags, int32_t appId, const std::string& seInfo); - binder::Status reconcileSdkData(const std::optional<std::string>& uuid, - const std::string& packageName, - const std::vector<std::string>& sdkPackageNames, - const std::vector<std::string>& randomSuffixes, int32_t userId, - int32_t appId, int32_t previousAppId, const std::string& seInfo, - int flags); binder::Status createSdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t appId, @@ -223,6 +218,15 @@ private: binder::Status destroySdkSandboxDataPackageDirectory(const std::optional<std::string>& uuid, const std::string& packageName, int32_t userId, int32_t flags); + binder::Status reconcileSdkData(const std::optional<std::string>& uuid, + const std::string& packageName, + const std::vector<std::string>& sdkPackageNames, + const std::vector<std::string>& randomSuffixes, int32_t userId, + int32_t appId, int32_t previousAppId, const std::string& seInfo, + int flags); + binder::Status restoreconSdkDataLocked(const std::optional<std::string>& uuid, + const std::string& packageName, int32_t userId, + int32_t flags, int32_t appId, const std::string& seInfo); }; } // namespace installd |