OLD | NEW |
1 /* | 1 /* |
2 * Originally based on dm-crypt.c, | 2 * Originally based on dm-crypt.c, |
3 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> | 3 * Copyright (C) 2003 Christophe Saout <christophe@saout.de> |
4 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> | 4 * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org> |
5 * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. | 5 * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved. |
6 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> | 6 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> |
7 * All Rights Reserved. | 7 * All Rights Reserved. |
8 * | 8 * |
9 * This file is released under the GPL. | 9 * This file is released under the GPL. |
10 * | 10 * |
11 * Implements a verifying transparent block device. | 11 * Implements a verifying transparent block device. |
12 * See Documentation/device-mapper/dm-verity.txt | 12 * See Documentation/device-mapper/dm-verity.txt |
13 */ | 13 */ |
| 14 #include <linux/async.h> |
14 #include <linux/backing-dev.h> | 15 #include <linux/backing-dev.h> |
15 #include <linux/bio.h> | 16 #include <linux/bio.h> |
16 #include <linux/blkdev.h> | 17 #include <linux/blkdev.h> |
17 #include <linux/completion.h> | 18 #include <linux/completion.h> |
18 #include <linux/crypto.h> | 19 #include <linux/crypto.h> |
19 #include <linux/delay.h> | 20 #include <linux/delay.h> |
| 21 #include <linux/device.h> |
| 22 #ifdef CONFIG_EFI_PARTITION |
| 23 # include <linux/efi.h> |
| 24 #endif |
20 #include <linux/err.h> | 25 #include <linux/err.h> |
| 26 #include <linux/genhd.h> |
21 #include <linux/init.h> | 27 #include <linux/init.h> |
22 #include <linux/kernel.h> | 28 #include <linux/kernel.h> |
23 #include <linux/mempool.h> | 29 #include <linux/mempool.h> |
24 #include <linux/module.h> | 30 #include <linux/module.h> |
25 #include <linux/slab.h> | 31 #include <linux/slab.h> |
26 #include <linux/workqueue.h> | 32 #include <linux/workqueue.h> |
27 #include <linux/reboot.h> | 33 #include <linux/reboot.h> |
28 #include <asm/atomic.h> | 34 #include <asm/atomic.h> |
29 #include <linux/scatterlist.h> | 35 #include <linux/scatterlist.h> |
30 #include <asm/page.h> | 36 #include <asm/page.h> |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
114 static int error_behavior = DM_VERITY_EIO; | 120 static int error_behavior = DM_VERITY_EIO; |
115 module_param(error_behavior, int, 0444); | 121 module_param(error_behavior, int, 0444); |
116 MODULE_PARM_DESC(error_behavior, "Behavior on error"); | 122 MODULE_PARM_DESC(error_behavior, "Behavior on error"); |
117 | 123 |
118 | 124 |
119 /* Control whether the reads are optimized for sequential access by pre-reading | 125 /* Control whether the reads are optimized for sequential access by pre-reading |
120 * entries in the bht. | 126 * entries in the bht. |
121 */ | 127 */ |
122 static int bht_readahead; | 128 static int bht_readahead; |
123 module_param(bht_readahead, int, 0644); | 129 module_param(bht_readahead, int, 0644); |
124 MODULE_PARM_DESC(bht_readahead, "number of entries to readahead in the bht"); | 130 MODULE_PARM_DESC(bht_readahead, "Number of entries to readahead in the bht"); |
| 131 |
| 132 /* Controls whether verity_get_device will wait forever for a device. */ |
| 133 static int dev_wait; |
| 134 module_param(dev_wait, bool, 0444); |
| 135 MODULE_PARM_DESC(dev_wait, "Wait forever for a backing device") |
125 | 136 |
126 /* Used for tracking pending bios as well as for exporting information via | 137 /* Used for tracking pending bios as well as for exporting information via |
127 * STATUSTYPE_INFO. | 138 * STATUSTYPE_INFO. |
128 */ | 139 */ |
129 struct verity_stats { | 140 struct verity_stats { |
130 unsigned int pending_bio; | 141 unsigned int pending_bio; |
131 unsigned int io_queue; | 142 unsigned int io_queue; |
132 unsigned int verify_queue; | 143 unsigned int verify_queue; |
133 unsigned int average_requeues; | 144 unsigned int average_requeues; |
134 unsigned int total_requeues; | 145 unsigned int total_requeues; |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
534 /* IO errors have to be propagated. */ | 545 /* IO errors have to be propagated. */ |
535 if (error != -EIO && io) | 546 if (error != -EIO && io) |
536 io->error = 0; | 547 io->error = 0; |
537 } | 548 } |
538 return; | 549 return; |
539 default: | 550 default: |
540 break; | 551 break; |
541 } | 552 } |
542 } | 553 } |
543 | 554 |
| 555 /** |
| 556 * efi_parse_hexbyte - Convert a ASCII hex number to a byte |
| 557 * @src: Pointer to at least 2 characters to convert. |
| 558 * |
| 559 * Convert a two character ASCII hex string to a number. |
| 560 * From ldm.c. |
| 561 * |
| 562 * Return: 0-255 Success, the byte was parsed correctly |
| 563 * -1 Error, an invalid character was supplied |
| 564 */ |
| 565 static int efi_hexbyte (const u8 *src) |
| 566 { |
| 567 unsigned int x; /* For correct wrapping */ |
| 568 int h; |
| 569 |
| 570 /* high part */ |
| 571 if ((x = src[0] - '0') <= '9'-'0') h = x; |
| 572 else if ((x = src[0] - 'a') <= 'f'-'a') h = x+10; |
| 573 else if ((x = src[0] - 'A') <= 'F'-'A') h = x+10; |
| 574 else return -1; |
| 575 h <<= 4; |
| 576 |
| 577 /* low part */ |
| 578 if ((x = src[1] - '0') <= '9'-'0') return h | x; |
| 579 if ((x = src[1] - 'a') <= 'f'-'a') return h | (x+10); |
| 580 if ((x = src[1] - 'A') <= 'F'-'A') return h | (x+10); |
| 581 return -1; |
| 582 } |
| 583 |
| 584 /** |
| 585 * efi_parse_guid - Convert GUID from ASCII to binary |
| 586 * @src: 36 char string of the form fa50ff2b-f2e8-45de-83fa-65417f2f49ba |
| 587 * @dest: Memory block to hold binary GUID (16 bytes) |
| 588 * |
| 589 * N.B. The GUID need not be NULL terminated and no safety checks are performed. |
| 590 * |
| 591 * Return: 'true' @dest contains binary GUID |
| 592 * 'false' @dest contents are undefined |
| 593 */ |
| 594 static bool efi_parse_guid(const u8 *src, u8 *dest) |
| 595 { |
| 596 dest[3] = efi_hexbyte(src); src += 2; |
| 597 dest[2] = efi_hexbyte(src); src += 2; |
| 598 dest[1] = efi_hexbyte(src); src += 2; |
| 599 dest[0] = efi_hexbyte(src); src += 2; |
| 600 src += 1; /* - */ |
| 601 dest[5] = efi_hexbyte(src); src += 2; |
| 602 dest[4] = efi_hexbyte(src); src += 2; |
| 603 src += 1; /* - */ |
| 604 dest[7] = efi_hexbyte(src); src += 2; |
| 605 dest[6] = efi_hexbyte(src); src += 2; |
| 606 src += 1; /* - */ |
| 607 dest[8] = efi_hexbyte(src); src += 2; |
| 608 dest[9] = efi_hexbyte(src); src += 2; |
| 609 src += 1; /* - */ |
| 610 dest[10] = efi_hexbyte(src); src += 2; |
| 611 dest[11] = efi_hexbyte(src); src += 2; |
| 612 dest[12] = efi_hexbyte(src); src += 2; |
| 613 dest[13] = efi_hexbyte(src); src += 2; |
| 614 dest[14] = efi_hexbyte(src); src += 2; |
| 615 dest[15] = efi_hexbyte(src); src += 2; |
| 616 return true; |
| 617 } |
| 618 |
| 619 /** |
| 620 * dm_get_efi_device: claim a device using its unique GUID |
| 621 * @ti: current dm_target |
| 622 * @guid_string: 36 byte GUID |
| 623 * (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) |
| 624 * @dev_start: offset in sectors passed to dm_get_device |
| 625 * @dev_len: length in sectors passed to dm_get_device |
| 626 * @dm_dev: dm_dev to populate |
| 627 * |
| 628 * Wraps dm_get_device allowing it to use a unique partition GUID to |
| 629 * find a given partition on any drive. This code is based on |
| 630 * printk_all_partitions in that it walks all of the register block devices. |
| 631 * |
| 632 * N.B., guid_string is not checked for safety. |
| 633 */ |
| 634 static int dm_get_efi_device(struct dm_target *ti, |
| 635 const char *guid_string, |
| 636 sector_t dev_start, |
| 637 sector_t dev_len, |
| 638 struct dm_dev **dm_dev) |
| 639 { |
| 640 #ifdef CONFIG_EFI_PARTITION |
| 641 int part = 0; |
| 642 efi_guid_t guid; |
| 643 struct class_dev_iter iter; |
| 644 struct device *dev; |
| 645 dev_t devt = 0; |
| 646 char devt_buf[BDEVT_SIZE]; |
| 647 |
| 648 DMDEBUG("dm_get_efi_device called"); |
| 649 if (!efi_parse_guid(guid_string, guid.b)) |
| 650 goto bad_guid; |
| 651 DMDEBUG("GUID parsed"); |
| 652 |
| 653 /* Walks the block_class. Since we can't access gendisk's |
| 654 * device_type, we just filter out entries with no devnode below. |
| 655 */ |
| 656 class_dev_iter_init(&iter, &block_class, NULL, NULL); |
| 657 while ((dev = class_dev_iter_next(&iter))) { |
| 658 struct gendisk *disk = dev_to_disk(dev); |
| 659 struct block_device *bdev = NULL; |
| 660 |
| 661 DMDEBUG("Walking %u:%u", MAJOR(dev->devt), MINOR(dev->devt)); |
| 662 |
| 663 /* |
| 664 * Don't show empty devices or things that have been |
| 665 * surpressed |
| 666 */ |
| 667 if (!disk || get_capacity(disk) == 0 || |
| 668 (disk->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)) |
| 669 continue; |
| 670 |
| 671 if (!disk->part_tbl) { |
| 672 DMDEBUG("No partition table for %u:%u", |
| 673 MAJOR(disk_devt(disk)), |
| 674 MINOR(disk_devt(disk))); |
| 675 continue; |
| 676 } |
| 677 |
| 678 /* We're walking all disk and partitions so just grab disks. */ |
| 679 bdev = bdget_disk(disk, 0); |
| 680 if (!bdev) { |
| 681 DMDEBUG("No bdev for %u:%u. Skipping", |
| 682 MAJOR(dev->devt), MINOR(dev->devt)); |
| 683 continue; |
| 684 } |
| 685 |
| 686 /* Ensure we have a bd_disk. If nothing else has it opened, |
| 687 * there's no guarantee it'll be populated. |
| 688 */ |
| 689 int err = blkdev_get(bdev, FMODE_READ); |
| 690 if (err < 0) { |
| 691 DMDEBUG("Failed to blkdev_get: %d", err); |
| 692 bdput(bdev); |
| 693 continue; |
| 694 } |
| 695 |
| 696 DMDEBUG("find_efi_partition called for disk: %u:%u", |
| 697 MAJOR(dev->devt), MINOR(dev->devt)); |
| 698 part = efi_find_partition(&guid, bdev); |
| 699 /* Nb, it seems that calling bdput after blkdev_put |
| 700 * isn't common. If the inode was only in use here, |
| 701 * then it will end up I_CLEAR'd when bdput gets to it. |
| 702 */ |
| 703 blkdev_put(bdev, FMODE_READ); |
| 704 /* On match, create the dev node if possible.*/ |
| 705 if (part > 0) { |
| 706 devt = MKDEV(MAJOR(dev->devt), |
| 707 MINOR(dev->devt) + part); |
| 708 DMDEBUG("found a part! (%d %u:%u)", part, |
| 709 MAJOR(devt), MINOR(devt)); |
| 710 break; |
| 711 } |
| 712 } |
| 713 class_dev_iter_exit(&iter); |
| 714 |
| 715 if (part <= 0) |
| 716 goto found_nothing; |
| 717 |
| 718 /* Construct the dev name to pass to dm_get_device. This is roundabout |
| 719 * EFI partition scanning isn't exactly fast so it doesn't seem like a |
| 720 * bad tradeoff. |
| 721 */ |
| 722 snprintf(devt_buf, sizeof(devt_buf), "%u:%u", MAJOR(devt), MINOR(devt)); |
| 723 |
| 724 /* TODO(wad) to make this generic we could also pass in the mode. */ |
| 725 if (dm_get_device(ti, devt_buf, dev_start, dev_len, |
| 726 dm_table_get_mode(ti->table), dm_dev) == 0) |
| 727 return 0; |
| 728 |
| 729 ti->error = "Failed to acquire device"; |
| 730 DMDEBUG("Failed to acquire discovered device %s", devt_buf); |
| 731 return -1; |
| 732 bad_guid: |
| 733 ti->error = "Bad GUID"; |
| 734 DMDEBUG("Supplied value '%s' is an invalid GUID", guid_string); |
| 735 return -1; |
| 736 found_nothing: |
| 737 DMDEBUG("No matching partition for GUID: %s", guid_string); |
| 738 ti->error = "No matching GUID"; |
| 739 #endif |
| 740 return -1; |
| 741 } |
| 742 |
| 743 static int verity_get_device(struct dm_target *ti, const char *devname, |
| 744 sector_t dev_start, sector_t dev_len, |
| 745 struct dm_dev **dm_dev) |
| 746 { |
| 747 do { |
| 748 /* Try the normal path first since if everything is ready, it |
| 749 * will be the fastest. |
| 750 */ |
| 751 if (!dm_get_device(ti, devname, dev_start, dev_len, |
| 752 dm_table_get_mode(ti->table), dm_dev)) |
| 753 return 0; |
| 754 |
| 755 /* Try the device by EFI GUID */ |
| 756 if (!dm_get_efi_device(ti, devname, dev_start, dev_len, dm_dev)) |
| 757 return 0; |
| 758 |
| 759 /* No need to be too aggressive since this is a slow path. */ |
| 760 msleep(500); |
| 761 } while (dev_wait && (driver_probe_done() != 0 || *dm_dev == NULL)); |
| 762 async_synchronize_full(); |
| 763 return -1; |
| 764 } |
| 765 |
| 766 |
544 /*----------------------------------------------------------------- | 767 /*----------------------------------------------------------------- |
545 * Reverse flow of requests into the device. | 768 * Reverse flow of requests into the device. |
546 * | 769 * |
547 * (Start at the bottom with verity_map and work your way upward). | 770 * (Start at the bottom with verity_map and work your way upward). |
548 *-----------------------------------------------------------------*/ | 771 *-----------------------------------------------------------------*/ |
549 | 772 |
550 static void verity_inc_pending(struct dm_verity_io *io); | 773 static void verity_inc_pending(struct dm_verity_io *io); |
551 | 774 |
552 /* verity_dec_pending manages the lifetime of all dm_verity_io structs. | 775 /* verity_dec_pending manages the lifetime of all dm_verity_io structs. |
553 * Non-bug error handling is centralized through this interface and | 776 * Non-bug error handling is centralized through this interface and |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1249 if (dm_bht_set_root_hexdigest(&vc->bht, argv[5])) { | 1472 if (dm_bht_set_root_hexdigest(&vc->bht, argv[5])) { |
1250 DMERR("root hexdigest error"); | 1473 DMERR("root hexdigest error"); |
1251 goto bad_root_hexdigest; | 1474 goto bad_root_hexdigest; |
1252 } | 1475 } |
1253 dm_bht_set_read_cb(&vc->bht, kverityd_bht_read_callback); | 1476 dm_bht_set_read_cb(&vc->bht, kverityd_bht_read_callback); |
1254 dm_bht_set_entry_readahead(&vc->bht, bht_readahead); | 1477 dm_bht_set_entry_readahead(&vc->bht, bht_readahead); |
1255 | 1478 |
1256 /* arg0: device to verify */ | 1479 /* arg0: device to verify */ |
1257 vc->start = 0; /* TODO: should this support a starting offset? */ | 1480 vc->start = 0; /* TODO: should this support a starting offset? */ |
1258 /* We only ever grab the device in read-only mode. */ | 1481 /* We only ever grab the device in read-only mode. */ |
1259 » ret = dm_get_device(ti, argv[0], vc->start, ti->len, | 1482 » ret = verity_get_device(ti, argv[0], vc->start, ti->len, &vc->dev); |
1260 » » » dm_table_get_mode(ti->table), &vc->dev); | |
1261 if (ret) { | 1483 if (ret) { |
1262 DMERR("Failed to acquire device '%s': %d", argv[0], ret); | 1484 DMERR("Failed to acquire device '%s': %d", argv[0], ret); |
1263 ti->error = "Device lookup failed"; | 1485 ti->error = "Device lookup failed"; |
1264 goto bad_verity_dev; | 1486 goto bad_verity_dev; |
1265 } | 1487 } |
1266 | 1488 |
1267 if (PAGE_ALIGN(vc->start) != vc->start || | 1489 if (PAGE_ALIGN(vc->start) != vc->start || |
1268 PAGE_ALIGN(to_bytes(ti->len)) != to_bytes(ti->len)) { | 1490 PAGE_ALIGN(to_bytes(ti->len)) != to_bytes(ti->len)) { |
1269 ti->error = "Device must be PAGE_SIZE divisble/aligned"; | 1491 ti->error = "Device must be PAGE_SIZE divisble/aligned"; |
1270 goto bad_hash_start; | 1492 goto bad_hash_start; |
1271 } | 1493 } |
1272 | 1494 |
1273 /* arg2: offset to hash on the hash device */ | 1495 /* arg2: offset to hash on the hash device */ |
1274 if (sscanf(argv[2], "%llu", &tmpull) != 1) { | 1496 if (sscanf(argv[2], "%llu", &tmpull) != 1) { |
1275 ti->error = | 1497 ti->error = |
1276 "Invalid hash_start supplied"; | 1498 "Invalid hash_start supplied"; |
1277 goto bad_hash_start; | 1499 goto bad_hash_start; |
1278 } | 1500 } |
1279 vc->hash_start = (sector_t)(tmpull); | 1501 vc->hash_start = (sector_t)(tmpull); |
1280 | 1502 |
1281 /* arg1: device with hashes. | 1503 /* arg1: device with hashes. |
1282 * Note, arg1 == arg0 is okay as long as the size of | 1504 * Note, arg1 == arg0 is okay as long as the size of |
1283 * ti->len passed to device mapper does not include | 1505 * ti->len passed to device mapper does not include |
1284 * the hashes. | 1506 * the hashes. |
1285 */ | 1507 */ |
1286 » if (dm_get_device(ti, argv[1], vc->hash_start, dm_bht_sectors(&vc->bht), | 1508 » if (verity_get_device(ti, argv[1], vc->hash_start, |
1287 » » » dm_table_get_mode(ti->table), &vc->hash_dev)) { | 1509 » » » dm_bht_sectors(&vc->bht), &vc->hash_dev)) { |
1288 ti->error = "Hash device lookup failed"; | 1510 ti->error = "Hash device lookup failed"; |
1289 goto bad_hash_dev; | 1511 goto bad_hash_dev; |
1290 } | 1512 } |
1291 | 1513 |
1292 /* We leave the validity on the hash device open until the | 1514 /* We leave the validity on the hash device open until the |
1293 * next arg. Then we go ahead and try to read in all the bundle | 1515 * next arg. Then we go ahead and try to read in all the bundle |
1294 * hashes which live after the block hashes. If it fails, then | 1516 * hashes which live after the block hashes. If it fails, then |
1295 * the hash offset was wrong. | 1517 * the hash offset was wrong. |
1296 */ | 1518 */ |
1297 | 1519 |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1549 dm_unregister_target(&verity_target); | 1771 dm_unregister_target(&verity_target); |
1550 kmem_cache_destroy(_verity_io_pool); | 1772 kmem_cache_destroy(_verity_io_pool); |
1551 } | 1773 } |
1552 | 1774 |
1553 module_init(dm_verity_init); | 1775 module_init(dm_verity_init); |
1554 module_exit(dm_verity_exit); | 1776 module_exit(dm_verity_exit); |
1555 | 1777 |
1556 MODULE_AUTHOR("The Chromium OS Authors <chromium-os-dev@chromium.org>"); | 1778 MODULE_AUTHOR("The Chromium OS Authors <chromium-os-dev@chromium.org>"); |
1557 MODULE_DESCRIPTION(DM_NAME " target for transparent disk integrity checking"); | 1779 MODULE_DESCRIPTION(DM_NAME " target for transparent disk integrity checking"); |
1558 MODULE_LICENSE("GPL"); | 1780 MODULE_LICENSE("GPL"); |
OLD | NEW |