ANDROID: dm: android-verity: Mounting root as linear device when verity disabled
authorBadhri Jagan Sridharan <Badhri@google.com>
Mon, 21 Mar 2016 17:55:23 +0000 (10:55 -0700)
committerAmit Pundir <amit.pundir@linaro.org>
Mon, 18 Dec 2017 15:41:22 +0000 (21:11 +0530)
This CL makes android-verity target to be added as linear
dm device if when bootloader is unlocked and verity is disabled.

Bug: 27175947
Change-Id: Ic41ca4b8908fb2777263799cf3a3e25934d70f18
Signed-off-by: Badhri Jagan Sridharan <Badhri@google.com>
[AmitP: Folded following android-4.9 commit changes into this patch
        7e70218c2699 ("ANDROID: dm: Minor cleanup")
        67584ff8412b ("ANDROID: dm: rename dm-linear methods for dm-android-verity")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
drivers/md/dm-android-verity.c
drivers/md/dm-android-verity.h
drivers/md/dm-linear.c

index aeb5045830d9600ec1c76ac05180ddd75478fd75..b7e059595f75d01ea25791e1f455d5d29b207c8b 100644 (file)
@@ -13,6 +13,7 @@
  */
 
 #include <linux/buffer_head.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/device-mapper.h>
 static char verifiedbootstate[VERITY_COMMANDLINE_PARAM_LENGTH];
 static char veritymode[VERITY_COMMANDLINE_PARAM_LENGTH];
 
+static bool target_added;
+static bool verity_enabled = true;
+struct dentry *debug_dir;
+static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv);
+
+static struct target_type android_verity_target = {
+       .name                   = "android-verity",
+       .version                = {1, 0, 0},
+       .module                 = THIS_MODULE,
+       .ctr                    = android_verity_ctr,
+       .dtr                    = verity_dtr,
+       .map                    = verity_map,
+       .status                 = verity_status,
+       .ioctl                  = verity_ioctl,
+       .merge                  = verity_merge,
+       .iterate_devices        = verity_iterate_devices,
+       .io_hints               = verity_io_hints,
+};
+
 static int __init verified_boot_state_param(char *line)
 {
        strlcpy(verifiedbootstate, line, sizeof(verifiedbootstate));
@@ -549,6 +569,32 @@ static inline bool test_mult_overflow(sector_t a, u32 b)
        return a > r;
 }
 
+static int add_as_linear_device(struct dm_target *ti, char *dev)
+{
+       /*Move to linear mapping defines*/
+       char *linear_table_args[DM_LINEAR_ARGS] = {dev,
+                                       DM_LINEAR_TARGET_OFFSET};
+       int err = 0;
+
+       android_verity_target.dtr = dm_linear_dtr,
+       android_verity_target.map = dm_linear_map,
+       android_verity_target.status = dm_linear_status,
+       android_verity_target.ioctl = dm_linear_ioctl,
+       android_verity_target.merge = dm_linear_merge,
+       android_verity_target.iterate_devices = dm_linear_iterate_devices,
+       android_verity_target.io_hints = NULL;
+
+       err = dm_linear_ctr(ti, DM_LINEAR_ARGS, linear_table_args);
+
+       if (!err) {
+               DMINFO("Added android-verity as a linear target");
+               target_added = true;
+       } else
+               DMERR("Failed to add android-verity as linear target");
+
+       return err;
+}
+
 /*
  * Target parameters:
  *     <key id>        Key id of the public key in the system keyring.
@@ -613,21 +659,27 @@ static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        if (err == VERITY_STATE_DISABLE) {
                DMERR("Mounting root with verity disabled");
-               return -EINVAL;
+               verity_enabled = false;
+               /* we would still have to parse the args to figure out
+                * the data blocks size. Or may be could map the entire
+                * partition similar to mounting the device.
+                */
        } else if (err) {
                DMERR("Verity header handle error");
                handle_error();
                goto free_metadata;
        }
 
