dm-verity-loadpin.c 1.7 KB

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