1 // SPDX-License-Identifier: GPL-2.0-only 2 3 #include <linux/list.h> 4 #include <linux/kernel.h> 5 #include <linux/dm-verity-loadpin.h> 6 7 #include "dm.h" 8 #include "dm-core.h" 9 #include "dm-verity.h" 10 11 #define DM_MSG_PREFIX "verity-loadpin" 12 13 LIST_HEAD(dm_verity_loadpin_trusted_root_digests); 14 15 static bool is_trusted_verity_target(struct dm_target *ti) 16 { 17 u8 *root_digest; 18 unsigned int digest_size; 19 struct dm_verity_loadpin_trusted_root_digest *trd; 20 bool trusted = false; 21 22 if (!dm_is_verity_target(ti)) 23 return false; 24 25 if (dm_verity_get_root_digest(ti, &root_digest, &digest_size)) 26 return false; 27 28 list_for_each_entry(trd, &dm_verity_loadpin_trusted_root_digests, node) { 29 if ((trd->len == digest_size) && 30 !memcmp(trd->data, root_digest, digest_size)) { 31 trusted = true; 32 break; 33 } 34 } 35 36 kfree(root_digest); 37 38 return trusted; 39 } 40 41 /* 42 * Determines whether the file system of a superblock is located on 43 * a verity device that is trusted by LoadPin. 44 */ 45 bool dm_verity_loadpin_is_bdev_trusted(struct block_device *bdev) 46 { 47 struct mapped_device *md; 48 struct dm_table *table; 49 struct dm_target *ti; 50 int srcu_idx; 51 bool trusted = false; 52 53 if (list_empty(&dm_verity_loadpin_trusted_root_digests)) 54 return false; 55 56 md = dm_get_md(bdev->bd_dev); 57 if (!md) 58 return false; 59 60 table = dm_get_live_table(md, &srcu_idx); 61 62 if (table->num_targets != 1) 63 goto out; 64 65 ti = dm_table_get_target(table, 0); 66 67 if (is_trusted_verity_target(ti)) 68 trusted = true; 69 70 out: 71 dm_put_live_table(md, srcu_idx); 72 dm_put(md); 73 74 return trusted; 75 } 76