-       err = verify_verity_signature(key_id, metadata);
+       if (!verity_enabled) {
+               err = verify_verity_signature(key_id, metadata);
 
-       if (err) {
-               DMERR("Signature verification failed");
-               handle_error();
-               goto free_metadata;
-       } else
-               DMINFO("Signature verification success");
+               if (err) {
+                       DMERR("Signature verification failed");
+                       handle_error();
+                       goto free_metadata;
+               } else
+                       DMINFO("Signature verification success");
+       }
 
        table_ptr = metadata->verity_table;
 
@@ -683,6 +735,12 @@ static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
        /* update target length */
        ti->len = data_sectors;
 
+       /* Setup linear target and free */
+       if (!verity_enabled) {
+               err = add_as_linear_device(ti, argv[1]);
+               goto free_metadata;
+       }
+
        /*substitute data_dev and hash_dev*/
        verity_table_args[1] = argv[1];
        verity_table_args[2] = argv[1];
@@ -730,6 +788,13 @@ static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        err = verity_ctr(ti, no_of_args, verity_table_args);
 
+       if (err)
+               DMERR("android-verity failed to mount as verity target");
+       else {
+               target_added = true;
+               DMINFO("android-verity mounted as verity target");
+       }
+
 free_metadata:
        kfree(metadata->header);
        kfree(metadata->verity_table);
@@ -737,33 +802,52 @@ free_metadata:
        return err;
 }
 
-static struct target_type android_verity_target = {
-       .name                   = "android-verity",
-       .version                = {1, 0, 0},
-       .module                 = THIS_MODULE,
-       .ctr                    = android_verity_ctr,
-       .dtr                    = verity_dtr,
-       .map                    = verity_map,
-       .status                 = verity_status,
-       .ioctl                  = verity_ioctl,
-       .merge                  = verity_merge,
-       .iterate_devices        = verity_iterate_devices,
-       .io_hints               = verity_io_hints,
-};
-
 static int __init dm_android_verity_init(void)
 {
        int r;
+       struct dentry *file;
 
        r = dm_register_target(&android_verity_target);
        if (r < 0)
                DMERR("register failed %d", r);
 
+       /* Tracks the status of the last added target */
+       debug_dir = debugfs_create_dir("android_verity", NULL);
+
+       if (IS_ERR_OR_NULL(debug_dir)) {
+               DMERR("Cannot create android_verity debugfs directory: %ld",
+                       PTR_ERR(debug_dir));
+               goto end;
+       }
+
+       file = debugfs_create_bool("target_added", S_IRUGO, debug_dir,
+                               (u32 *)&target_added);
+
+       if (IS_ERR_OR_NULL(file)) {
+               DMERR("Cannot create android_verity debugfs directory: %ld",
+                       PTR_ERR(debug_dir));
+               debugfs_remove_recursive(debug_dir);
+               goto end;
+       }
+
+       file = debugfs_create_bool("verity_enabled", S_IRUGO, debug_dir,
+                               (u32 *)&verity_enabled);
+
+       if (IS_ERR_OR_NULL(file)) {
+               DMERR("Cannot create android_verity debugfs directory: %ld",
+                       PTR_ERR(debug_dir));
+               debugfs_remove_recursive(debug_dir);
+       }
+
+end:
        return r;
 }
 
 static void __exit dm_android_verity_exit(void)
 {
+       if (!IS_ERR_OR_NULL(debug_dir))
+               debugfs_remove_recursive(debug_dir);
+
        dm_unregister_target(&android_verity_target);
 }
 
index 11477ffd2243e55b012978cb28ee25201dd2ef45..efb7965248968c79d65764396c0ac49bc8f22261 100644 (file)
 #define VERITY_DEBUG 0
 
 #define DM_MSG_PREFIX                   "android-verity"
