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 (addr < PAGE_SIZE) 37 addr = PAGE_SIZE; 38 39 if (WARN_ON(!check_encodable(addr, size))) 40 return false; 41 42 /* Encode and decode */ 43 { 44 const long encoded_watchpoint = 45 encode_watchpoint(addr, size, is_write); 46 unsigned long verif_masked_addr; 47 size_t verif_size; 48 bool verif_is_write; 49 50 /* Check special watchpoints */ 51 if (WARN_ON(decode_watchpoint( 52 INVALID_WATCHPOINT, &verif_masked_addr, 53 &verif_size, &verif_is_write))) 54 return false; 55 if (WARN_ON(decode_watchpoint( 56 CONSUMED_WATCHPOINT, &verif_masked_addr, 57 &verif_size, &verif_is_write))) 58 return false; 59 60 /* Check decoding watchpoint returns same data */ 61 if (WARN_ON(!decode_watchpoint( 62 encoded_watchpoint, &verif_masked_addr, 63 &verif_size, &verif_is_write))) 64 return false; 65 if (WARN_ON(verif_masked_addr != 66 (addr & WATCHPOINT_ADDR_MASK))) 67 goto fail; 68 if (WARN_ON(verif_size != size)) 69 goto fail; 70 if (WARN_ON(is_write != verif_is_write)) 71 goto fail; 72 73 continue; 74 fail: 75 pr_err("%s fail: %s %zu bytes @ %lx -> encoded: %lx -> %s %zu bytes @ %lx\n", 76 __func__, is_write ? "write" : "read", size, 77 addr, encoded_watchpoint, 78 verif_is_write ? "write" : "read", verif_size, 79 verif_masked_addr); 80 return false; 81 } 82 } 83 84 return true; 85 } 86 87 /* Test access matching function. */ 88 static bool test_matching_access(void) 89 { 90 if (WARN_ON(!matching_access(10, 1, 10, 1))) 91 return false; 92 if (WARN_ON(!matching_access(10, 2, 11, 1))) 93 return false; 94 if (WARN_ON(!matching_access(10, 1, 9, 2))) 95 return false; 96 if (WARN_ON(matching_access(10, 1, 11, 1))) 97 return false; 98 if (WARN_ON(matching_access(9, 1, 10, 1))) 99 return false; 100 101 /* 102 * An access of size 0 could match another access, as demonstrated here. 103 * Rather than add more comparisons to 'matching_access()', which would 104 * end up in the fast-path for *all* checks, check_access() simply 105 * returns for all accesses of size 0. 106 */ 107 if (WARN_ON(!matching_access(8, 8, 12, 0))) 108 return false; 109 110 return true; 111 } 112 113 static int __init kcsan_selftest(void) 114 { 115 int passed = 0; 116 int total = 0; 117 118 #define RUN_TEST(do_test) \ 119 do { \ 120 ++total; \ 121 if (do_test()) \ 122 ++passed; \ 123 else \ 124 pr_err("selftest: " #do_test " failed"); \ 125 } while (0) 126 127 RUN_TEST(test_requires); 128 RUN_TEST(test_encode_decode); 129 RUN_TEST(test_matching_access); 130 131 pr_info("selftest: %d/%d tests passed\n", passed, total); 132 if (passed != total) 133 panic("selftests failed"); 134 return 0; 135 } 136 postcore_initcall(kcsan_selftest); 137