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

Commit 5e47d516 authored by Jin Qian's avatar Jin Qian
Browse files

recovery: handle security footer before passing size to mke2fs

mke2fs doesn't take negative size as reserved size. If footer is
specified, compute fs size to be
(max partition size - reserved footer size) / block_size

Bug: 23686092
Bug: 63968011
Merged-In: Iac4e143bd26a70cfc81eb52a399d687e19b1049c
Change-Id: Iac4e143bd26a70cfc81eb52a399d687e19b1049c
(cherry picked from commit f3ccad58ddb256150858df55a5e6fe5a906c5754)
parent 7e05669a
Loading
Loading
Loading
Loading
+28 −11
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <ext4_utils/wipe.h>
#include <fs_mgr.h>

@@ -173,6 +174,23 @@ static int exec_cmd(const char* path, char* const argv[]) {
    return WEXITSTATUS(status);
}

static ssize_t get_file_size(int fd, uint64_t reserve_len) {
  struct stat buf;
  int ret = fstat(fd, &buf);
  if (ret) return 0;

  ssize_t computed_size;
  if (S_ISREG(buf.st_mode)) {
    computed_size = buf.st_size - reserve_len;
  } else if (S_ISBLK(buf.st_mode)) {
    computed_size = get_block_device_size(fd) - reserve_len;
  } else {
    computed_size = 0;
  }

  return computed_size;
}

int format_volume(const char* volume, const char* directory) {
    Volume* v = volume_for_path(volume);
    if (v == NULL) {
@@ -212,7 +230,16 @@ int format_volume(const char* volume, const char* directory) {
        if (v->length != 0) {
            length = v->length;
        } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
            length = -CRYPT_FOOTER_OFFSET;
          android::base::unique_fd fd(open(v->blk_device, O_RDONLY));
          if (fd < 0) {
            PLOG(ERROR) << "get_file_size: failed to open " << v->blk_device;
            return -1;
          }
          length = get_file_size(fd.get(), CRYPT_FOOTER_OFFSET);
          if (length <= 0) {
            LOG(ERROR) << "get_file_size: invalid size " << length << " for " << v->blk_device;
            return -1;
          }
        }
        int result;
        if (strcmp(v->fs_type, "ext4") == 0) {
@@ -272,16 +299,6 @@ int format_volume(const char* volume, const char* directory) {
            result = exec_cmd(e2fsdroid_argv[0], const_cast<char**>(e2fsdroid_argv));
            }
        } else {   /* Has to be f2fs because we checked earlier. */
            if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) {
                LOG(ERROR) << "format_volume: crypt footer + negative length (" << length
                           << ") not supported on " << v->fs_type;
                return -1;
            }
            if (length < 0) {
                LOG(ERROR) << "format_volume: negative length (" << length
                           << ") not supported on " << v->fs_type;
                return -1;
            }
            char *num_sectors = nullptr;
            if (length >= 512 && asprintf(&num_sectors, "%zd", length / 512) <= 0) {
                LOG(ERROR) << "format_volume: failed to create " << v->fs_type