diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp index 129a5bb50..72554a8ee 100644 --- a/fs_mgr/fs_mgr_verity.cpp +++ b/fs_mgr/fs_mgr_verity.cpp @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -211,7 +212,7 @@ static int get_verity_device_name(struct dm_ioctl *io, char *name, int fd, char } struct verity_table_params { - const char *table; + char *table; int mode; struct fec_ecc_metadata ecc; const char *ecc_dev; @@ -843,15 +844,42 @@ out: return rc; } +static void update_verity_table_blk_device(char *blk_device, char **table) +{ + std::string result, word; + auto tokens = android::base::Split(*table, " "); + + for (const auto token : tokens) { + if (android::base::StartsWith(token, "/dev/block/") && + android::base::StartsWith(blk_device, token.c_str())) { + word = blk_device; + } else { + word = token; + } + + if (result.empty()) { + result = word; + } else { + result += " " + word; + } + } + + if (result.empty()) { + return; + } + + free(*table); + *table = strdup(result.c_str()); +} + int fs_mgr_setup_verity(struct fstab_rec *fstab) { int retval = FS_MGR_SETUP_VERITY_FAIL; int fd = -1; - char *invalid_table = NULL; char *verity_blk_name = NULL; struct fec_handle *f = NULL; struct fec_verity_metadata verity; - struct verity_table_params params; + struct verity_table_params params = { .table = NULL }; alignas(dm_ioctl) char buffer[DM_BUF_SIZE]; struct dm_ioctl *io = (struct dm_ioctl *) buffer; @@ -912,8 +940,17 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) params.mode = VERITY_MODE_EIO; } + if (!verity.table) { + goto out; + } + + params.table = strdup(verity.table); + if (!params.table) { + goto out; + } + // verify the signature on the table - if (verify_table(verity.signature, sizeof(verity.signature), verity.table, + if (verify_table(verity.signature, sizeof(verity.signature), params.table, verity.table_length) < 0) { if (params.mode == VERITY_MODE_LOGGING) { // the user has been warned, allow mounting without dm-verity @@ -922,20 +959,18 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) } // invalidate root hash and salt to trigger device-specific recovery - invalid_table = strdup(verity.table); - - if (!invalid_table || - invalidate_table(invalid_table, verity.table_length) < 0) { + if (invalidate_table(params.table, verity.table_length) < 0) { goto out; } - - params.table = invalid_table; - } else { - params.table = verity.table; } INFO("Enabling dm-verity for %s (mode %d)\n", mount_point, params.mode); + if (fstab->fs_mgr_flags & MF_SLOTSELECT) { + // Update the verity params using the actual block device path + update_verity_table_blk_device(fstab->blk_device, ¶ms.table); + } + // load the verity mapping table if (load_verity_table(io, mount_point, verity.data_size, fd, ¶ms, format_verity_table) == 0) { @@ -1001,7 +1036,7 @@ out: } fec_close(f); - free(invalid_table); + free(params.table); free(verity_blk_name); return retval;