summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSami Tolvanen <samitolvanen@google.com>2015-09-21 15:12:29 +0100
committerSami Tolvanen <samitolvanen@google.com>2015-09-22 08:09:37 +0000
commit4ae302af7d0f72559ffb8dd521f290b02fed3072 (patch)
tree26cc1a1abf9105592d1ac0192e8350e643c49156
parenta3f45684bda7b3a479e480ccb90cc745f8852efd (diff)
downloadsystem_core-4ae302af7d0f72559ffb8dd521f290b02fed3072.tar.gz
system_core-4ae302af7d0f72559ffb8dd521f290b02fed3072.tar.bz2
system_core-4ae302af7d0f72559ffb8dd521f290b02fed3072.zip
fs_mgr: trigger dm-verity error handling for invalid signatures
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 47caa5c386b436ba13de9f2ef356380f39afaf3f)
-rw-r--r--fs_mgr/fs_mgr_verity.c54
1 files changed, 47 insertions, 7 deletions
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 60f53982f..a9e3358b2 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 @@ out:
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 @@ 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];
@@ -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) {
@@ -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
@@ -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