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