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

Commit d1670a06 authored by Tao Bao's avatar Tao Bao
Browse files

uncrypt: Replace a few C-strings with std::string.

Also use android::base::{Dirname,Realpath,StartsWith}.

Test: Run uncrypt on device (`uncrypt package block.map`).
Change-Id: Ifacd01d6b35d85ea4afcb93a0dbc0235bb765a75
parent 62040c53
Loading
Loading
Loading
Loading
+168 −175
Original line number Diff line number Diff line
@@ -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>
@@ -103,6 +102,7 @@

#include <algorithm>
#include <memory>
#include <string>
#include <vector>

#include <android-base/file.h>
@@ -163,13 +163,11 @@ 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) {
@@ -207,8 +205,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)) {
@@ -221,7 +219,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) {
@@ -241,16 +239,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;
@@ -263,8 +260,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;
  }

@@ -275,8 +272,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;
@@ -290,7 +287,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;
@@ -298,7 +295,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;
@@ -351,7 +348,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;
                }
@@ -396,7 +393,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;
            }
@@ -446,13 +443,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;
@@ -469,42 +465,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;
@@ -523,7 +516,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);
@@ -534,7 +527,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());