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

Commit c2ac8aec authored by Paul Crowley's avatar Paul Crowley Committed by Android (Google) Code Review
Browse files

Merge "Add --wipe-and-use-fbe option to fastboot for FBE userdata marker."

parents f6814787 8f7f56e2
Loading
Loading
Loading
Loading
+90 −5
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ static unsigned ramdisk_offset = 0x01000000;
static unsigned second_offset  = 0x00f00000;
static unsigned tags_offset    = 0x00000100;

static const std::string convert_fbe_marker_filename("convert_fbe");

enum fb_buffer_type {
    FB_BUFFER,
    FB_BUFFER_SPARSE,
@@ -322,11 +324,17 @@ static void usage() {
            "                                           provided, this will default to the value\n"
            "                                           given by --slot. If slots are not\n"
            "                                           supported, this does nothing.\n"
#if !defined(_WIN32)
            "  --wipe-and-use-fbe                       On devices which support it,\n"
            "                                           erase userdata and cache, and\n"
            "                                           enable file-based encryption\n"
#endif
            "  --unbuffered                             Do not buffer input or output.\n"
            "  --version                                Display version.\n"
            "  -h, --help                               show this message.\n"
        );
}

static void* load_bootable_image(const char* kernel, const char* ramdisk,
                                 const char* secondstage, int64_t* sz,
                                 const char* cmdline) {
@@ -446,8 +454,60 @@ static FILE* win32_tmpfile() {

#define tmpfile win32_tmpfile

static std::string make_temporary_directory() {
    fprintf(stderr, "make_temporary_directory not supported under Windows, sorry!");
    return "";
}

#else

static std::string make_temporary_directory() {
    const char *tmpdir = getenv("TMPDIR");
    if (tmpdir == nullptr) {
        tmpdir = P_tmpdir;
    }
    std::string result = std::string(tmpdir) + "/fastboot_userdata_XXXXXX";
    if (mkdtemp(&result[0]) == NULL) {
        fprintf(stderr, "Unable to create temporary directory: %s\n",
            strerror(errno));
        return "";
    }
    return result;
}

#endif

static std::string create_fbemarker_tmpdir() {
    std::string dir = make_temporary_directory();
    if (dir.empty()) {
        fprintf(stderr, "Unable to create local temp directory for FBE marker\n");
        return "";
    }
    std::string marker_file = dir + "/" + convert_fbe_marker_filename;
    int fd = open(marker_file.c_str(), O_CREAT | O_WRONLY | O_CLOEXEC, 0666);
    if (fd == -1) {
        fprintf(stderr, "Unable to create FBE marker file %s locally: %d, %s\n",
            marker_file.c_str(), errno, strerror(errno));
        return "";
    }
    close(fd);
    return dir;
}

static void delete_fbemarker_tmpdir(const std::string& dir) {
    std::string marker_file = dir + "/" + convert_fbe_marker_filename;
    if (unlink(marker_file.c_str()) == -1) {
        fprintf(stderr, "Unable to delete FBE marker file %s locally: %d, %s\n",
            marker_file.c_str(), errno, strerror(errno));
        return;
    }
    if (rmdir(dir.c_str()) == -1) {
        fprintf(stderr, "Unable to delete FBE marker directory %s locally: %d, %s\n",
            dir.c_str(), errno, strerror(errno));
        return;
    }
}

static int unzip_to_file(ZipArchiveHandle zip, char* entry_name) {
    FILE* fp = tmpfile();
    if (fp == nullptr) {
@@ -994,7 +1054,8 @@ static int64_t parse_num(const char *arg)

static void fb_perform_format(Transport* transport,
                              const char* partition, int skip_if_not_supported,
                              const char* type_override, const char* size_override) {
                              const char* type_override, const char* size_override,
                              const std::string& initial_dir) {
    std::string partition_type, partition_size;

    struct fastboot_buffer buf;
@@ -1058,7 +1119,7 @@ static void fb_perform_format(Transport* transport,
    }

    fd = fileno(tmpfile());
    if (fs_generator_generate(gen, fd, size)) {
    if (fs_generator_generate(gen, fd, size, initial_dir)) {
        fprintf(stderr, "Cannot generate image: %s\n", strerror(errno));
        close(fd);
        return;
@@ -1087,6 +1148,7 @@ int main(int argc, char **argv)
    bool wants_reboot_bootloader = false;
    bool wants_set_active = false;
    bool erase_first = true;
    bool set_fbe_marker = false;
    void *data;
    int64_t sz;
    int longindex;
@@ -1109,6 +1171,9 @@ int main(int argc, char **argv)
        {"slot", required_argument, 0, 0},
        {"set_active", optional_argument, 0, 'a'},
        {"set-active", optional_argument, 0, 'a'},
#if !defined(_WIN32)
        {"wipe-and-use-fbe", no_argument, 0, 0},
#endif
        {0, 0, 0, 0}
    };

@@ -1190,6 +1255,15 @@ int main(int argc, char **argv)
                return 0;
            } else if (strcmp("slot", longopts[longindex].name) == 0) {
                slot_override = std::string(optarg);
#if !defined(_WIN32)
            } else if (strcmp("wipe-and-use-fbe", longopts[longindex].name) == 0) {
                wants_wipe = true;
                set_fbe_marker = true;
#endif
            } else {
                fprintf(stderr, "Internal error in options processing for %s\n",
                    longopts[longindex].name);
                return 1;
            }
            break;
        default:
@@ -1283,7 +1357,8 @@ int main(int argc, char **argv)
                if (erase_first && needs_erase(transport, partition.c_str())) {
                    fb_queue_erase(partition.c_str());
                }
                fb_perform_format(transport, partition.c_str(), 0, type_override, size_override);
                fb_perform_format(transport, partition.c_str(), 0,
                    type_override, size_override, "");
            };
            do_for_partitions(transport, argv[1], slot_override.c_str(), format, true);
            skip(2);
@@ -1413,13 +1488,23 @@ int main(int argc, char **argv)
    if (wants_wipe) {
        fprintf(stderr, "wiping userdata...\n");
        fb_queue_erase("userdata");
        fb_perform_format(transport, "userdata", 1, nullptr, nullptr);
        if (set_fbe_marker) {
            fprintf(stderr, "setting FBE marker...\n");
            std::string initial_userdata_dir = create_fbemarker_tmpdir();
            if (initial_userdata_dir.empty()) {
                return 1;
            }
            fb_perform_format(transport, "userdata", 1, nullptr, nullptr, initial_userdata_dir);
            delete_fbemarker_tmpdir(initial_userdata_dir);
        } else {
            fb_perform_format(transport, "userdata", 1, nullptr, nullptr, "");
        }

        std::string cache_type;
        if (fb_getvar(transport, "partition-type:cache", &cache_type) && !cache_type.empty()) {
            fprintf(stderr, "wiping cache...\n");
            fb_queue_erase("cache");
            fb_perform_format(transport, "cache", 1, nullptr, nullptr);
            fb_perform_format(transport, "cache", 1, nullptr, nullptr, "");
        }
    }
    if (wants_set_active) {
+19 −9
Original line number Diff line number Diff line
#include "fs.h"

#include "fastboot.h"
#include "make_ext4fs.h"
#include "make_f2fs.h"
#include "fs.h"

#include <errno.h>
#include <stdio.h>
@@ -13,24 +14,32 @@

#include <sparse/sparse.h>

static int generate_ext4_image(int fd, long long partSize)
static int generate_ext4_image(int fd, long long partSize, const std::string& initial_dir)
{
    if (initial_dir.empty()) {
        make_ext4fs_sparse_fd(fd, partSize, NULL, NULL);

    } else {
        make_ext4fs_sparse_fd_directory(fd, partSize, NULL, NULL, initial_dir.c_str());
    }
    return 0;
}

#ifdef USE_F2FS
static int generate_f2fs_image(int fd, long long partSize)
static int generate_f2fs_image(int fd, long long partSize, const std::string& initial_dir)
{
    if (!initial_dir.empty()) {
        fprintf(stderr, "Unable to set initial directory on F2FS filesystem\n");
        return -1;
    }
    return make_f2fs_sparse_fd(fd, partSize, NULL, NULL);
}
#endif

static const struct fs_generator {

    const char* fs_type;  //must match what fastboot reports for partition type
    int (*generate)(int fd, long long partSize); //returns 0 or error value

    //returns 0 or error value
    int (*generate)(int fd, long long partSize, const std::string& initial_dir);

} generators[] = {
    { "ext4", generate_ext4_image},
@@ -48,7 +57,8 @@ const struct fs_generator* fs_get_generator(const std::string& fs_type) {
    return nullptr;
}

int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize)
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize,
    const std::string& initial_dir)
{
    return gen->generate(tmpFileNo, partSize);
    return gen->generate(tmpFileNo, partSize, initial_dir);
}
+3 −1
Original line number Diff line number Diff line
#ifndef _FS_H_
#define _FS_H_

#include <string>
#include <stdint.h>

struct fs_generator;

const struct fs_generator* fs_get_generator(const std::string& fs_type);
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize);
int fs_generator_generate(const struct fs_generator* gen, int tmpFileNo, long long partSize,
    const std::string& initial_dir);

#endif