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

Commit c684696a authored by Paul Crowley's avatar Paul Crowley
Browse files

Use vold's mount with metadata encryption service.

Don't use the FDE flow to support metadata encryption; just use the
vold service which directly mounts the volume.

Bug: 63927601
Test: Boot Taimen to SUW with and without metadata encryption.
Change-Id: Idf9c27a69872cd7a9e2fb76df09a91d8e5ef4896
parent 0ce76f91
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
@@ -32,11 +32,14 @@
#include <unistd.h>

#include <memory>
#include <string>
#include <thread>
#include <vector>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <cutils/android_filesystem_config.h>
#include <cutils/android_reboot.h>
@@ -775,6 +778,22 @@ static int handle_encryptable(const struct fstab_rec* rec)
    }
}

static bool call_vdc(const std::vector<std::string>& args) {
    std::vector<char const*> argv;
    argv.emplace_back("/system/bin/vdc");
    for (auto& arg : args) {
        argv.emplace_back(arg.c_str());
    }
    LOG(INFO) << "Calling: " << android::base::Join(argv, ' ');
    int ret = android_fork_execvp(4, const_cast<char**>(argv.data()), nullptr, false, true);
    if (ret != 0) {
        LOG(ERROR) << "vdc returned error code: " << ret;
        return false;
    }
    LOG(DEBUG) << "vdc finished successfully";
    return true;
}

/* When multiple fstab records share the same mount_point, it will
 * try to mount each one in turn, and ignore any duplicates after a
 * first successful mount.
@@ -881,6 +900,13 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
                    LERROR << "Only one encryptable/encrypted partition supported";
                }
                encryptable = status;
                if (status == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
                    if (!call_vdc(
                            {"cryptfs", "encryptFstab", fstab->recs[attempted_idx].mount_point})) {
                        LERROR << "Encryption failed";
                        return FS_MGR_MNTALL_FAIL;
                    }
                }
            }

            /* Success!  Go get the next one */
@@ -955,7 +981,11 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
            encryptable = FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED;
        } else if (mret && mount_errno != EBUSY && mount_errno != EACCES &&
                   should_use_metadata_encryption(&fstab->recs[attempted_idx])) {
            if (!call_vdc({"cryptfs", "mountFstab", fstab->recs[attempted_idx].mount_point})) {
                ++error_count;
            }
            encryptable = FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED;
            continue;
        } else {
            // fs_options might be null so we cannot use PERROR << directly.
            // Use StringPrintf to output "(null)" instead.
+6 −4
Original line number Diff line number Diff line
@@ -514,8 +514,9 @@ static Result<Success> queue_fs_event(int code) {
        property_set("ro.crypto.state", "encrypted");
        property_set("ro.crypto.type", "file");

        // defaultcrypto detects file/block encryption. init flow is same for each.
        ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
        // Although encrypted, vold has already set the device up, so we do not need to
        // do anything different from the nonencrypted case.
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
        return Success();
    } else if (code == FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION) {
        if (e4crypt_install_keyring()) {
@@ -523,8 +524,9 @@ static Result<Success> queue_fs_event(int code) {
        }
        property_set("ro.crypto.type", "file");

        // encrypt detects file/block encryption. init flow is same for each.
        ActionManager::GetInstance().QueueEventTrigger("encrypt");
        // Although encrypted, vold has already set the device up, so we do not need to
        // do anything different from the nonencrypted case.
        ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
        return Success();
    } else if (code > 0) {
        Error() << "fs_mgr_mount_all() returned unexpected error " << code;