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

Commit aaf70e77 authored by Bowgo Tsai's avatar Bowgo Tsai
Browse files

fs_mgr: support AVB in fs_mgr_update_verity_state()

fs_mgr_update_verity_state() is invoked by 'verity_update_state' in
init.rc. It will then set property "partition.system.verified" and
"partition.vendor.verified" to verify_mode. We should support this for
AVB as well.

Also change the order of static libs in init to fix the build error
after this change:
  system/extras/ext4_utils/ext4_crypt.cpp:69: error: undefined reference to 'property_get'

Bug: 35416769
Test: Mount /system and /vendor with vboot 2.0 (AVB), check the following properties exist.
      - [partition.system.verified]: [2]
      - [partition.vendor.verified]: [2]
Test: Mount /system and /vendor with vboot 1.0, check the following properties exist.
      - [partition.system.verified]: [0]
      - [partition.vendor.verified]: [0]

Change-Id: I4328d66a8cb93f26e7960e620a0b2292d5f15900
parent 8bba52fc
Loading
Loading
Loading
Loading
+98 −0
Original line number Diff line number Diff line
@@ -31,7 +31,10 @@
#include <time.h>
#include <unistd.h>

#include <memory>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
#include <cutils/android_reboot.h>
@@ -50,6 +53,7 @@
#include "fs_mgr.h"
#include "fs_mgr_avb.h"
#include "fs_mgr_priv.h"
#include "fs_mgr_priv_dm_ioctl.h"

#define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
#define KEY_IN_FOOTER  "footer"
@@ -1258,3 +1262,97 @@ int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc, char *real_blk_dev

    return 0;
}

bool fs_mgr_load_verity_state(int* mode) {
    /* return the default mode, unless any of the verified partitions are in
     * logging mode, in which case return that */
    *mode = VERITY_MODE_DEFAULT;

    std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
                                                               fs_mgr_free_fstab);
    if (!fstab) {
        LERROR << "Failed to read default fstab";
        return false;
    }

    for (int i = 0; i < fstab->num_entries; i++) {
        if (fs_mgr_is_avb(&fstab->recs[i])) {
            *mode = VERITY_MODE_RESTART;  // avb only supports restart mode.
            break;
        } else if (!fs_mgr_is_verified(&fstab->recs[i])) {
            continue;
        }

        int current;
        if (load_verity_state(&fstab->recs[i], &current) < 0) {
            continue;
        }
        if (current != VERITY_MODE_DEFAULT) {
            *mode = current;
            break;
        }
    }

    return true;
}

bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback) {
    if (!callback) {
        return false;
    }

    int mode;
    if (!fs_mgr_load_verity_state(&mode)) {
        return false;
    }

    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC)));
    if (fd == -1) {
        PERROR << "Error opening device mapper";
        return false;
    }

    std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> fstab(fs_mgr_read_fstab_default(),
                                                               fs_mgr_free_fstab);
    if (!fstab) {
        LERROR << "Failed to read default fstab";
        return false;
    }

    alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
    struct dm_ioctl* io = (struct dm_ioctl*)buffer;
    bool system_root = android::base::GetProperty("ro.build.system_root_image", "") == "true";

    for (int i = 0; i < fstab->num_entries; i++) {
        if (!fs_mgr_is_verified(&fstab->recs[i]) && !fs_mgr_is_avb(&fstab->recs[i])) {
            continue;
        }

        std::string mount_point;
        if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
            mount_point = "system";
        } else {
            mount_point = basename(fstab->recs[i].mount_point);
        }

        fs_mgr_verity_ioctl_init(io, mount_point, 0);

        const char* status;
        if (ioctl(fd, DM_TABLE_STATUS, io)) {
            if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
                status = "V";
            } else {
                PERROR << "Failed to query DM_TABLE_STATUS for " << mount_point.c_str();
                continue;
            }
        }

        status = &buffer[io->data_start + sizeof(struct dm_target_spec)];

        if (*status == 'C' || *status == 'V') {
            callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
        }
    }

    return true;
}
+1 −0
Original line number Diff line number Diff line
@@ -115,5 +115,6 @@ int fs_mgr_test_access(const char *device);
bool fs_mgr_update_for_slotselect(struct fstab *fstab);
bool is_dt_compatible();
bool is_device_secure();
int load_verity_state(struct fstab_rec* fstab, int* mode);

