Commit f433cf21 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull KCSAN updates from Paul McKenney:

 - Add instrumentation for memcpy(), memset(), and memmove() for Clang
   v16+'s new function names that are used when the -fsanitize=thread
   argument is given

 - Fix objtool warnings from KCSAN's volatile instrumentation, and typos
   in a pair of Kconfig options' help clauses

* tag 'kcsan.2022.12.02a' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/linux-rcu:
  kcsan: Fix trivial typo in Kconfig help comments
  objtool, kcsan: Add volatile read/write instrumentation to whitelist
  kcsan: Instrument memcpy/memset/memmove with newer Clang
parents 5517a2ea 144b9152
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -14,10 +14,12 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/minmax.h>
#include <linux/moduleparam.h>
#include <linux/percpu.h>
#include <linux/preempt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/uaccess.h>

#include "encoding.h"
@@ -1308,3 +1310,51 @@ noinline void __tsan_atomic_signal_fence(int memorder)
	}
}
EXPORT_SYMBOL(__tsan_atomic_signal_fence);

#ifdef __HAVE_ARCH_MEMSET
void *__tsan_memset(void *s, int c, size_t count);
noinline void *__tsan_memset(void *s, int c, size_t count)
{
	/*
	 * Instead of not setting up watchpoints where accessed size is greater
	 * than MAX_ENCODABLE_SIZE, truncate checked size to MAX_ENCODABLE_SIZE.
	 */
	size_t check_len = min_t(size_t, count, MAX_ENCODABLE_SIZE);

	check_access(s, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
	return memset(s, c, count);
}
#else
void *__tsan_memset(void *s, int c, size_t count) __alias(memset);
#endif
EXPORT_SYMBOL(__tsan_memset);

#ifdef __HAVE_ARCH_MEMMOVE
void *__tsan_memmove(void *dst, const void *src, size_t len);
noinline void *__tsan_memmove(void *dst, const void *src, size_t len)
{
	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);

	check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
	check_access(src, check_len, 0, _RET_IP_);
	return memmove(dst, src, len);
}
#else
void *__tsan_memmove(void *dst, const void *src, size_t len) __alias(memmove);
#endif
EXPORT_SYMBOL(__tsan_memmove);

#ifdef __HAVE_ARCH_MEMCPY
void *__tsan_memcpy(void *dst, const void *src, size_t len);
noinline void *__tsan_memcpy(void *dst, const void *src, size_t len)
{
	size_t check_len = min_t(size_t, len, MAX_ENCODABLE_SIZE);

	check_access(dst, check_len, KCSAN_ACCESS_WRITE, _RET_IP_);
	check_access(src, check_len, 0, _RET_IP_);
	return memcpy(dst, src, len);
}
#else
void *__tsan_memcpy(void *dst, const void *src, size_t len) __alias(memcpy);
#endif
EXPORT_SYMBOL(__tsan_memcpy);
+3 −3
Original line number Diff line number Diff line
@@ -125,7 +125,7 @@ config KCSAN_SKIP_WATCH
	default 4000
	help
	  The number of per-CPU memory operations to skip, before another
	  watchpoint is set up, i.e. one in KCSAN_WATCH_SKIP per-CPU
	  watchpoint is set up, i.e. one in KCSAN_SKIP_WATCH per-CPU
	  memory operations are used to set up a watchpoint. A smaller value
	  results in more aggressive race detection, whereas a larger value
	  improves system performance at the cost of missing some races.
@@ -135,8 +135,8 @@ config KCSAN_SKIP_WATCH_RANDOMIZE
	default y
	help
	  If instruction skip count should be randomized, where the maximum is
	  KCSAN_WATCH_SKIP. If false, the chosen value is always
	  KCSAN_WATCH_SKIP.
	  KCSAN_SKIP_WATCH. If false, the chosen value is always
	  KCSAN_SKIP_WATCH.

config KCSAN_INTERRUPT_WATCHER
	bool "Interruptible watchers" if !KCSAN_STRICT
+10 −0
Original line number Diff line number Diff line
@@ -999,6 +999,16 @@ static const char *uaccess_safe_builtin[] = {
	"__tsan_read_write4",
	"__tsan_read_write8",
	"__tsan_read_write16",
	"__tsan_volatile_read1",
	"__tsan_volatile_read2",
	"__tsan_volatile_read4",
	"__tsan_volatile_read8",
	"__tsan_volatile_read16",
	"__tsan_volatile_write1",
	"__tsan_volatile_write2",
	"__tsan_volatile_write4",
	"__tsan_volatile_write8",
	"__tsan_volatile_write16",
	"__tsan_atomic8_load",
	"__tsan_atomic16_load",
	"__tsan_atomic32_load",