Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: drivers/md/dm-bht.c

Issue 6684008: CHROMIUM: verity: use sg_set_buf instead of sg_set_page (Closed) Base URL: http://git.chromium.org/git/kernel.git@master
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org> 2 * Copyright (C) 2010 The Chromium OS Authors <chromium-os-dev@chromium.org>
3 * 3 *
4 * Device-Mapper block hash tree interface. 4 * Device-Mapper block hash tree interface.
5 * See Documentation/device-mapper/dm-bht.txt for details. 5 * See Documentation/device-mapper/dm-bht.txt for details.
6 * 6 *
7 * This file is released under the GPL. 7 * This file is released under the GPL.
8 */ 8 */
9 9
10 #include <asm/atomic.h> 10 #include <asm/atomic.h>
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 dm_bht_bin_to_hex(computed, computed_hex, bht->digest_size); 88 dm_bht_bin_to_hex(computed, computed_hex, bht->digest_size);
89 DMERR_LIMIT("%s != %s", given_hex, computed_hex); 89 DMERR_LIMIT("%s != %s", given_hex, computed_hex);
90 } 90 }
91 91
92 /* Used for turning verifiers into computers */ 92 /* Used for turning verifiers into computers */
93 typedef int (*dm_bht_compare_cb)(struct dm_bht *, u8 *, u8 *); 93 typedef int (*dm_bht_compare_cb)(struct dm_bht *, u8 *, u8 *);
94 94
95 /** 95 /**
96 * dm_bht_compute_hash: hashes a page of data 96 * dm_bht_compute_hash: hashes a page of data
97 */ 97 */
98 static int dm_bht_compute_hash(struct dm_bht *bht, struct page *page, 98 static int dm_bht_compute_hash(struct dm_bht *bht, const void *block,
99 u8 *digest) 99 u8 *digest)
100 { 100 {
101 struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()]; 101 struct hash_desc *hash_desc = &bht->hash_desc[smp_processor_id()];
102 struct scatterlist sg; 102 struct scatterlist sg;
103 103
104 sg_init_table(&sg, 1); 104 sg_init_table(&sg, 1);
105 » sg_set_page(&sg, page, PAGE_SIZE, 0); 105 » sg_set_buf(&sg, block, PAGE_SIZE);
Will Drewry 2011/03/11 19:01:57 I considered using this before but don't we need t
106 /* Note, this is synchronous. */ 106 /* Note, this is synchronous. */
107 if (crypto_hash_init(hash_desc)) { 107 if (crypto_hash_init(hash_desc)) {
108 DMCRIT("failed to reinitialize crypto hash (proc:%d)", 108 DMCRIT("failed to reinitialize crypto hash (proc:%d)",
109 smp_processor_id()); 109 smp_processor_id());
110 return -EINVAL; 110 return -EINVAL;
111 } 111 }
112 if (crypto_hash_digest(hash_desc, &sg, PAGE_SIZE, digest)) { 112 if (crypto_hash_digest(hash_desc, &sg, PAGE_SIZE, digest)) {
113 DMCRIT("crypto_hash_digest failed"); 113 DMCRIT("crypto_hash_digest failed");
114 return -EINVAL; 114 return -EINVAL;
115 } 115 }
(...skipping 478 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 block_index); 594 block_index);
595 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; 595 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
596 u8 *node; 596 u8 *node;
597 597
598 /* This call is only safe if all nodes along the path 598 /* This call is only safe if all nodes along the path
599 * are already populated (i.e. READY) via dm_bht_populate. 599 * are already populated (i.e. READY) via dm_bht_populate.
600 */ 600 */
601 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY); 601 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY);
602 602
603 node = dm_bht_get_node(bht, parent, depth, block_index); 603 node = dm_bht_get_node(bht, parent, depth, block_index);
604 » if (dm_bht_compute_hash(bht, virt_to_page(block), digest) || 604 » if (dm_bht_compute_hash(bht, block, digest) ||
605 dm_bht_compare_hash(bht, digest, node)) { 605 dm_bht_compare_hash(bht, digest, node)) {
606 DMERR("failed to verify entry's hash against parent " 606 DMERR("failed to verify entry's hash against parent "
607 "(d=%u,bi=%u)", depth, block_index); 607 "(d=%u,bi=%u)", depth, block_index);
608 return DM_BHT_ENTRY_ERROR_MISMATCH; 608 return DM_BHT_ENTRY_ERROR_MISMATCH;
609 } 609 }
610 return 0; 610 return 0;
611 } 611 }
612 612
613 /* Walk all entries at level 0 to compute the root digest. 613 /* Walk all entries at level 0 to compute the root digest.
614 * 0 on success. 614 * 0 on success.
(...skipping 14 matching lines...) Expand all
629 } 629 }
630 630
631 /* Point the scatterlist to the entries, then compute the digest */ 631 /* Point the scatterlist to the entries, then compute the digest */
632 for (count = 0; count < bht->levels[0].count; ++count, ++entry) { 632 for (count = 0; count < bht->levels[0].count; ++count, ++entry) {
633 if (atomic_read(&entry->state) <= DM_BHT_ENTRY_PENDING) { 633 if (atomic_read(&entry->state) <= DM_BHT_ENTRY_PENDING) {
634 DMCRIT("data not ready to compute root: %u", 634 DMCRIT("data not ready to compute root: %u",
635 count); 635 count);
636 return 1; 636 return 1;
637 } 637 }
638 sg_init_table(&sg, 1); 638 sg_init_table(&sg, 1);
639 » » sg_set_page(&sg, virt_to_page(entry->nodes), PAGE_SIZE, 0); 639 » » sg_set_buf(&sg, entry->nodes, PAGE_SIZE);
Will Drewry 2011/03/11 19:01:57 This one is known safe since we use a page pool :)
640 if (crypto_hash_update(hash_desc, &sg, PAGE_SIZE)) { 640 if (crypto_hash_update(hash_desc, &sg, PAGE_SIZE)) {
641 DMCRIT("Failed to update crypto hash"); 641 DMCRIT("Failed to update crypto hash");
642 return -EINVAL; 642 return -EINVAL;
643 } 643 }
644 } 644 }
645 645
646 if (crypto_hash_final(hash_desc, digest)) { 646 if (crypto_hash_final(hash_desc, digest)) {
647 DMCRIT("Failed to compute final digest"); 647 DMCRIT("Failed to compute final digest");
648 return -EINVAL; 648 return -EINVAL;
649 } 649 }
(...skipping 29 matching lines...) Expand all
679 * Verifies the path from block_index to depth=0. Returns 0 on ok. 679 * Verifies the path from block_index to depth=0. Returns 0 on ok.
680 */ 680 */
681 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index) 681 static int dm_bht_verify_path(struct dm_bht *bht, unsigned int block_index)
682 { 682 {
683 unsigned int depth = bht->depth - 1; 683 unsigned int depth = bht->depth - 1;
684 struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index); 684 struct dm_bht_entry *entry = dm_bht_get_entry(bht, depth, block_index);
685 685
686 while (depth > 0) { 686 while (depth > 0) {
687 u8 digest[DM_BHT_MAX_DIGEST_SIZE]; 687 u8 digest[DM_BHT_MAX_DIGEST_SIZE];
688 struct dm_bht_entry *parent; 688 struct dm_bht_entry *parent;
689 struct page *page;
690 u8 *node; 689 u8 *node;
691 int state; 690 int state;
692 691
693 DMDEBUG("verify_path for b=%u on d=%d", block_index, depth); 692 DMDEBUG("verify_path for b=%u on d=%d", block_index, depth);
694 /* TODO(msb,wad): would be nice to avoid two atomic reads */ 693 /* TODO(msb,wad): would be nice to avoid two atomic reads */
695 state = atomic_read(&entry->state); 694 state = atomic_read(&entry->state);
696 if (state == DM_BHT_ENTRY_VERIFIED) { 695 if (state == DM_BHT_ENTRY_VERIFIED) {
697 DMDEBUG("verify_path node %u is verified to root", 696 DMDEBUG("verify_path node %u is verified to root",
698 block_index); 697 block_index);
699 depth++; /* avoid an extra cmpxchg */ 698 depth++; /* avoid an extra cmpxchg */
(...skipping 11 matching lines...) Expand all
711 710
712 /* We need to check that this entry matches the expected 711 /* We need to check that this entry matches the expected
713 * hash in the parent->nodes. 712 * hash in the parent->nodes.
714 */ 713 */
715 parent = dm_bht_get_entry(bht, depth - 1, block_index); 714 parent = dm_bht_get_entry(bht, depth - 1, block_index);
716 /* This call is only safe if all nodes along the path 715 /* This call is only safe if all nodes along the path
717 * are already populated (i.e. READY) via dm_bht_populate. 716 * are already populated (i.e. READY) via dm_bht_populate.
718 */ 717 */
719 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY); 718 BUG_ON(atomic_read(&parent->state) < DM_BHT_ENTRY_READY);
720 node = dm_bht_get_node(bht, parent, depth, block_index); 719 node = dm_bht_get_node(bht, parent, depth, block_index);
721 page = virt_to_page(entry->nodes);
722 720
723 » » if (dm_bht_compute_hash(bht, page, digest) || 721 » » if (dm_bht_compute_hash(bht, entry->nodes, digest) ||
724 dm_bht_compare_hash(bht, digest, node)) { 722 dm_bht_compare_hash(bht, digest, node)) {
725 DMERR("failed to verify entry's hash against parent " 723 DMERR("failed to verify entry's hash against parent "
726 "(d=%u,bi=%u)", depth, block_index); 724 "(d=%u,bi=%u)", depth, block_index);
727 goto mismatch; 725 goto mismatch;
728 } 726 }
729 727
730 entry = parent; 728 entry = parent;
731 depth--; 729 depth--;
732 } 730 }
733 /* Mark path to leaf as verified. */ 731 /* Mark path to leaf as verified. */
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 atomic_set(&entry->state, DM_BHT_ENTRY_READY); 808 atomic_set(&entry->state, DM_BHT_ENTRY_READY);
811 } else if (state <= DM_BHT_ENTRY_ERROR) { 809 } else if (state <= DM_BHT_ENTRY_ERROR) {
812 DMCRIT("leaf entry for block %u is invalid", 810 DMCRIT("leaf entry for block %u is invalid",
813 block_index); 811 block_index);
814 return state; 812 return state;
815 } else if (state == DM_BHT_ENTRY_PENDING) { 813 } else if (state == DM_BHT_ENTRY_PENDING) {
816 DMERR("leaf data is pending for block %u", block_index); 814 DMERR("leaf data is pending for block %u", block_index);
817 return 1; 815 return 1;
818 } 816 }
819 817
820 » dm_bht_compute_hash(bht, virt_to_page(block_data), 818 » dm_bht_compute_hash(bht, block_data,
821 dm_bht_node(bht, entry, node_index)); 819 dm_bht_node(bht, entry, node_index));
822 return 0; 820 return 0;
823 } 821 }
824 EXPORT_SYMBOL(dm_bht_store_block); 822 EXPORT_SYMBOL(dm_bht_store_block);
825 823
826 /** 824 /**
827 * dm_bht_zeroread_callback - read callback which always returns 0s 825 * dm_bht_zeroread_callback - read callback which always returns 0s
828 * @ctx: ignored 826 * @ctx: ignored
829 * @start: ignored 827 * @start: ignored
830 * @data: buffer to write 0s to 828 * @data: buffer to write 0s to
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 874
877 r = dm_bht_maybe_read_entries(bht, read_cb_ctx, depth, 875 r = dm_bht_maybe_read_entries(bht, read_cb_ctx, depth,
878 0, level->count, true); 876 0, level->count, true);
879 if (r < 0) { 877 if (r < 0) {
880 DMCRIT("an error occurred while reading entry"); 878 DMCRIT("an error occurred while reading entry");
881 goto out; 879 goto out;
882 } 880 }
883 881
884 for (i = 0; i < level->count; i++, entry++) { 882 for (i = 0; i < level->count; i++, entry++) {
885 for (j = 0; j < count; j++, child++) { 883 for (j = 0; j < count; j++, child++) {
886 » » » » struct page *pg = virt_to_page(child->nodes); 884 » » » » u8 *block = child->nodes;
887 » » » » u8 *node = dm_bht_node(bht, entry, j); 885 » » » » u8 *digest = dm_bht_node(bht, entry, j);
888 886
889 » » » » r = dm_bht_compute_hash(bht, pg, node); 887 » » » » r = dm_bht_compute_hash(bht, block, digest);
890 if (r) { 888 if (r) {
891 DMERR("Failed to update (d=%u,i=%u)", 889 DMERR("Failed to update (d=%u,i=%u)",
892 depth, i); 890 depth, i);
893 goto out; 891 goto out;
894 } 892 }
895 } 893 }
896 } 894 }
897 } 895 }
898 /* Don't forget the root digest! */ 896 /* Don't forget the root digest! */
899 DMDEBUG("Calling verify_root with update_hash"); 897 DMDEBUG("Calling verify_root with update_hash");
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 DMERR("no root digest exists to export"); 1228 DMERR("no root digest exists to export");
1231 if (available > 0) 1229 if (available > 0)
1232 *hexdigest = 0; 1230 *hexdigest = 0;
1233 return -1; 1231 return -1;
1234 } 1232 }
1235 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size); 1233 dm_bht_bin_to_hex(bht->root_digest, hexdigest, bht->digest_size);
1236 return 0; 1234 return 0;
1237 } 1235 }
1238 EXPORT_SYMBOL(dm_bht_root_hexdigest); 1236 EXPORT_SYMBOL(dm_bht_root_hexdigest);
1239 1237
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698