#endif /* __CORE_FS_MGR_PRIV_H */
+1 −125
Original line number Diff line number Diff line
@@ -653,8 +653,7 @@ static int get_verity_state_offset(struct fstab_rec *fstab, off64_t *offset)
                offset);
}

static int load_verity_state(struct fstab_rec *fstab, int *mode)
{
int load_verity_state(struct fstab_rec* fstab, int* mode) {
    int match = 0;
    off64_t offset = 0;

@@ -690,129 +689,6 @@ static int load_verity_state(struct fstab_rec *fstab, int *mode)
    return read_verity_state(fstab->verity_loc, offset, mode);
}

int fs_mgr_load_verity_state(int *mode)
{
    int rc = -1;
    int i;
    int current;
    struct fstab *fstab = NULL;

    /* return the default mode, unless any of the verified partitions are in
     * logging mode, in which case return that */
    *mode = VERITY_MODE_DEFAULT;

    fstab = fs_mgr_read_fstab_default();
    if (!fstab) {
        LERROR << "Failed to read default fstab";
        goto out;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        if (!fs_mgr_is_verified(&fstab->recs[i])) {
            continue;
        }

        rc = load_verity_state(&fstab->recs[i], &current);
        if (rc < 0) {
            continue;
        }

        if (current != VERITY_MODE_DEFAULT) {
            *mode = current;
            break;
        }
    }

    rc = 0;

out:
    if (fstab) {
        fs_mgr_free_fstab(fstab);
    }

    return rc;
}

int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback)
{
    alignas(dm_ioctl) char buffer[DM_BUF_SIZE];
    bool system_root = false;
    std::string mount_point;
    char propbuf[PROPERTY_VALUE_MAX];
    const char *status;
    int fd = -1;
    int i;
    int mode;
    int rc = -1;
    struct dm_ioctl *io = (struct dm_ioctl *) buffer;
    struct fstab *fstab = NULL;

    if (!callback) {
        return -1;
    }

    if (fs_mgr_load_verity_state(&mode) == -1) {
        return -1;
    }

    fd = TEMP_FAILURE_RETRY(open("/dev/device-mapper", O_RDWR | O_CLOEXEC));
    if (fd == -1) {
        PERROR << "Error opening device mapper";
        goto out;
    }

    property_get("ro.build.system_root_image", propbuf, "");
    system_root = !strcmp(propbuf, "true");
    fstab = fs_mgr_read_fstab_default();
    if (!fstab) {
        LERROR << "Failed to read default fstab";
        goto out;
    }

    for (i = 0; i < fstab->num_entries; i++) {
        if (!fs_mgr_is_verified(&fstab->recs[i])) {
            continue;
        }

        if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
            mount_point = "system";
        } else {
            mount_point = basename(fstab->recs[i].mount_point);
        }

        fs_mgr_verity_ioctl_init(io, mount_point, 0);

        if (ioctl(fd, DM_TABLE_STATUS, io)) {
            if (fstab->recs[i].fs_mgr_flags & MF_VERIFYATBOOT) {
                status = "V";
            } else {
                PERROR << "Failed to query DM_TABLE_STATUS for "
                       << mount_point.c_str();
                continue;
            }
        }

        status = &buffer[io->data_start + sizeof(struct dm_target_spec)];

        if (*status == 'C' || *status == 'V') {
            callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
        }
    }

    rc = 0;

out:
    if (fstab) {
        fs_mgr_free_fstab(fstab);
    }

    if (fd) {
        close(fd);
    }

    return rc;
}

static void update_verity_table_blk_device(char *blk_device, char **table)
{
    std::string result, word;
+2 −2
Original line number Diff line number Diff line
@@ -113,8 +113,8 @@ int fs_mgr_do_tmpfs_mount(const char *n_name);
int fs_mgr_unmount_all(struct fstab *fstab);
int fs_mgr_get_crypt_info(struct fstab *fstab, char *key_loc,
                          char *real_blk_device, int size);
int fs_mgr_load_verity_state(int *mode);
int fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
bool fs_mgr_load_verity_state(int* mode);
bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
int fs_mgr_add_entry(struct fstab *fstab,
                     const char *mount_point, const char *fs_type,
                     const char *blk_device);
+1 −1
Original line number Diff line number Diff line
@@ -111,8 +111,8 @@ LOCAL_STATIC_LIBRARIES := \
    libfec_rs \
    libsquashfs_utils \
    liblogwrap \
    libcutils \
    libext4_utils \
    libcutils \
    libbase \
    libc \
    libselinux \
Loading