Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 995b2469 authored by JW Wang's avatar JW Wang
Browse files

Fixes De data is not backed up correctly when user locked (1/n)

https://android.googlesource.com/platform/frameworks/native/+/fda19ecdd6df8f43d3368781a633792723fb9965/cmds/installd/InstalldNativeService.cpp#933

When an APK is stage installed, snapshotAppData(..., FLAG_STORAGE_DE)
is called before user unlocked. The function bails out early at #937
because the folder is still encrypted.

We should move the if block at #958 above so we can back up De data
correctly even when Ce directories not ready.

Note we have to check if the De folder exists before making a copy.

(Cherry-picked from 1d643c77)

Bug: 169594054
Test: atest StagedRollbackTest
Merged-In: I2ca810bd9495de3bed58378a41b47863c6e8f8dd
Change-Id: I2ca810bd9495de3bed58378a41b47863c6e8f8dd
parent 3d8f2d71
Loading
Loading
Loading
Loading
+27 −24
Original line number Diff line number Diff line
@@ -876,6 +876,33 @@ binder::Status InstalldNativeService::snapshotAppData(

    auto scope_guard = android::base::make_scope_guard(deleter);

    if (storageFlags & FLAG_STORAGE_DE) {
        auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
        auto to = create_data_misc_de_rollback_path(volume_uuid, user, snapshotId);
        auto rollback_package_path = create_data_misc_de_rollback_package_path(volume_uuid, user,
            snapshotId, package_name);

        int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
        if (rc != 0) {
            return error(rc, "Failed to create folder " + to);
        }

        rc = delete_dir_contents(rollback_package_path, true /* ignore_if_missing */);
        if (rc != 0) {
            return error(rc, "Failed clearing existing snapshot " + rollback_package_path);
        }

        // Check if we have data to copy.
        if (access(from.c_str(), F_OK) == 0) {
          rc = copy_directory_recursive(from.c_str(), to.c_str());
        }
        if (rc != 0) {
            res = error(rc, "Failed copying " + from + " to " + to);
            clear_de_on_exit = true;
            return res;
        }
    }

    // The app may not have any data at all, in which case it's OK to skip here.
    auto from_ce = create_data_user_ce_package_path(volume_uuid, user, package_name);
    if (access(from_ce.c_str(), F_OK) != 0) {
@@ -901,30 +928,6 @@ binder::Status InstalldNativeService::snapshotAppData(
        LOG(WARNING) << "Failed to clear code_cache of app " << packageName;
    }

    if (storageFlags & FLAG_STORAGE_DE) {
        auto from = create_data_user_de_package_path(volume_uuid, user, package_name);
        auto to = create_data_misc_de_rollback_path(volume_uuid, user, snapshotId);
        auto rollback_package_path = create_data_misc_de_rollback_package_path(volume_uuid, user,
            snapshotId, package_name);

        int rc = create_dir_if_needed(to.c_str(), kRollbackFolderMode);
        if (rc != 0) {
            return error(rc, "Failed to create folder " + to);
        }

        rc = delete_dir_contents(rollback_package_path, true /* ignore_if_missing */);
        if (rc != 0) {
            return error(rc, "Failed clearing existing snapshot " + rollback_package_path);
        }

        rc = copy_directory_recursive(from.c_str(), to.c_str());
        if (rc != 0) {
            res = error(rc, "Failed copying " + from + " to " + to);
            clear_de_on_exit = true;
            return res;
        }
    }

    if (storageFlags & FLAG_STORAGE_CE) {
        auto from = create_data_user_ce_package_path(volume_uuid, user, package_name);
        auto to = create_data_misc_ce_rollback_path(volume_uuid, user, snapshotId);