Skip to content

Commit

Permalink
fs_mgr: trigger dm-verity error handling for invalid signatures
Browse files Browse the repository at this point in the history
Currently, the device doesn't mount verified partitions if the
verity table signature is invalid, which usually means it fails to
boot. This change instead sets up dm-verity with an invalid root
hash and triggers device-specific error handling to recover from
the corruption.

Bug: 24256506
Change-Id: I6d693306fa0e7459c5500b028e433df61ecea6fb
(cherry picked from commit 47caa5c)
  • Loading branch information
samitolvanen committed Sep 22, 2015
1 parent a3f4568 commit 4ae302a
Showing 1 changed file with 47 additions and 7 deletions.
54 changes: 47 additions & 7 deletions fs_mgr/fs_mgr_verity.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@

#define VERITY_METADATA_SIZE 32768
#define VERITY_TABLE_RSA_KEY "/verity_key"
#define VERITY_TABLE_HASH_IDX 8
#define VERITY_TABLE_SALT_IDX 9

#define METADATA_MAGIC 0x01564c54
#define METADATA_TAG_MAX_LENGTH 63
Expand Down Expand Up @@ -141,6 +143,33 @@ static int verify_table(char *signature, char *table, int table_length)
return retval;
}

static int invalidate_table(char *table, int table_length)
{
int n = 0;
int idx = 0;
int cleared = 0;

while (n < table_length) {
if (table[n++] == ' ') {
++idx;
}

if (idx != VERITY_TABLE_HASH_IDX && idx != VERITY_TABLE_SALT_IDX) {
continue;
}

while (n < table_length && table[n] != ' ') {
table[n++] = '0';
}

if (++cleared == 2) {
return 0;
}
}

return -1;
}

static int squashfs_get_target_device_size(char *blk_device, uint64_t *device_size)
{
struct squashfs_info sq_info;
Expand Down Expand Up @@ -957,6 +986,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) {
char *verity_blk_name = 0;
char *verity_table = 0;
char *verity_table_signature = 0;
int verity_table_length = 0;
uint64_t device_size = 0;

_Alignas(struct dm_ioctl) char buffer[DM_BUF_SIZE];
Expand All @@ -983,6 +1013,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) {
}

retval = FS_MGR_SETUP_VERITY_FAIL;
verity_table_length = strlen(verity_table);

// get the device mapper fd
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
Expand All @@ -1002,13 +1033,6 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) {
goto out;
}

// verify the signature on the table
if (verify_table(verity_table_signature,
verity_table,
strlen(verity_table)) < 0) {
goto out;
}

if (load_verity_state(fstab, &mode) < 0) {
/* if accessing or updating the state failed, switch to the default
* safe mode. This makes sure the device won't end up in an endless
Expand All @@ -1017,6 +1041,22 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) {
mode = VERITY_MODE_EIO;
}

// verify the signature on the table
if (verify_table(verity_table_signature,
verity_table,
verity_table_length) < 0) {
if (mode == VERITY_MODE_LOGGING) {
// the user has been warned, allow mounting without dm-verity
retval = FS_MGR_SETUP_VERITY_SUCCESS;
goto out;
}

// invalidate root hash and salt to trigger device-specific recovery
if (invalidate_table(verity_table, verity_table_length) < 0) {
goto out;
}
}

INFO("Enabling dm-verity for %s (mode %d)\n", mount_point, mode);

// load the verity mapping table
Expand Down

0 comments on commit 4ae302a

Please sign in to comment.