am 4ae302af: fs_mgr: trigger dm-verity error handling for invalid signatures
* commit '4ae302af7d0f72559ffb8dd521f290b02fed3072':
fs_mgr: trigger dm-verity error handling for invalid signatures
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 60f5398..a9e3358 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -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
@@ -141,6 +143,33 @@
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;
@@ -957,6 +986,7 @@
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];
@@ -983,6 +1013,7 @@
}
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) {
@@ -1002,13 +1033,6 @@
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
@@ -1017,6 +1041,22 @@
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