+
+#define DM_LINEAR_ARGS 2
+#define DM_LINEAR_TARGET_OFFSET "0"
+
 /*
  * There can be two formats.
  * if fec is present
@@ -89,4 +93,17 @@ struct bio_read {
        int number_of_pages;
 };
 
+extern struct target_type linear_target;
+
+extern void dm_linear_dtr(struct dm_target *ti);
+extern int dm_linear_map(struct dm_target *ti, struct bio *bio);
+extern void dm_linear_status(struct dm_target *ti, status_type_t type,
+                       unsigned status_flags, char *result, unsigned maxlen);
+extern int dm_linear_ioctl(struct dm_target *ti, unsigned int cmd,
+               unsigned long arg);
+extern int dm_linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
+               struct bio_vec *biovec, int max_size);
+extern int dm_linear_iterate_devices(struct dm_target *ti,
+                       iterate_devices_callout_fn fn, void *data);
+extern int dm_linear_ctr(struct dm_target *ti, unsigned int argc, char **argv);
 #endif /* DM_ANDROID_VERITY_H */
index d5f8eff7c11d88a066d1dd83fe4707b33264cfae..9ac433096a04227f8d6db6b1a6c2384e10cce605 100644 (file)
@@ -26,7 +26,7 @@ struct linear_c {
 /*
  * Construct a linear mapping: <dev_path> <offset>
  */
-static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+int dm_linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
 {
        struct linear_c *lc;
        unsigned long long tmp;
@@ -69,7 +69,7 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
        return ret;
 }
 
-static void linear_dtr(struct dm_target *ti)
+void dm_linear_dtr(struct dm_target *ti)
 {
        struct linear_c *lc = (struct linear_c *) ti->private;
 
@@ -94,7 +94,7 @@ static void linear_map_bio(struct dm_target *ti, struct bio *bio)
                        linear_map_sector(ti, bio->bi_iter.bi_sector);
 }
 
-static int linear_map(struct dm_target *ti, struct bio *bio)
+int dm_linear_map(struct dm_target *ti, struct bio *bio)
 {
        linear_map_bio(ti, bio);
 
@@ -112,7 +112,7 @@ static int linear_end_io(struct dm_target *ti, struct bio *bio,
        return DM_ENDIO_DONE;
 }
 
-static void linear_status(struct dm_target *ti, status_type_t type,
+void dm_linear_status(struct dm_target *ti, status_type_t type,
                          unsigned status_flags, char *result, unsigned maxlen)
 {
        struct linear_c *lc = (struct linear_c *) ti->private;
@@ -129,7 +129,7 @@ static void linear_status(struct dm_target *ti, status_type_t type,
        }
 }
 
-static int linear_prepare_ioctl(struct dm_target *ti,
+static int dm_linear_prepare_ioctl(struct dm_target *ti,
                struct block_device **bdev, fmode_t *mode)
 {
        struct linear_c *lc = (struct linear_c *) ti->private;
@@ -146,7 +146,7 @@ static int linear_prepare_ioctl(struct dm_target *ti,
        return 0;
 }
 
-static int linear_iterate_devices(struct dm_target *ti,
+int dm_linear_iterate_devices(struct dm_target *ti,
                                  iterate_devices_callout_fn fn, void *data)
 {
        struct linear_c *lc = ti->private;
@@ -189,13 +189,13 @@ static struct target_type linear_target = {
        .version = {1, 4, 0},
        .features = DM_TARGET_PASSES_INTEGRITY | DM_TARGET_ZONED_HM,
        .module = THIS_MODULE,
-       .ctr    = linear_ctr,
-       .dtr    = linear_dtr,
-       .map    = linear_map,
+       .ctr    = dm_linear_ctr,
+       .dtr    = dm_linear_dtr,
+       .map    = dm_linear_map,
+       .status = dm_linear_status,
        .end_io = linear_end_io,
-       .status = linear_status,
-       .prepare_ioctl = linear_prepare_ioctl,
-       .iterate_devices = linear_iterate_devices,
+       .prepare_ioctl = dm_linear_prepare_ioctl,
+       .iterate_devices = dm_linear_iterate_devices,
        .direct_access = linear_dax_direct_access,
        .dax_copy_from_iter = linear_dax_copy_from_iter,
 };