selftest.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // SPDX-License-Identifier: GPL-2.0
  2. #define pr_fmt(fmt) "kcsan: " fmt
  3. #include <linux/init.h>
  4. #include <linux/kernel.h>
  5. #include <linux/printk.h>
  6. #include <linux/random.h>
  7. #include <linux/types.h>
  8. #include "encoding.h"
  9. #define ITERS_PER_TEST 2000
  10. /* Test requirements. */
  11. static bool test_requires(void)
  12. {
  13. /* random should be initialized for the below tests */
  14. return prandom_u32() + prandom_u32() != 0;
  15. }
  16. /*
  17. * Test watchpoint encode and decode: check that encoding some access's info,
  18. * and then subsequent decode preserves the access's info.
  19. */
  20. static bool test_encode_decode(void)
  21. {
  22. int i;
  23. for (i = 0; i < ITERS_PER_TEST; ++i) {
  24. size_t size = prandom_u32_max(MAX_ENCODABLE_SIZE) + 1;
  25. bool is_write = !!prandom_u32_max(2);
  26. unsigned long addr;
  27. prandom_bytes(&addr, sizeof(addr));
  28. if (WARN_ON(!check_encodable(addr, size)))
  29. return false;
  30. /* Encode and decode */
  31. {
  32. const long encoded_watchpoint =
  33. encode_watchpoint(addr, size, is_write);
  34. unsigned long verif_masked_addr;
  35. size_t verif_size;
  36. bool verif_is_write;
  37. /* Check special watchpoints */
  38. if (WARN_ON(decode_watchpoint(
  39. INVALID_WATCHPOINT, &verif_masked_addr,
  40. &verif_size, &verif_is_write)))
  41. return false;
  42. if (WARN_ON(decode_watchpoint(
  43. CONSUMED_WATCHPOINT, &verif_masked_addr,
  44. &verif_size, &verif_is_write)))
  45. return false;
  46. /* Check decoding watchpoint returns same data */
  47. if (WARN_ON(!decode_watchpoint(
  48. encoded_watchpoint, &verif_masked_addr,
  49. &verif_size, &verif_is_write)))
  50. return false;
  51. if (WARN_ON(verif_masked_addr !=
  52. (addr & WATCHPOINT_ADDR_MASK)))
  53. goto fail;
  54. if (WARN_ON(verif_size != size))
  55. goto fail;
  56. if (WARN_ON(is_write != verif_is_write))
  57. goto fail;
  58. continue;
  59. fail:
  60. pr_err("%s fail: %s %zu bytes @ %lx -> encoded: %lx -> %s %zu bytes @ %lx\n",
  61. __func__, is_write ? "write" : "read", size,
  62. addr, encoded_watchpoint,
  63. verif_is_write ? "write" : "read", verif_size,
  64. verif_masked_addr);
  65. return false;
  66. }
  67. }
  68. return true;
  69. }
  70. /* Test access matching function. */
  71. static bool test_matching_access(void)
  72. {
  73. if (WARN_ON(!matching_access(10, 1, 10, 1)))
  74. return false;
  75. if (WARN_ON(!matching_access(10, 2, 11, 1)))
  76. return false;
  77. if (WARN_ON(!matching_access(10, 1, 9, 2)))
  78. return false;
  79. if (WARN_ON(matching_access(10, 1, 11, 1)))
  80. return false;
  81. if (WARN_ON(matching_access(9, 1, 10, 1)))
  82. return false;
  83. /*
  84. * An access of size 0 could match another access, as demonstrated here.
  85. * Rather than add more comparisons to 'matching_access()', which would
  86. * end up in the fast-path for *all* checks, check_access() simply
  87. * returns for all accesses of size 0.
  88. */
  89. if (WARN_ON(!matching_access(8, 8, 12, 0)))
  90. return false;
  91. return true;
  92. }
  93. static int __init kcsan_selftest(void)
  94. {
  95. int passed = 0;
  96. int total = 0;
  97. #define RUN_TEST(do_test) \
  98. do { \
  99. ++total; \
  100. if (do_test()) \
  101. ++passed; \
  102. else \
  103. pr_err("selftest: " #do_test " failed"); \
  104. } while (0)
  105. RUN_TEST(test_requires);
  106. RUN_TEST(test_encode_decode);
  107. RUN_TEST(test_matching_access);
  108. pr_info("selftest: %d/%d tests passed\n", passed, total);
  109. if (passed != total)
  110. panic("selftests failed");
  111. return 0;
  112. }
  113. postcore_initcall(kcsan_selftest);