mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jann Horn <jannh@google.com>
To: Dmitry Vyukov <dvyukov@google.com>,
	 Andrey Konovalov <andreyknvl@gmail.com>,
	 Alexander Potapenko <glider@google.com>
Cc: Nathan Chancellor <nathan@kernel.org>,
	 Nick Desaulniers <nick.desaulniers+lkml@gmail.com>,
	 Bill Wendling <morbo@google.com>,
	Justin Stitt <justinstitt@google.com>,
	 linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com,
	 llvm@lists.linux.dev, Jann Horn <jannh@google.com>
Subject: [PATCH RFC v3 07/12] kasan: provide memory access information to KCOV
Date: Tue, 08 Sep 2026 18:54:47 +0200	[thread overview]
Message-ID: <20260908-kcov-extrecord-v3-7-dcbc11593e88@google.com> (raw)
In-Reply-To: <20260908-kcov-extrecord-v3-0-dcbc11593e88@google.com>

In CONFIG_KCOV_MEMORY builds, let KASAN provide information about memory
accesses to KCOV.
Since KCOV already receives information from instrument_*() directly,
filter out those accesses by introducing KASAN_TYPE_EXPLICIT.
Because the KCOV usecase requires seeing ~every memory access (including
accesses to globals and repeated accesses to the same memory location
within a basic block), gate this on CC_IS_CLANG and let it flip some hidden
LLVM flags that disable ASAN optimizations.

Signed-off-by: Jann Horn <jannh@google.com>
---
 include/linux/kasan.h  |  1 +
 lib/Kconfig.debug      |  2 ++
 lib/Kconfig.kasan      |  9 +++++++++
 mm/kasan/generic.c     | 15 +++++++++++++++
 mm/kasan/shadow.c      |  5 +++--
 scripts/Makefile.kasan | 17 +++++++++++++++++
 tools/objtool/check.c  |  1 +
 7 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/include/linux/kasan.h b/include/linux/kasan.h
index 03c7ac79345d..4b915e0c51bc 100644
--- a/include/linux/kasan.h
+++ b/include/linux/kasan.h
@@ -34,6 +34,7 @@ typedef unsigned int __bitwise kasan_vmalloc_flags_t;
 #define KASAN_VMALLOC_TLB_FLUSH  0x2 /* TLB flush */
 
 #define KASAN_TYPE_WRITE 0x1
+#define KASAN_TYPE_EXPLICIT 0x2
 
 #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
 
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 5de427ccc42d..f763f0504f62 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -2221,6 +2221,8 @@ config KCOV_MEMORY
 	bool "Enable memory access trace collection by KCOV"
 	depends on KCOV
 	depends on KCOV_EXT_RECORDS
+	depends on HAVE_KASAN_REPORT_EVERY_ACCESS
+	select KASAN_REPORT_EVERY_ACCESS
 	help
 	  Provide a KCOV mode which records memory access operations and allows
 	  userspace to inject execution delays to impose constraints on the
diff --git a/lib/Kconfig.kasan b/lib/Kconfig.kasan
index a4bb610a7a6f..9a43f6269c5c 100644
--- a/lib/Kconfig.kasan
+++ b/lib/Kconfig.kasan
@@ -228,4 +228,13 @@ config KASAN_EXTRA_INFO
 	  boot parameter, it will add 8 * stack_ring_size bytes of additional
 	  memory consumption.
 
+# Is KASAN_REPORT_EVERY_ACCESS allowed?
+config HAVE_KASAN_REPORT_EVERY_ACCESS
+	def_bool y
+	depends on KASAN_OUTLINE
+	depends on CC_IS_CLANG
+
+config KASAN_REPORT_EVERY_ACCESS
+	bool
+
 endif # KASAN
diff --git a/mm/kasan/generic.c b/mm/kasan/generic.c
index 9efd6fbbb7c3..6cf88f569e64 100644
--- a/mm/kasan/generic.c
+++ b/mm/kasan/generic.c
@@ -32,6 +32,8 @@
 #include <linux/types.h>
 #include <linux/vmalloc.h>
 #include <linux/bug.h>
+#include <linux/kcov.h>
+#include <uapi/linux/kcov.h>
 
 #include "kasan.h"
 #include "../slab.h"
