diff options
Diffstat (limited to 'fs_mgr/fs_mgr_verity.c')
-rw-r--r-- | fs_mgr/fs_mgr_verity.c | 67 |
1 files changed, 46 insertions, 21 deletions
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c index b79a4a8..bcd9094 100644 --- a/fs_mgr/fs_mgr_verity.c +++ b/fs_mgr/fs_mgr_verity.c @@ -43,7 +43,6 @@ #include "fs_mgr_priv_verity.h" #define VERITY_METADATA_SIZE 32768 -#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001 #define VERITY_TABLE_RSA_KEY "/verity_key" extern struct fs_info info; @@ -155,7 +154,9 @@ static int read_verity_metadata(char *block_device, char **signature, char **tab uint64_t device_length; int protocol_version; FILE *device; - int retval = -1; + int retval = FS_MGR_SETUP_VERITY_FAIL; + *signature = 0; + *table = 0; device = fopen(block_device, "r"); if (!device) { @@ -178,8 +179,18 @@ static int read_verity_metadata(char *block_device, char **signature, char **tab ERROR("Couldn't read magic number!\n"); goto out; } + +#ifdef ALLOW_ADBD_DISABLE_VERITY + if (magic_number == VERITY_METADATA_MAGIC_DISABLE) { + retval = FS_MGR_SETUP_VERITY_DISABLED; + INFO("Attempt to cleanly disable verity - only works in USERDEBUG"); + goto out; + } +#endif + if (magic_number != VERITY_METADATA_MAGIC_NUMBER) { - ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n", device_length); + ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n", + device_length); goto out; } @@ -201,14 +212,12 @@ static int read_verity_metadata(char *block_device, char **signature, char **tab } if (!fread(*signature, RSANUMBYTES, 1, device)) { ERROR("Couldn't read signature from verity metadata!\n"); - free(*signature); goto out; } // get the size of the table if (!fread(&table_length, sizeof(int), 1, device)) { ERROR("Couldn't get the size of the verity table from metadata!\n"); - free(*signature); goto out; } @@ -221,16 +230,22 @@ static int read_verity_metadata(char *block_device, char **signature, char **tab } if (!fgets(*table, table_length, device)) { ERROR("Couldn't read the verity table from metadata!\n"); - free(*table); - free(*signature); goto out; } - retval = 0; + retval = FS_MGR_SETUP_VERITY_SUCCESS; out: if (device) fclose(device); + + if (retval != FS_MGR_SETUP_VERITY_SUCCESS) { + free(*table); + free(*signature); + *table = 0; + *signature = 0; + } + return retval; } @@ -358,10 +373,11 @@ static int set_verified_property(char *name) { int fs_mgr_setup_verity(struct fstab_rec *fstab) { int retval = -1; + int fd = -1; - char *verity_blk_name; - char *verity_table; - char *verity_table_signature; + char *verity_blk_name = 0; + char *verity_table = 0; + char *verity_table_signature = 0; char buffer[DM_BUF_SIZE]; struct dm_ioctl *io = (struct dm_ioctl *) buffer; @@ -378,11 +394,19 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { return retval; } + // read the verity block at the end of the block device + // send error code up the chain so we can detect attempts to disable verity + retval = read_verity_metadata(fstab->blk_device, + &verity_table_signature, + &verity_table); + if (retval < 0) { + goto out; + } + // get the device mapper fd - int fd; if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { ERROR("Error opening device mapper (%s)", strerror(errno)); - return retval; + goto out;; } // create the device @@ -397,13 +421,6 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { goto out; } - // read the verity block at the end of the block device - if (read_verity_metadata(fstab->blk_device, - &verity_table_signature, - &verity_table) < 0) { - goto out; - } - // verify the signature on the table if (verify_table(verity_table_signature, verity_table, @@ -424,6 +441,7 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { // assign the new verity block device as the block device free(fstab->blk_device); fstab->blk_device = verity_blk_name; + verity_blk_name = 0; // make sure we've set everything up properly if (test_access(fstab->blk_device) < 0) { @@ -434,6 +452,13 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) { retval = set_verified_property(mount_point); out: - close(fd); + if (fd != -1) { + close(fd); + } + + free (verity_table); + free (verity_table_signature); + free (verity_blk_name); + return retval; } |