Loading fastboot/fastboot.cpp +90 −5 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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} }; Loading Loading @@ -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: Loading Loading @@ -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); Loading Loading @@ -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) { Loading fastboot/fs.cpp +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> Loading @@ -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}, Loading @@ -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); } fastboot/fs.h +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 Loading
fastboot/fastboot.cpp +90 −5 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading Loading @@ -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) { Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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} }; Loading Loading @@ -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: Loading Loading @@ -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); Loading Loading @@ -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) { Loading
fastboot/fs.cpp +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> Loading @@ -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}, Loading @@ -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); }
fastboot/fs.h +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