1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 2 3 /* 3 /* 4 * This header provides generic wrappers for m 4 * This header provides generic wrappers for memory access instrumentation that 5 * the compiler cannot emit for: KASAN, KCSAN, !! 5 * the compiler cannot emit for: KASAN, KCSAN. 6 */ 6 */ 7 #ifndef _LINUX_INSTRUMENTED_H 7 #ifndef _LINUX_INSTRUMENTED_H 8 #define _LINUX_INSTRUMENTED_H 8 #define _LINUX_INSTRUMENTED_H 9 9 10 #include <linux/compiler.h> 10 #include <linux/compiler.h> 11 #include <linux/kasan-checks.h> 11 #include <linux/kasan-checks.h> 12 #include <linux/kcsan-checks.h> 12 #include <linux/kcsan-checks.h> 13 #include <linux/kmsan-checks.h> << 14 #include <linux/types.h> 13 #include <linux/types.h> 15 14 16 /** 15 /** 17 * instrument_read - instrument regular read a 16 * instrument_read - instrument regular read access 18 * @v: address of access << 19 * @size: size of access << 20 * 17 * 21 * Instrument a regular read access. The instr 18 * Instrument a regular read access. The instrumentation should be inserted 22 * before the actual read happens. 19 * before the actual read happens. >> 20 * >> 21 * @ptr address of access >> 22 * @size size of access 23 */ 23 */ 24 static __always_inline void instrument_read(co 24 static __always_inline void instrument_read(const volatile void *v, size_t size) 25 { 25 { 26 kasan_check_read(v, size); 26 kasan_check_read(v, size); 27 kcsan_check_read(v, size); 27 kcsan_check_read(v, size); 28 } 28 } 29 29 30 /** 30 /** 31 * instrument_write - instrument regular write 31 * instrument_write - instrument regular write access 32 * @v: address of access << 33 * @size: size of access << 34 * 32 * 35 * Instrument a regular write access. The inst 33 * Instrument a regular write access. The instrumentation should be inserted 36 * before the actual write happens. 34 * before the actual write happens. >> 35 * >> 36 * @ptr address of access >> 37 * @size size of access 37 */ 38 */ 38 static __always_inline void instrument_write(c 39 static __always_inline void instrument_write(const volatile void *v, size_t size) 39 { 40 { 40 kasan_check_write(v, size); 41 kasan_check_write(v, size); 41 kcsan_check_write(v, size); 42 kcsan_check_write(v, size); 42 } 43 } 43 44 44 /** 45 /** 45 * instrument_read_write - instrument regular << 46 * @v: address of access << 47 * @size: size of access << 48 * << 49 * Instrument a regular write access. The inst << 50 * before the actual write happens. << 51 */ << 52 static __always_inline void instrument_read_wr << 53 { << 54 kasan_check_write(v, size); << 55 kcsan_check_read_write(v, size); << 56 } << 57 << 58 /** << 59 * instrument_atomic_read - instrument atomic 46 * instrument_atomic_read - instrument atomic read access 60 * @v: address of access << 61 * @size: size of access << 62 * 47 * 63 * Instrument an atomic read access. The instr 48 * Instrument an atomic read access. The instrumentation should be inserted 64 * before the actual read happens. 49 * before the actual read happens. >> 50 * >> 51 * @ptr address of access >> 52 * @size size of access 65 */ 53 */ 66 static __always_inline void instrument_atomic_ 54 static __always_inline void instrument_atomic_read(const volatile void *v, size_t size) 67 { 55 { 68 kasan_check_read(v, size); 56 kasan_check_read(v, size); 69 kcsan_check_atomic_read(v, size); 57 kcsan_check_atomic_read(v, size); 70 } 58 } 71 59 72 /** 60 /** 73 * instrument_atomic_write - instrument atomic 61 * instrument_atomic_write - instrument atomic write access 74 * @v: address of access << 75 * @size: size of access << 76 * 62 * 77 * Instrument an atomic write access. The inst 63 * Instrument an atomic write access. The instrumentation should be inserted 78 * before the actual write happens. 64 * before the actual write happens. >> 65 * >> 66 * @ptr address of access >> 67 * @size size of access 79 */ 68 */ 80 static __always_inline void instrument_atomic_ 69 static __always_inline void instrument_atomic_write(const volatile void *v, size_t size) 81 { 70 { 82 kasan_check_write(v, size); 71 kasan_check_write(v, size); 83 kcsan_check_atomic_write(v, size); 72 kcsan_check_atomic_write(v, size); 84 } 73 } 85 74 86 /** 75 /** 87 * instrument_atomic_read_write - instrument a << 88 * @v: address of access << 89 * @size: size of access << 90 * << 91 * Instrument an atomic read-write access. The << 92 * inserted before the actual write happens. << 93 */ << 94 static __always_inline void instrument_atomic_ << 95 { << 96 kasan_check_write(v, size); << 97 kcsan_check_atomic_read_write(v, size) << 98 } << 99 << 100 /** << 101 * instrument_copy_to_user - instrument reads 76 * instrument_copy_to_user - instrument reads of copy_to_user 102 * @to: destination address << 103 * @from: source address << 104 * @n: number of bytes to copy << 105 * 77 * 106 * Instrument reads from kernel memory, that a 78 * Instrument reads from kernel memory, that are due to copy_to_user (and 107 * variants). The instrumentation must be inse 79 * variants). The instrumentation must be inserted before the accesses. >> 80 * >> 81 * @to destination address >> 82 * @from source address >> 83 * @n number of bytes to copy 108 */ 84 */ 109 static __always_inline void 85 static __always_inline void 110 instrument_copy_to_user(void __user *to, const 86 instrument_copy_to_user(void __user *to, const void *from, unsigned long n) 111 { 87 { 112 kasan_check_read(from, n); 88 kasan_check_read(from, n); 113 kcsan_check_read(from, n); 89 kcsan_check_read(from, n); 114 kmsan_copy_to_user(to, from, n, 0); << 115 } 90 } 116 91 117 /** 92 /** 118 * instrument_copy_from_user_before - add inst !! 93 * instrument_copy_from_user - instrument writes of copy_from_user 119 * @to: destination address << 120 * @from: source address << 121 * @n: number of bytes to copy << 122 * 94 * 123 * Instrument writes to kernel memory, that ar 95 * Instrument writes to kernel memory, that are due to copy_from_user (and 124 * variants). The instrumentation should be in 96 * variants). The instrumentation should be inserted before the accesses. 125 */ << 126 static __always_inline void << 127 instrument_copy_from_user_before(const void *t << 128 { << 129 kasan_check_write(to, n); << 130 kcsan_check_write(to, n); << 131 } << 132 << 133 /** << 134 * instrument_copy_from_user_after - add instr << 135 * @to: destination address << 136 * @from: source address << 137 * @n: number of bytes to copy << 138 * @left: number of bytes not copied (as retur << 139 * 97 * 140 * Instrument writes to kernel memory, that ar !! 98 * @to destination address 141 * variants). The instrumentation should be in !! 99 * @from source address >> 100 * @n number of bytes to copy 142 */ 101 */ 143 static __always_inline void 102 static __always_inline void 144 instrument_copy_from_user_after(const void *to !! 103 instrument_copy_from_user(const void *to, const void __user *from, unsigned long n) 145 unsigned long << 146 { << 147 kmsan_unpoison_memory(to, n - left); << 148 } << 149 << 150 /** << 151 * instrument_memcpy_before - add instrumentat << 152 * @to: destination address << 153 * @from: source address << 154 * @n: number of bytes to copy << 155 * << 156 * Instrument memory accesses that happen in c << 157 * instrumentation should be inserted before t << 158 */ << 159 static __always_inline void instrument_memcpy_ << 160 << 161 { 104 { 162 kasan_check_write(to, n); 105 kasan_check_write(to, n); 163 kasan_check_read(from, n); << 164 kcsan_check_write(to, n); 106 kcsan_check_write(to, n); 165 kcsan_check_read(from, n); << 166 } << 167 << 168 /** << 169 * instrument_memcpy_after - add instrumentati << 170 * @to: destination address << 171 * @from: source address << 172 * @n: number of bytes to copy << 173 * @left: number of bytes not copied (if known << 174 * << 175 * Instrument memory accesses that happen in c << 176 * instrumentation should be inserted after th << 177 */ << 178 static __always_inline void instrument_memcpy_ << 179 << 180 << 181 { << 182 kmsan_memmove(to, from, n - left); << 183 } 107 } 184 << 185 /** << 186 * instrument_get_user() - add instrumentation << 187 * @to: destination variable, may not be addre << 188 * << 189 * get_user() and friends are fragile, so it m << 190 * whether the instrumentation happens before << 191 * the userspace. << 192 */ << 193 #define instrument_get_user(to) << 194 ({ << 195 u64 __tmp = (u64)(to); << 196 kmsan_unpoison_memory(&__tmp, sizeof(_ << 197 to = __tmp; << 198 }) << 199 << 200 << 201 /** << 202 * instrument_put_user() - add instrumentation << 203 * @from: source address << 204 * @ptr: userspace pointer to copy to << 205 * @size: number of bytes to copy << 206 * << 207 * put_user() and friends are fragile, so it m << 208 * whether the instrumentation happens before << 209 * the userspace. << 210 */ << 211 #define instrument_put_user(from, ptr, size) << 212 ({ << 213 kmsan_copy_to_user(ptr, &from, sizeof( << 214 }) << 215 108 216 #endif /* _LINUX_INSTRUMENTED_H */ 109 #endif /* _LINUX_INSTRUMENTED_H */ 217 110
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.