|
14 | 14 | #include <linux/init.h>
|
15 | 15 | #include <linux/kernel.h>
|
16 | 16 | #include <linux/list.h>
|
| 17 | +#include <linux/minmax.h> |
17 | 18 | #include <linux/moduleparam.h>
|
18 | 19 | #include <linux/percpu.h>
|
19 | 20 | #include <linux/preempt.h>
|
20 | 21 | #include <linux/sched.h>
|
| 22 | +#include <linux/string.h> |
21 | 23 | #include <linux/uaccess.h>
|
22 | 24 |
|
23 | 25 | #include "encoding.h"
|
@@ -1308,3 +1310,51 @@ noinline void __tsan_atomic_signal_fence(int memorder)
|
1308 | 1310 | }
|
1309 | 1311 | }
|
1310 | 1312 | EXPORT_SYMBOL(__tsan_atomic_signal_fence);
|
| 1313 | + |
| 1314 | +#ifdef __HAVE_ARCH_MEMSET |
| 1315 | +void *__tsan_memset(void *s, int c, size_t count); |
| 1316 | +noinline void *__tsan_memset(void *s, int c, size_t count) |
| 1317 | +{ |
| 1318 | + /* |
| 1319 | + * Instead of not setting up watchpoints where accessed size is greater |
| 1320 | + * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE. |
| 1321 | + */ |
| 1322 | + size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE); |
| 1323 | + |
| 1324 | + check_access(s, check_len, KCSAN_ACCESS_WRITE, _RET_IP_); |
| 1325 | + return memset(s, c, count); |
| 1326 | +} |
| 1327 | +#else |
| 1328 | +void *__tsan_memset(void *s, int c, size_t count) __alias(memset); |
| 1329 | +#endif |
| 1330 | +EXPORT_SYMBOL(__tsan_memset); |
| 1331 | + |
| 1332 | +#ifdef __HAVE_ARCH_MEMMOVE |
| 1333 | +void *__tsan_memmove(void *dst, const void *src, size_t len); |
| 1334 | +noinline void *__tsan_memmove(void *dst, const void *src, size_t len) |
| 1335 | +{ |
| 1336 | + size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE); |
| 1337 | + |
| 1338 | + check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_); |
| 1339 | + check_access(src, check_len, 0, _RET_IP_); |
| 1340 | + return memmove(dst, src, len); |
| 1341 | +} |
| 1342 | +#else |
| 1343 | +void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove); |
| 1344 | +#endif |
| 1345 | +EXPORT_SYMBOL(__tsan_memmove); |
| 1346 | + |
| 1347 | +#ifdef __HAVE_ARCH_MEMCPY |
| 1348 | +void *__tsan_memcpy(void *dst, const void *src, size_t len); |
| 1349 | +noinline void *__tsan_memcpy(void *dst, const void *src, size_t len) |
| 1350 | +{ |
| 1351 | + size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE); |
| 1352 | + |
| 1353 | + check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_); |
| 1354 | + check_access(src, check_len, 0, _RET_IP_); |
| 1355 | + return memcpy(dst, src, len); |
| 1356 | +} |
| 1357 | +#else |
| 1358 | +void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy); |
| 1359 | +#endif |
| 1360 | +EXPORT_SYMBOL(__tsan_memcpy); |
0 commit comments