Loading uncrypt/uncrypt.cpp +166 −175 Original line number Diff line number Diff line Loading @@ -89,7 +89,6 @@ #include <errno.h> #include <fcntl.h> #include <inttypes.h> #include <libgen.h> #include <linux/fs.h> #include <stdarg.h> #include <stdio.h> Loading @@ -103,6 +102,7 @@ #include <algorithm> #include <memory> #include <string> #include <vector> #include <android-base/file.h> Loading Loading @@ -163,22 +163,18 @@ static void add_block_to_ranges(std::vector<int>& ranges, int new_block) { } } static std::string find_block_device(const char* path, bool* encryptable, bool* encrypted, // Looks for a volume whose mount point is the prefix of path and returns its block device or an // empty string. Sets encryption flags accordingly. static std::string FindBlockDevice(const std::string& path, bool* encryptable, bool* encrypted, bool* f2fs_fs) { // Look for a volume whose mount point is the prefix of path and // return its block device. Set encrypted if it's currently // encrypted. // ensure f2fs_fs is set to false first. // Ensure f2fs_fs is set to false first. *f2fs_fs = false; for (const auto& entry : fstab) { if (entry.mount_point.empty()) { continue; } auto len = entry.mount_point.size(); if (android::base::StartsWith(path, entry.mount_point) && (path[len] == '/' || path[len] == 0)) { if (android::base::StartsWith(path, entry.mount_point + "/")) { *encrypted = false; *encryptable = false; if (entry.is_encryptable() || entry.fs_mgr_flags.file_encryption) { Loading Loading @@ -207,8 +203,8 @@ static bool write_status_to_socket(int status, int socket) { return android::base::WriteFully(socket, &status_out, sizeof(int)); } // Parse uncrypt_file to find the update package name. static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::string* package_name) { // Parses the given path file to find the update package name. static bool FindUncryptPackage(const std::string& uncrypt_path_file, std::string* package_name) { CHECK(package_name != nullptr); std::string uncrypt_path; if (!android::base::ReadFileToString(uncrypt_path_file, &uncrypt_path)) { Loading @@ -221,7 +217,7 @@ static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::stri return true; } static int retry_fibmap(const int fd, const char* name, int* block, const int head_block) { static int RetryFibmap(int fd, const std::string& name, int* block, const int head_block) { CHECK(block != nullptr); for (size_t i = 0; i < FIBMAP_RETRY_LIMIT; i++) { if (fsync(fd) == -1) { Loading @@ -241,16 +237,15 @@ static int retry_fibmap(const int fd, const char* name, int* block, const int he return kUncryptIoctlError; } static int produce_block_map(const char* path, const char* map_file, const char* blk_dev, bool encrypted, bool f2fs_fs, int socket) { static int ProductBlockMap(const std::string& path, const std::string& map_file, const std::string& blk_dev, bool encrypted, bool f2fs_fs, int socket) { std::string err; if (!android::base::RemoveFileIfExists(map_file, &err)) { LOG(ERROR) << "failed to remove the existing map file " << map_file << ": " << err; return kUncryptFileRemoveError; } std::string tmp_map_file = std::string(map_file) + ".tmp"; android::base::unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); std::string tmp_map_file = map_file + ".tmp"; android::base::unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); if (mapfd == -1) { PLOG(ERROR) << "failed to open " << tmp_map_file; return kUncryptFileOpenError; Loading @@ -263,8 +258,8 @@ static int produce_block_map(const char* path, const char* map_file, const char* } struct stat sb; if (stat(path, &sb) != 0) { LOG(ERROR) << "failed to stat " << path; if (stat(path.c_str(), &sb) != 0) { PLOG(ERROR) << "failed to stat " << path; return kUncryptFileStatError; } Loading @@ -275,8 +270,8 @@ static int produce_block_map(const char* path, const char* map_file, const char* std::vector<int> ranges; std::string s = android::base::StringPrintf("%s\n%" PRId64 " %" PRId64 "\n", blk_dev, static_cast<int64_t>(sb.st_size), std::string s = android::base::StringPrintf("%s\n%" PRId64 " %" PRId64 "\n", blk_dev.c_str(), static_cast<int64_t>(sb.st_size), static_cast<int64_t>(sb.st_blksize)); if (!android::base::WriteStringToFd(s, mapfd)) { PLOG(ERROR) << "failed to write " << tmp_map_file; Loading @@ -290,7 +285,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* int head_block = 0; int head = 0, tail = 0; android::base::unique_fd fd(open(path, O_RDWR)); android::base::unique_fd fd(open(path.c_str(), O_RDWR)); if (fd == -1) { PLOG(ERROR) << "failed to open " << path << " for reading"; return kUncryptFileOpenError; Loading @@ -298,7 +293,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* android::base::unique_fd wfd; if (encrypted) { wfd.reset(open(blk_dev, O_WRONLY)); wfd.reset(open(blk_dev.c_str(), O_WRONLY)); if (wfd == -1) { PLOG(ERROR) << "failed to open " << blk_dev << " for writing"; return kUncryptBlockOpenError; Loading Loading @@ -351,7 +346,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* if (block == 0) { LOG(ERROR) << "failed to find block " << head_block << ", retrying"; int error = retry_fibmap(fd, path, &block, head_block); int error = RetryFibmap(fd, path, &block, head_block); if (error != kUncryptNoError) { return error; } Loading Loading @@ -396,7 +391,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* if (block == 0) { LOG(ERROR) << "failed to find block " << head_block << ", retrying"; int error = retry_fibmap(fd, path, &block, head_block); int error = RetryFibmap(fd, path, &block, head_block); if (error != kUncryptNoError) { return error; } Loading Loading @@ -446,13 +441,12 @@ static int produce_block_map(const char* path, const char* map_file, const char* } } if (rename(tmp_map_file.c_str(), map_file) == -1) { if (rename(tmp_map_file.c_str(), map_file.c_str()) == -1) { PLOG(ERROR) << "failed to rename " << tmp_map_file << " to " << map_file; return kUncryptFileRenameError; } // Sync dir to make rename() result written to disk. std::string file_name = map_file; std::string dir_name = dirname(&file_name[0]); std::string dir_name = android::base::Dirname(map_file); android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY)); if (dfd == -1) { PLOG(ERROR) << "failed to open dir " << dir_name; Loading @@ -469,42 +463,39 @@ static int produce_block_map(const char* path, const char* map_file, const char* return 0; } static int uncrypt(const char* input_path, const char* map_file, const int socket) { static int Uncrypt(const std::string& input_path, const std::string& map_file, int socket) { LOG(INFO) << "update package is \"" << input_path << "\""; // Turn the name of the file we're supposed to convert into an absolute path, so we can find // what filesystem it's on. char path[PATH_MAX+1]; if (realpath(input_path, path) == nullptr) { PLOG(ERROR) << "failed to convert \"" << input_path << "\" to absolute path"; // Turn the name of the file we're supposed to convert into an absolute path, so we can find what // filesystem it's on. std::string path; if (!android::base::Realpath(input_path, &path)) { PLOG(ERROR) << "Failed to convert \"" << input_path << "\" to absolute path"; return kUncryptRealpathFindError; } bool encryptable; bool encrypted; bool f2fs_fs; const std::string blk_dev = find_block_device(path, &encryptable, &encrypted, &f2fs_fs); const std::string blk_dev = FindBlockDevice(path, &encryptable, &encrypted, &f2fs_fs); if (blk_dev.empty()) { LOG(ERROR) << "failed to find block device for " << path; LOG(ERROR) << "Failed to find block device for " << path; return kUncryptBlockDeviceFindError; } // If the filesystem it's on isn't encrypted, we only produce the // block map, we don't rewrite the file contents (it would be // pointless to do so). // If the filesystem it's on isn't encrypted, we only produce the block map, we don't rewrite the // file contents (it would be pointless to do so). LOG(INFO) << "encryptable: " << (encryptable ? "yes" : "no"); LOG(INFO) << " encrypted: " << (encrypted ? "yes" : "no"); // Recovery supports installing packages from 3 paths: /cache, // /data, and /sdcard. (On a particular device, other locations // may work, but those are three we actually expect.) // Recovery supports installing packages from 3 paths: /cache, /data, and /sdcard. (On a // particular device, other locations may work, but those are three we actually expect.) // // On /data we want to convert the file to a block map so that we // can read the package without mounting the partition. On /cache // and /sdcard we leave the file alone. if (strncmp(path, "/data/", 6) == 0) { // On /data we want to convert the file to a block map so that we can read the package without // mounting the partition. On /cache and /sdcard we leave the file alone. if (android::base::StartsWith(path, "/data/")) { LOG(INFO) << "writing block map " << map_file; return produce_block_map(path, map_file, blk_dev.c_str(), encrypted, f2fs_fs, socket); return ProductBlockMap(path, map_file, blk_dev, encrypted, f2fs_fs, socket); } return 0; Loading @@ -523,7 +514,7 @@ static bool uncrypt_wrapper(const char* input_path, const char* map_file, const std::string package; if (input_path == nullptr) { if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) { if (!FindUncryptPackage(UNCRYPT_PATH_FILE, &package)) { write_status_to_socket(-1, socket); // Overwrite the error message. log_uncrypt_error_code(kUncryptPackageMissingError); Loading @@ -534,7 +525,7 @@ static bool uncrypt_wrapper(const char* input_path, const char* map_file, const CHECK(map_file != nullptr); auto start = std::chrono::system_clock::now(); int status = uncrypt(input_path, map_file, socket); int status = Uncrypt(input_path, map_file, socket); std::chrono::duration<double> duration = std::chrono::system_clock::now() - start; int count = static_cast<int>(duration.count()); Loading Loading
uncrypt/uncrypt.cpp +166 −175 Original line number Diff line number Diff line Loading @@ -89,7 +89,6 @@ #include <errno.h> #include <fcntl.h> #include <inttypes.h> #include <libgen.h> #include <linux/fs.h> #include <stdarg.h> #include <stdio.h> Loading @@ -103,6 +102,7 @@ #include <algorithm> #include <memory> #include <string> #include <vector> #include <android-base/file.h> Loading Loading @@ -163,22 +163,18 @@ static void add_block_to_ranges(std::vector<int>& ranges, int new_block) { } } static std::string find_block_device(const char* path, bool* encryptable, bool* encrypted, // Looks for a volume whose mount point is the prefix of path and returns its block device or an // empty string. Sets encryption flags accordingly. static std::string FindBlockDevice(const std::string& path, bool* encryptable, bool* encrypted, bool* f2fs_fs) { // Look for a volume whose mount point is the prefix of path and // return its block device. Set encrypted if it's currently // encrypted. // ensure f2fs_fs is set to false first. // Ensure f2fs_fs is set to false first. *f2fs_fs = false; for (const auto& entry : fstab) { if (entry.mount_point.empty()) { continue; } auto len = entry.mount_point.size(); if (android::base::StartsWith(path, entry.mount_point) && (path[len] == '/' || path[len] == 0)) { if (android::base::StartsWith(path, entry.mount_point + "/")) { *encrypted = false; *encryptable = false; if (entry.is_encryptable() || entry.fs_mgr_flags.file_encryption) { Loading Loading @@ -207,8 +203,8 @@ static bool write_status_to_socket(int status, int socket) { return android::base::WriteFully(socket, &status_out, sizeof(int)); } // Parse uncrypt_file to find the update package name. static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::string* package_name) { // Parses the given path file to find the update package name. static bool FindUncryptPackage(const std::string& uncrypt_path_file, std::string* package_name) { CHECK(package_name != nullptr); std::string uncrypt_path; if (!android::base::ReadFileToString(uncrypt_path_file, &uncrypt_path)) { Loading @@ -221,7 +217,7 @@ static bool find_uncrypt_package(const std::string& uncrypt_path_file, std::stri return true; } static int retry_fibmap(const int fd, const char* name, int* block, const int head_block) { static int RetryFibmap(int fd, const std::string& name, int* block, const int head_block) { CHECK(block != nullptr); for (size_t i = 0; i < FIBMAP_RETRY_LIMIT; i++) { if (fsync(fd) == -1) { Loading @@ -241,16 +237,15 @@ static int retry_fibmap(const int fd, const char* name, int* block, const int he return kUncryptIoctlError; } static int produce_block_map(const char* path, const char* map_file, const char* blk_dev, bool encrypted, bool f2fs_fs, int socket) { static int ProductBlockMap(const std::string& path, const std::string& map_file, const std::string& blk_dev, bool encrypted, bool f2fs_fs, int socket) { std::string err; if (!android::base::RemoveFileIfExists(map_file, &err)) { LOG(ERROR) << "failed to remove the existing map file " << map_file << ": " << err; return kUncryptFileRemoveError; } std::string tmp_map_file = std::string(map_file) + ".tmp"; android::base::unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); std::string tmp_map_file = map_file + ".tmp"; android::base::unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); if (mapfd == -1) { PLOG(ERROR) << "failed to open " << tmp_map_file; return kUncryptFileOpenError; Loading @@ -263,8 +258,8 @@ static int produce_block_map(const char* path, const char* map_file, const char* } struct stat sb; if (stat(path, &sb) != 0) { LOG(ERROR) << "failed to stat " << path; if (stat(path.c_str(), &sb) != 0) { PLOG(ERROR) << "failed to stat " << path; return kUncryptFileStatError; } Loading @@ -275,8 +270,8 @@ static int produce_block_map(const char* path, const char* map_file, const char* std::vector<int> ranges; std::string s = android::base::StringPrintf("%s\n%" PRId64 " %" PRId64 "\n", blk_dev, static_cast<int64_t>(sb.st_size), std::string s = android::base::StringPrintf("%s\n%" PRId64 " %" PRId64 "\n", blk_dev.c_str(), static_cast<int64_t>(sb.st_size), static_cast<int64_t>(sb.st_blksize)); if (!android::base::WriteStringToFd(s, mapfd)) { PLOG(ERROR) << "failed to write " << tmp_map_file; Loading @@ -290,7 +285,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* int head_block = 0; int head = 0, tail = 0; android::base::unique_fd fd(open(path, O_RDWR)); android::base::unique_fd fd(open(path.c_str(), O_RDWR)); if (fd == -1) { PLOG(ERROR) << "failed to open " << path << " for reading"; return kUncryptFileOpenError; Loading @@ -298,7 +293,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* android::base::unique_fd wfd; if (encrypted) { wfd.reset(open(blk_dev, O_WRONLY)); wfd.reset(open(blk_dev.c_str(), O_WRONLY)); if (wfd == -1) { PLOG(ERROR) << "failed to open " << blk_dev << " for writing"; return kUncryptBlockOpenError; Loading Loading @@ -351,7 +346,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* if (block == 0) { LOG(ERROR) << "failed to find block " << head_block << ", retrying"; int error = retry_fibmap(fd, path, &block, head_block); int error = RetryFibmap(fd, path, &block, head_block); if (error != kUncryptNoError) { return error; } Loading Loading @@ -396,7 +391,7 @@ static int produce_block_map(const char* path, const char* map_file, const char* if (block == 0) { LOG(ERROR) << "failed to find block " << head_block << ", retrying"; int error = retry_fibmap(fd, path, &block, head_block); int error = RetryFibmap(fd, path, &block, head_block); if (error != kUncryptNoError) { return error; } Loading Loading @@ -446,13 +441,12 @@ static int produce_block_map(const char* path, const char* map_file, const char* } } if (rename(tmp_map_file.c_str(), map_file) == -1) { if (rename(tmp_map_file.c_str(), map_file.c_str()) == -1) { PLOG(ERROR) << "failed to rename " << tmp_map_file << " to " << map_file; return kUncryptFileRenameError; } // Sync dir to make rename() result written to disk. std::string file_name = map_file; std::string dir_name = dirname(&file_name[0]); std::string dir_name = android::base::Dirname(map_file); android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY)); if (dfd == -1) { PLOG(ERROR) << "failed to open dir " << dir_name; Loading @@ -469,42 +463,39 @@ static int produce_block_map(const char* path, const char* map_file, const char* return 0; } static int uncrypt(const char* input_path, const char* map_file, const int socket) { static int Uncrypt(const std::string& input_path, const std::string& map_file, int socket) { LOG(INFO) << "update package is \"" << input_path << "\""; // Turn the name of the file we're supposed to convert into an absolute path, so we can find // what filesystem it's on. char path[PATH_MAX+1]; if (realpath(input_path, path) == nullptr) { PLOG(ERROR) << "failed to convert \"" << input_path << "\" to absolute path"; // Turn the name of the file we're supposed to convert into an absolute path, so we can find what // filesystem it's on. std::string path; if (!android::base::Realpath(input_path, &path)) { PLOG(ERROR) << "Failed to convert \"" << input_path << "\" to absolute path"; return kUncryptRealpathFindError; } bool encryptable; bool encrypted; bool f2fs_fs; const std::string blk_dev = find_block_device(path, &encryptable, &encrypted, &f2fs_fs); const std::string blk_dev = FindBlockDevice(path, &encryptable, &encrypted, &f2fs_fs); if (blk_dev.empty()) { LOG(ERROR) << "failed to find block device for " << path; LOG(ERROR) << "Failed to find block device for " << path; return kUncryptBlockDeviceFindError; } // If the filesystem it's on isn't encrypted, we only produce the // block map, we don't rewrite the file contents (it would be // pointless to do so). // If the filesystem it's on isn't encrypted, we only produce the block map, we don't rewrite the // file contents (it would be pointless to do so). LOG(INFO) << "encryptable: " << (encryptable ? "yes" : "no"); LOG(INFO) << " encrypted: " << (encrypted ? "yes" : "no"); // Recovery supports installing packages from 3 paths: /cache, // /data, and /sdcard. (On a particular device, other locations // may work, but those are three we actually expect.) // Recovery supports installing packages from 3 paths: /cache, /data, and /sdcard. (On a // particular device, other locations may work, but those are three we actually expect.) // // On /data we want to convert the file to a block map so that we // can read the package without mounting the partition. On /cache // and /sdcard we leave the file alone. if (strncmp(path, "/data/", 6) == 0) { // On /data we want to convert the file to a block map so that we can read the package without // mounting the partition. On /cache and /sdcard we leave the file alone. if (android::base::StartsWith(path, "/data/")) { LOG(INFO) << "writing block map " << map_file; return produce_block_map(path, map_file, blk_dev.c_str(), encrypted, f2fs_fs, socket); return ProductBlockMap(path, map_file, blk_dev, encrypted, f2fs_fs, socket); } return 0; Loading @@ -523,7 +514,7 @@ static bool uncrypt_wrapper(const char* input_path, const char* map_file, const std::string package; if (input_path == nullptr) { if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) { if (!FindUncryptPackage(UNCRYPT_PATH_FILE, &package)) { write_status_to_socket(-1, socket); // Overwrite the error message. log_uncrypt_error_code(kUncryptPackageMissingError); Loading @@ -534,7 +525,7 @@ static bool uncrypt_wrapper(const char* input_path, const char* map_file, const CHECK(map_file != nullptr); auto start = std::chrono::system_clock::now(); int status = uncrypt(input_path, map_file, socket); int status = Uncrypt(input_path, map_file, socket); std::chrono::duration<double> duration = std::chrono::system_clock::now() - start; int count = static_cast<int>(duration.count()); Loading