Skip to content

Commit

Permalink
ANDROID: dm: android-verity: Mounting root as linear device when veri…
Browse files Browse the repository at this point in the history
…ty disabled

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
        7e70218 ("ANDROID: dm: Minor cleanup")
        67584ff ("ANDROID: dm: rename dm-linear methods for dm-android-verity")]
Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
  • Loading branch information
Badhri Jagan Sridharan authored and Amit Pundir committed Dec 18, 2017
1 parent 7069aa2 commit 47c3ee9
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 34 deletions.
128 changes: 106 additions & 22 deletions drivers/md/dm-android-verity.c
Expand Up @@ -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>
Expand Down Expand Up @@ -43,6 +44,25 @@
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));
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -730,40 +788,66 @@ 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);
kfree(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);
}

Expand Down
17 changes: 17 additions & 0 deletions drivers/md/dm-android-verity.h
Expand Up @@ -44,6 +44,10 @@
#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
Expand Down Expand Up @@ -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 */
24 changes: 12 additions & 12 deletions drivers/md/dm-linear.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand All @@ -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);

Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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,
};
Expand Down

0 comments on commit 47c3ee9

Please sign in to comment.