@@ -182,6 +184,19 @@ static __always_inline bool check_region_inline(const void *addr,
 	if (unlikely(size == 0))
 		return true;
 
+	/*
+	 * Do not route information about an access to KCOV if we got called
+	 * through the instrument_*() path - KCOV can get those accesses
+	 * directly from instrument_*(), and get a bit more metadata about the
+	 * access that way.
+	 */
+	if (likely((flags & KASAN_TYPE_EXPLICIT) == 0)) {
+		unsigned int kcov_flags =
+			(flags & KASAN_TYPE_WRITE) ? MEMORY_ACCESS_RECORD_WRITE : 0;
+
+		__kcov_handle_memaccess(addr, size, kcov_flags, ret_ip);
+	}
+
 	if (unlikely(addr + size < addr))
 		return !kasan_report(addr, size, flags, ret_ip);
 
diff --git a/mm/kasan/shadow.c b/mm/kasan/shadow.c
index a24f1225dd88..84f8567d4f2c 100644
--- a/mm/kasan/shadow.c
+++ b/mm/kasan/shadow.c
@@ -28,13 +28,14 @@
 
 bool __kasan_check_read(const volatile void *p, unsigned int size)
 {
-	return kasan_check_range((void *)p, size, 0, _RET_IP_);
+	return kasan_check_range((void *)p, size, KASAN_TYPE_EXPLICIT, _RET_IP_);
 }
 EXPORT_SYMBOL(__kasan_check_read);
 
 bool __kasan_check_write(const volatile void *p, unsigned int size)
 {
-	return kasan_check_range((void *)p, size, KASAN_TYPE_WRITE, _RET_IP_);
+	return kasan_check_range((void *)p, size,
+		KASAN_TYPE_WRITE|KASAN_TYPE_EXPLICIT, _RET_IP_);
 }
 EXPORT_SYMBOL(__kasan_check_write);
 
diff --git a/scripts/Makefile.kasan b/scripts/Makefile.kasan
index 91504e81247a..82e88c5fb9bc 100644
--- a/scripts/Makefile.kasan
+++ b/scripts/Makefile.kasan
@@ -60,6 +60,23 @@ kasan_params += asan-instrumentation-with-call-threshold=$(call_threshold) \
 		asan-instrument-allocas=1 \
 		asan-globals=1
 
+# When we piggyback tracing of memory accesses for race condition testing on top
+# of KASAN, we want the compiler to report memory accesses even when KASAN can
+# prove that no UAF/OOB can occur; in particular, these optimizations must be
+# inhibited:
+#
+#  - suppression of ASAN hook calls for global variables
+#  - merging of multiple accesses in a basic block into a single ASAN hook call
+#
+# For now, known stack variable accesses are still ignored as a performance
+# tradeoff, though that will probably make a small number of races (where
+# another task concurrently accesses stuff on our stack) invisible to the
+# instrumentation. (Stack access instrumentation is gated on
+# asan-use-stack-safety and asan-skip-promotable-allocas.)
+ifdef CONFIG_KASAN_REPORT_EVERY_ACCESS
+kasan_params += asan-opt-globals=0 asan-opt-same-temp=0
+endif # CONFIG_KASAN_REPORT_EVERY_ACCESS
+
 # Instrument memcpy/memset/memmove calls by using instrumented __asan_mem*()
 # instead. With compilers that don't support this option, compiler-inserted
 # memintrinsics won't be checked by KASAN on GENERIC_ENTRY architectures.
diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index d70cb640e2ec..08ebfe1f3fac 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1219,6 +1219,7 @@ static const char *uaccess_safe_builtin[] = {
 	/* KCOV */
 	"write_comp_data",
 	"check_kcov_mode",
+	"__kcov_handle_memaccess",
 	"__sanitizer_cov_trace_pc",
 	"__sanitizer_cov_trace_pc_entry",
 	"__sanitizer_cov_trace_pc_exit",

-- 
2.55.0.979.g7e5102b832-goog


  parent reply	other threads:[~2026-09-08 16:55 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-08 16:54 [PATCH RFC v3 00/12] KCOV: entry/exit records, memory access records, and delay injection Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 01/12] kcov: wire up compiler instrumentation for CONFIG_KCOV_EXT_RECORDS Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 02/12] kcov: refactor mode check out of check_kcov_mode() Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 03/12] kcov: introduce extended PC coverage collection mode Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 04/12] kcov: summarize entry/exit while disabled Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 05/12] kasan: refactor write/is_write arguments to flags Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 06/12] kcov: introduce memory access tracing Jann Horn
2026-09-08 16:54 ` Jann Horn [this message]
2026-09-08 16:54 ` [PATCH RFC v3 08/12] kcov: log freeing of SLUB objects and pages Jann Horn
2026-09-08 17:04   ` Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 09/12] kcov: record return address on function entry Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 10/12] kcov: log old value Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 11/12] kcov: introduce delay injection Jann Horn
2026-09-08 16:54 ` [PATCH RFC v3 12/12] Documentation/kcov: add documentation for EXT_RECORDS and KCOV_MEMORY Jann Horn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260908-kcov-extrecord-v3-7-dcbc11593e88@google.com \
    --to=jannh@google.com \
    --cc=andreyknvl@gmail.com \
    --cc=dvyukov@google.com \
    --cc=glider@google.com \
    --cc=justinstitt@google.com \
    --cc=kasan-dev@googlegroups.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=llvm@lists.linux.dev \
    --cc=morbo@google.com \
    --cc=nathan@kernel.org \
    --cc=nick.desaulniers+lkml@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®