blob: 00275a986d037d68d66f50ab6c41f8de979707c2 [file] [log] [blame]
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -08001/*
2 * Copyright (C) 2015 Google, Inc.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15#include <linux/buffer_head.h>
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -070016#include <linux/debugfs.h>
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -080017#include <linux/delay.h>
18#include <linux/device.h>
19#include <linux/device-mapper.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/fcntl.h>
23#include <linux/init.h>
24#include <linux/kernel.h>
25#include <linux/key.h>
26#include <linux/module.h>
27#include <linux/mount.h>
28#include <linux/namei.h>
29#include <linux/of.h>
30#include <linux/reboot.h>
31#include <linux/string.h>
32#include <linux/vmalloc.h>
33
34#include <asm/setup.h>
35#include <crypto/hash.h>
36#include <crypto/public_key.h>
37#include <crypto/sha.h>
38#include <keys/asymmetric-type.h>
39#include <keys/system_keyring.h>
40
41#include "dm-verity.h"
42#include "dm-android-verity.h"
43
44static char verifiedbootstate[VERITY_COMMANDLINE_PARAM_LENGTH];
45static char veritymode[VERITY_COMMANDLINE_PARAM_LENGTH];
46
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -070047static bool target_added;
48static bool verity_enabled = true;
49struct dentry *debug_dir;
50static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv);
51
52static struct target_type android_verity_target = {
53 .name = "android-verity",
54 .version = {1, 0, 0},
55 .module = THIS_MODULE,
56 .ctr = android_verity_ctr,
57 .dtr = verity_dtr,
58 .map = verity_map,
59 .status = verity_status,
60 .ioctl = verity_ioctl,
61 .merge = verity_merge,
62 .iterate_devices = verity_iterate_devices,
63 .io_hints = verity_io_hints,
64};
65
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -080066static int __init verified_boot_state_param(char *line)
67{
68 strlcpy(verifiedbootstate, line, sizeof(verifiedbootstate));
69 return 1;
70}
71
72__setup("androidboot.verifiedbootstate=", verified_boot_state_param);
73
74static int __init verity_mode_param(char *line)
75{
76 strlcpy(veritymode, line, sizeof(veritymode));
77 return 1;
78}
79
80__setup("androidboot.veritymode=", verity_mode_param);
81
82static int table_extract_mpi_array(struct public_key_signature *pks,
83 const void *data, size_t len)
84{
85 MPI mpi = mpi_read_raw_data(data, len);
86
87 if (!mpi) {
88 DMERR("Error while allocating mpi array");
89 return -ENOMEM;
90 }
91
92 pks->mpi[0] = mpi;
93 pks->nr_mpi = 1;
94 return 0;
95}
96
97static struct public_key_signature *table_make_digest(
Badhri Jagan Sridharan56f6a6b2016-02-08 16:28:43 -080098 enum hash_algo hash,
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -080099 const void *table,
100 unsigned long table_len)
101{
102 struct public_key_signature *pks = NULL;
103 struct crypto_shash *tfm;
104 struct shash_desc *desc;
105 size_t digest_size, desc_size;
106 int ret;
107
108 /* Allocate the hashing algorithm we're going to need and find out how
109 * big the hash operational data will be.
110 */
Badhri Jagan Sridharan56f6a6b2016-02-08 16:28:43 -0800111 tfm = crypto_alloc_shash(hash_algo_name[hash], 0, 0);
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800112 if (IS_ERR(tfm))
113 return ERR_CAST(tfm);
114
115 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
116 digest_size = crypto_shash_digestsize(tfm);
117
118 /* We allocate the hash operational data storage on the end of out
119 * context data and the digest output buffer on the end of that.
120 */
121 ret = -ENOMEM;
122 pks = kzalloc(digest_size + sizeof(*pks) + desc_size, GFP_KERNEL);
123 if (!pks)
124 goto error;
125
126 pks->pkey_hash_algo = hash;
127 pks->digest = (u8 *)pks + sizeof(*pks) + desc_size;
128 pks->digest_size = digest_size;
129
130 desc = (struct shash_desc *)(pks + 1);
131 desc->tfm = tfm;
132 desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
133
134 ret = crypto_shash_init(desc);
135 if (ret < 0)
136 goto error;
137
138 ret = crypto_shash_finup(desc, table, table_len, pks->digest);
139 if (ret < 0)
140 goto error;
141
142 crypto_free_shash(tfm);
143 return pks;
144
145error:
146 kfree(pks);
147 crypto_free_shash(tfm);
148 return ERR_PTR(ret);
149}
150
151static int read_block_dev(struct bio_read *payload, struct block_device *bdev,
152 sector_t offset, int length)
153{
154 struct bio *bio;
155 int err = 0, i;
156
157 payload->number_of_pages = DIV_ROUND_UP(length, PAGE_SIZE);
158
159 bio = bio_alloc(GFP_KERNEL, payload->number_of_pages);
160 if (!bio) {
161 DMERR("Error while allocating bio");
162 return -ENOMEM;
163 }
164
165 bio->bi_bdev = bdev;
Badhri Jagan Sridharan56f6a6b2016-02-08 16:28:43 -0800166 bio->bi_iter.bi_sector = offset;
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800167
168 payload->page_io = kzalloc(sizeof(struct page *) *
169 payload->number_of_pages, GFP_KERNEL);
170 if (!payload->page_io) {
171 DMERR("page_io array alloc failed");
172 err = -ENOMEM;
173 goto free_bio;
174 }
175
176 for (i = 0; i < payload->number_of_pages; i++) {
177 payload->page_io[i] = alloc_page(GFP_KERNEL);
178 if (!payload->page_io[i]) {
179 DMERR("alloc_page failed");
180 err = -ENOMEM;
181 goto free_pages;
182 }
183 if (!bio_add_page(bio, payload->page_io[i], PAGE_SIZE, 0)) {
184 DMERR("bio_add_page error");
185 err = -EIO;
186 goto free_pages;
187 }
188 }
189
190 if (!submit_bio_wait(READ, bio))
191 /* success */
192 goto free_bio;
193 DMERR("bio read failed");
194 err = -EIO;
195
196free_pages:
197 for (i = 0; i < payload->number_of_pages; i++)
198 if (payload->page_io[i])
199 __free_page(payload->page_io[i]);
200 kfree(payload->page_io);
201free_bio:
202 bio_put(bio);
203 return err;
204}
205
206static inline u64 fec_div_round_up(u64 x, u64 y)
207{
208 u64 remainder;
209
210 return div64_u64_rem(x, y, &remainder) +
211 (remainder > 0 ? 1 : 0);
212}
213
214static inline void populate_fec_metadata(struct fec_header *header,
215 struct fec_ecc_metadata *ecc)
216{
217 ecc->blocks = fec_div_round_up(le64_to_cpu(header->inp_size),
218 FEC_BLOCK_SIZE);
219 ecc->roots = le32_to_cpu(header->roots);
220 ecc->start = le64_to_cpu(header->inp_size);
221}
222
223static inline int validate_fec_header(struct fec_header *header, u64 offset)
224{
225 /* move offset to make the sanity check work for backup header
226 * as well. */
227 offset -= offset % FEC_BLOCK_SIZE;
228 if (le32_to_cpu(header->magic) != FEC_MAGIC ||
229 le32_to_cpu(header->version) != FEC_VERSION ||
230 le32_to_cpu(header->size) != sizeof(struct fec_header) ||
231 le32_to_cpu(header->roots) == 0 ||
232 le32_to_cpu(header->roots) >= FEC_RSM ||
233 offset < le32_to_cpu(header->fec_size) ||
234 offset - le32_to_cpu(header->fec_size) !=
235 le64_to_cpu(header->inp_size))
236 return -EINVAL;
237
238 return 0;
239}
240
241static int extract_fec_header(dev_t dev, struct fec_header *fec,
242 struct fec_ecc_metadata *ecc)
243{
244 u64 device_size;
245 struct bio_read payload;
246 int i, err = 0;
247 struct block_device *bdev;
248
249 bdev = blkdev_get_by_dev(dev, FMODE_READ, NULL);
250
251 if (IS_ERR(bdev)) {
252 DMERR("bdev get error");
253 return PTR_ERR(bdev);
254 }
255
256 device_size = i_size_read(bdev->bd_inode);
257
258 /* fec metadata size is a power of 2 and PAGE_SIZE
259 * is a power of 2 as well.
260 */
261 BUG_ON(FEC_BLOCK_SIZE > PAGE_SIZE);
262 /* 512 byte sector alignment */
263 BUG_ON(((device_size - FEC_BLOCK_SIZE) % (1 << SECTOR_SHIFT)) != 0);
264
265 err = read_block_dev(&payload, bdev, (device_size -
266 FEC_BLOCK_SIZE) / (1 << SECTOR_SHIFT), FEC_BLOCK_SIZE);
267 if (err) {
268 DMERR("Error while reading verity metadata");
269 goto error;
270 }
271
272 BUG_ON(sizeof(struct fec_header) > PAGE_SIZE);
273 memcpy(fec, page_address(payload.page_io[0]),
274 sizeof(*fec));
275
276 ecc->valid = true;
277 if (validate_fec_header(fec, device_size - FEC_BLOCK_SIZE)) {
278 /* Try the backup header */
279 memcpy(fec, page_address(payload.page_io[0]) + FEC_BLOCK_SIZE
280 - sizeof(*fec) ,
281 sizeof(*fec));
282 if (validate_fec_header(fec, device_size -
283 sizeof(struct fec_header)))
284 ecc->valid = false;
285 }
286
287 if (ecc->valid)
288 populate_fec_metadata(fec, ecc);
289
290 for (i = 0; i < payload.number_of_pages; i++)
291 __free_page(payload.page_io[i]);
292 kfree(payload.page_io);
293
294error:
295 blkdev_put(bdev, FMODE_READ);
296 return err;
297}
298static void find_metadata_offset(struct fec_header *fec,
299 struct block_device *bdev, u64 *metadata_offset)
300{
301 u64 device_size;
302
303 device_size = i_size_read(bdev->bd_inode);
304
305 if (le32_to_cpu(fec->magic) == FEC_MAGIC)
306 *metadata_offset = le64_to_cpu(fec->inp_size) -
307 VERITY_METADATA_SIZE;
308 else
309 *metadata_offset = device_size - VERITY_METADATA_SIZE;
310}
311
312static struct android_metadata *extract_metadata(dev_t dev,
313 struct fec_header *fec)
314{
315 struct block_device *bdev;
316 struct android_metadata_header *header;
317 struct android_metadata *uninitialized_var(metadata);
318 int i;
319 u32 table_length, copy_length, offset;
320 u64 metadata_offset;
321 struct bio_read payload;
322 int err = 0;
323
324 bdev = blkdev_get_by_dev(dev, FMODE_READ, NULL);
325
326 if (IS_ERR(bdev)) {
327 DMERR("blkdev_get_by_dev failed");
328 return ERR_CAST(bdev);
329 }
330
331 find_metadata_offset(fec, bdev, &metadata_offset);
332
333 /* Verity metadata size is a power of 2 and PAGE_SIZE
334 * is a power of 2 as well.
335 * PAGE_SIZE is also a multiple of 512 bytes.
336 */
337 if (VERITY_METADATA_SIZE > PAGE_SIZE)
338 BUG_ON(VERITY_METADATA_SIZE % PAGE_SIZE != 0);
339 /* 512 byte sector alignment */
340 BUG_ON(metadata_offset % (1 << SECTOR_SHIFT) != 0);
341
342 err = read_block_dev(&payload, bdev, metadata_offset /
343 (1 << SECTOR_SHIFT), VERITY_METADATA_SIZE);
344 if (err) {
345 DMERR("Error while reading verity metadata");
346 metadata = ERR_PTR(err);
347 goto blkdev_release;
348 }
349
350 header = kzalloc(sizeof(*header), GFP_KERNEL);
351 if (!header) {
352 DMERR("kzalloc failed for header");
353 err = -ENOMEM;
354 goto free_payload;
355 }
356
357 memcpy(header, page_address(payload.page_io[0]),
358 sizeof(*header));
359
360 DMINFO("bio magic_number:%u protocol_version:%d table_length:%u",
361 le32_to_cpu(header->magic_number),
362 le32_to_cpu(header->protocol_version),
363 le32_to_cpu(header->table_length));
364
365 metadata = kzalloc(sizeof(*metadata), GFP_KERNEL);
366 if (!metadata) {
367 DMERR("kzalloc for metadata failed");
368 err = -ENOMEM;
369 goto free_header;
370 }
371
372 metadata->header = header;
373 table_length = le32_to_cpu(header->table_length);
374
375 if (table_length == 0 ||
376 table_length > (VERITY_METADATA_SIZE -
377 sizeof(struct android_metadata_header)))
378 goto free_metadata;
379
380 metadata->verity_table = kzalloc(table_length + 1, GFP_KERNEL);
381
382 if (!metadata->verity_table) {
383 DMERR("kzalloc verity_table failed");
384 err = -ENOMEM;
385 goto free_metadata;
386 }
387
388 if (sizeof(struct android_metadata_header) +
389 table_length <= PAGE_SIZE) {
390 memcpy(metadata->verity_table, page_address(payload.page_io[0])
391 + sizeof(struct android_metadata_header),
392 table_length);
393 } else {
394 copy_length = PAGE_SIZE -
395 sizeof(struct android_metadata_header);
396 memcpy(metadata->verity_table, page_address(payload.page_io[0])
397 + sizeof(struct android_metadata_header),
398 copy_length);
399 table_length -= copy_length;
400 offset = copy_length;
401 i = 1;
402 while (table_length != 0) {
403 if (table_length > PAGE_SIZE) {
404 memcpy(metadata->verity_table + offset,
405 page_address(payload.page_io[i]),
406 PAGE_SIZE);
407 offset += PAGE_SIZE;
408 table_length -= PAGE_SIZE;
409 } else {
410 memcpy(metadata->verity_table + offset,
411 page_address(payload.page_io[i]),
412 table_length);
413 table_length = 0;
414 }
415 i++;
416 }
417 }
418 metadata->verity_table[table_length] = '\0';
419
420 goto free_payload;
421
422free_metadata:
423 kfree(metadata);
424free_header:
425 kfree(header);
426 metadata = ERR_PTR(err);
427free_payload:
428 for (i = 0; i < payload.number_of_pages; i++)
429 if (payload.page_io[i])
430 __free_page(payload.page_io[i]);
431 kfree(payload.page_io);
432
433 DMINFO("verity_table: %s", metadata->verity_table);
434blkdev_release:
435 blkdev_put(bdev, FMODE_READ);
436 return metadata;
437}
438
439/* helper functions to extract properties from dts */
440const char *find_dt_value(const char *name)
441{
442 struct device_node *firmware;
443 const char *value;
444
445 firmware = of_find_node_by_path("/firmware/android");
446 if (!firmware)
447 return NULL;
448 value = of_get_property(firmware, name, NULL);
449 of_node_put(firmware);
450
451 return value;
452}
453
454static bool is_unlocked(void)
455{
456 static const char unlocked[] = "orange";
457 static const char verified_boot_prop[] = "verifiedbootstate";
458 const char *value;
459
460 value = find_dt_value(verified_boot_prop);
461 if (!value)
462 value = verifiedbootstate;
463
464 return !strncmp(value, unlocked, sizeof(unlocked) - 1);
465}
466
467static int verity_mode(void)
468{
469 static const char enforcing[] = "enforcing";
470 static const char verified_mode_prop[] = "veritymode";
471 const char *value;
472
473 value = find_dt_value(verified_mode_prop);
474 if (!value)
475 value = veritymode;
476 if (!strncmp(value, enforcing, sizeof(enforcing) - 1))
477 return DM_VERITY_MODE_RESTART;
478
479 return DM_VERITY_MODE_EIO;
480}
481
482static int verify_header(struct android_metadata_header *header)
483{
484 int retval = -EINVAL;
485
486 if (is_unlocked() && le32_to_cpu(header->magic_number) ==
487 VERITY_METADATA_MAGIC_DISABLE) {
488 retval = VERITY_STATE_DISABLE;
489 return retval;
490 }
491
492 if (!(le32_to_cpu(header->magic_number) ==
493 VERITY_METADATA_MAGIC_NUMBER) ||
494 (le32_to_cpu(header->magic_number) ==
495 VERITY_METADATA_MAGIC_DISABLE)) {
496 DMERR("Incorrect magic number");
497 return retval;
498 }
499
500 if (le32_to_cpu(header->protocol_version) !=
501 VERITY_METADATA_VERSION) {
502 DMERR("Unsupported version %u",
503 le32_to_cpu(header->protocol_version));
504 return retval;
505 }
506
507 return 0;
508}
509
510static int verify_verity_signature(char *key_id,
511 struct android_metadata *metadata)
512{
513 key_ref_t key_ref;
514 struct key *key;
515 struct public_key_signature *pks = NULL;
516 int retval = -EINVAL;
517
518 key_ref = keyring_search(make_key_ref(system_trusted_keyring, 1),
519 &key_type_asymmetric, key_id);
520
521 if (IS_ERR(key_ref)) {
522 DMERR("keyring: key not found");
523 return -ENOKEY;
524 }
525
526 key = key_ref_to_ptr(key_ref);
527
Badhri Jagan Sridharan56f6a6b2016-02-08 16:28:43 -0800528 pks = table_make_digest(HASH_ALGO_SHA256,
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800529 (const void *)metadata->verity_table,
530 le32_to_cpu(metadata->header->table_length));
531
532 if (IS_ERR(pks)) {
533 DMERR("hashing failed");
534 goto error;
535 }
536
537 retval = table_extract_mpi_array(pks, &metadata->header->signature[0],
538 RSANUMBYTES);
539 if (retval < 0) {
540 DMERR("Error extracting mpi %d", retval);
541 goto error;
542 }
543
544 retval = verify_signature(key, pks);
545 mpi_free(pks->rsa.s);
546error:
547 kfree(pks);
548 key_put(key);
549
550 return retval;
551}
552
553static void handle_error(void)
554{
555 int mode = verity_mode();
556 if (mode == DM_VERITY_MODE_RESTART) {
557 DMERR("triggering restart");
558 kernel_restart("dm-verity device corrupted");
559 } else {
560 DMERR("Mounting verity root failed");
561 }
562}
563
564static inline bool test_mult_overflow(sector_t a, u32 b)
565{
566 sector_t r = (sector_t)~0ULL;
567
568 sector_div(r, b);
569 return a > r;
570}
571
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700572static int add_as_linear_device(struct dm_target *ti, char *dev)
573{
574 /*Move to linear mapping defines*/
Badhri Jagan Sridharan7e702182016-03-28 14:41:21 -0700575 char *linear_table_args[DM_LINEAR_ARGS] = {dev,
576 DM_LINEAR_TARGET_OFFSET};
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700577 int err = 0;
578
Badhri Jagan Sridharan67584ff2016-04-05 11:18:16 -0700579 android_verity_target.dtr = dm_linear_dtr,
580 android_verity_target.map = dm_linear_map,
581 android_verity_target.status = dm_linear_status,
582 android_verity_target.ioctl = dm_linear_ioctl,
583 android_verity_target.merge = dm_linear_merge,
584 android_verity_target.iterate_devices = dm_linear_iterate_devices,
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700585 android_verity_target.io_hints = NULL;
586
Badhri Jagan Sridharan67584ff2016-04-05 11:18:16 -0700587 err = dm_linear_ctr(ti, DM_LINEAR_ARGS, linear_table_args);
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700588
589 if (!err) {
590 DMINFO("Added android-verity as a linear target");
591 target_added = true;
592 } else
593 DMERR("Failed to add android-verity as linear target");
594
595 return err;
596}
597
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800598/*
599 * Target parameters:
600 * <key id> Key id of the public key in the system keyring.
601 * Verity metadata's signature would be verified against
602 * this. If the key id contains spaces, replace them
603 * with '#'.
604 * <block device> The block device for which dm-verity is being setup.
605 */
606static int android_verity_ctr(struct dm_target *ti, unsigned argc, char **argv)
607{
608 dev_t uninitialized_var(dev);
609 struct android_metadata *uninitialized_var(metadata);
610 int err = 0, i, mode;
611 char *key_id, *table_ptr, dummy,
612 *verity_table_args[VERITY_TABLE_ARGS + 2 + VERITY_TABLE_OPT_FEC_ARGS];
613 /* One for specifying number of opt args and one for mode */
614 sector_t data_sectors;
615 u32 data_block_size;
Jeremy Compostella0b768a42016-04-15 13:32:54 +0200616 unsigned int no_of_args = VERITY_TABLE_ARGS + 2 + VERITY_TABLE_OPT_FEC_ARGS;
Badhri Jagan Sridharan56f6a6b2016-02-08 16:28:43 -0800617 struct fec_header uninitialized_var(fec);
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800618 struct fec_ecc_metadata uninitialized_var(ecc);
619 char buf[FEC_ARG_LENGTH], *buf_ptr;
620 unsigned long long tmpll;
621
622 if (argc != 2) {
623 DMERR("Incorrect number of arguments");
624 handle_error();
625 return -EINVAL;
626 }
627
628 /* should come as one of the arguments for the verity target */
629 key_id = argv[0];
630 strreplace(argv[0], '#', ' ');
631
Jeremy Compostella0b768a42016-04-15 13:32:54 +0200632 dev = name_to_dev_t(argv[1]);
633 if (!dev) {
634 DMERR("no dev found for %s", argv[1]);
635 handle_error();
636 return -EINVAL;
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800637 }
638
639 DMINFO("key:%s dev:%s", argv[0], argv[1]);
640
641 if (extract_fec_header(dev, &fec, &ecc)) {
642 DMERR("Error while extracting fec header");
643 handle_error();
644 return -EINVAL;
645 }
646
647 metadata = extract_metadata(dev, &fec);
648
649 if (IS_ERR(metadata)) {
650 DMERR("Error while extracting metadata");
651 handle_error();
652 return -EINVAL;
653 }
654
655 err = verify_header(metadata->header);
656
657 if (err == VERITY_STATE_DISABLE) {
658 DMERR("Mounting root with verity disabled");
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700659 verity_enabled = false;
660 /* we would still have to parse the args to figure out
661 * the data blocks size. Or may be could map the entire
662 * partition similar to mounting the device.
663 */
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800664 } else if (err) {
665 DMERR("Verity header handle error");
666 handle_error();
667 goto free_metadata;
668 }
669
Badhri Jagan Sridharane96affa2016-05-20 16:44:19 -0700670 if (verity_enabled) {
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700671 err = verify_verity_signature(key_id, metadata);
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800672
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700673 if (err) {
674 DMERR("Signature verification failed");
675 handle_error();
676 goto free_metadata;
677 } else
678 DMINFO("Signature verification success");
679 }
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800680
681 table_ptr = metadata->verity_table;
682
683 for (i = 0; i < VERITY_TABLE_ARGS; i++) {
684 verity_table_args[i] = strsep(&table_ptr, " ");
685 if (verity_table_args[i] == NULL)
686 break;
687 }
688
689 if (i != VERITY_TABLE_ARGS) {
690 DMERR("Verity table not in the expected format");
691 err = -EINVAL;
692 handle_error();
693 goto free_metadata;
694 }
695
696 if (sscanf(verity_table_args[5], "%llu%c", &tmpll, &dummy)
697 != 1) {
698 DMERR("Verity table not in the expected format");
699 handle_error();
700 err = -EINVAL;
701 goto free_metadata;
702 }
703
704 if (tmpll > ULONG_MAX) {
705 DMERR("<num_data_blocks> too large. Forgot to turn on CONFIG_LBDAF?");
706 handle_error();
707 err = -EINVAL;
708 goto free_metadata;
709 }
710
711 data_sectors = tmpll;
712
713 if (sscanf(verity_table_args[3], "%u%c", &data_block_size, &dummy)
714 != 1) {
715 DMERR("Verity table not in the expected format");
716 handle_error();
717 err = -EINVAL;
718 goto free_metadata;
719 }
720
721 if (test_mult_overflow(data_sectors, data_block_size >>
722 SECTOR_SHIFT)) {
723 DMERR("data_sectors too large");
724 handle_error();
725 err = -EOVERFLOW;
726 goto free_metadata;
727 }
728
729 data_sectors *= data_block_size >> SECTOR_SHIFT;
730 DMINFO("Data sectors %llu", (unsigned long long)data_sectors);
731
732 /* update target length */
733 ti->len = data_sectors;
734
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700735 /* Setup linear target and free */
736 if (!verity_enabled) {
737 err = add_as_linear_device(ti, argv[1]);
738 goto free_metadata;
739 }
740
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800741 /*substitute data_dev and hash_dev*/
742 verity_table_args[1] = argv[1];
743 verity_table_args[2] = argv[1];
744
745 mode = verity_mode();
746
747 if (ecc.valid && IS_BUILTIN(CONFIG_DM_VERITY_FEC)) {
748 if (mode) {
749 err = snprintf(buf, FEC_ARG_LENGTH,
750 "%u %s " VERITY_TABLE_OPT_FEC_FORMAT,
751 1 + VERITY_TABLE_OPT_FEC_ARGS,
752 mode == DM_VERITY_MODE_RESTART ?
753 VERITY_TABLE_OPT_RESTART : VERITY_TABLE_OPT_LOGGING,
754 argv[1], ecc.start / FEC_BLOCK_SIZE, ecc.blocks,
755 ecc.roots);
756 } else {
757 err = snprintf(buf, FEC_ARG_LENGTH,
758 "%u " VERITY_TABLE_OPT_FEC_FORMAT,
759 VERITY_TABLE_OPT_FEC_ARGS, argv[1],
760 ecc.start / FEC_BLOCK_SIZE, ecc.blocks, ecc.roots);
761 }
762 } else if (mode) {
763 err = snprintf(buf, FEC_ARG_LENGTH,
764 "2 " VERITY_TABLE_OPT_IGNZERO " %s",
765 mode == DM_VERITY_MODE_RESTART ?
766 VERITY_TABLE_OPT_RESTART : VERITY_TABLE_OPT_LOGGING);
767 } else {
768 err = snprintf(buf, FEC_ARG_LENGTH, "1 %s",
769 "ignore_zero_blocks");
770 }
771
772 if (err < 0 || err >= FEC_ARG_LENGTH)
773 goto free_metadata;
774
775 buf_ptr = buf;
776
777 for (i = VERITY_TABLE_ARGS; i < (VERITY_TABLE_ARGS +
778 VERITY_TABLE_OPT_FEC_ARGS + 2); i++) {
779 verity_table_args[i] = strsep(&buf_ptr, " ");
780 if (verity_table_args[i] == NULL) {
781 no_of_args = i;
782 break;
783 }
784 }
785
786 err = verity_ctr(ti, no_of_args, verity_table_args);
787
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700788 if (err)
789 DMERR("android-verity failed to mount as verity target");
790 else {
791 target_added = true;
792 DMINFO("android-verity mounted as verity target");
793 }
794
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800795free_metadata:
796 kfree(metadata->header);
797 kfree(metadata->verity_table);
798 kfree(metadata);
799 return err;
800}
801
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800802static int __init dm_android_verity_init(void)
803{
804 int r;
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700805 struct dentry *file;
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800806
807 r = dm_register_target(&android_verity_target);
808 if (r < 0)
809 DMERR("register failed %d", r);
810
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700811 /* Tracks the status of the last added target */
812 debug_dir = debugfs_create_dir("android_verity", NULL);
813
814 if (IS_ERR_OR_NULL(debug_dir)) {
815 DMERR("Cannot create android_verity debugfs directory: %ld",
816 PTR_ERR(debug_dir));
817 goto end;
818 }
819
820 file = debugfs_create_bool("target_added", S_IRUGO, debug_dir,
821 (u32 *)&target_added);
822
823 if (IS_ERR_OR_NULL(file)) {
824 DMERR("Cannot create android_verity debugfs directory: %ld",
825 PTR_ERR(debug_dir));
826 debugfs_remove_recursive(debug_dir);
827 goto end;
828 }
829
830 file = debugfs_create_bool("verity_enabled", S_IRUGO, debug_dir,
831 (u32 *)&verity_enabled);
832
833 if (IS_ERR_OR_NULL(file)) {
834 DMERR("Cannot create android_verity debugfs directory: %ld",
835 PTR_ERR(debug_dir));
836 debugfs_remove_recursive(debug_dir);
837 }
838
839end:
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800840 return r;
841}
842
843static void __exit dm_android_verity_exit(void)
844{
Badhri Jagan Sridharand0706bc2016-03-21 10:55:23 -0700845 if (!IS_ERR_OR_NULL(debug_dir))
846 debugfs_remove_recursive(debug_dir);
847
Badhri Jagan Sridharan8bb45a52015-12-14 20:09:39 -0800848 dm_unregister_target(&android_verity_target);
849}
850
851module_init(dm_android_verity_init);
852module_exit(dm_android_verity_exit);