linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 00/33] kmsan: Enable on s390
@ 2023-11-21 22:00 Ilya Leoshkevich
  2023-11-21 22:00 ` [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func() Ilya Leoshkevich
                   ` (30 more replies)
  0 siblings, 31 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:00 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

v1: https://lore.kernel.org/lkml/20231115203401.2495875-1-iii@linux.ibm.com/
v1 -> v2: Add comments, sort #includes, introduce
          memset_no_sanitize_memory() and use it to avoid unpoisoning
          of redzones, change vmalloc alignment to _REGION3_SIZE, add
          R-bs (Alexander P.).

          Fix building
          [PATCH 28/33] s390/string: Add KMSAN support
          with FORTIFY_SOURCE.
          Reported-by: kernel test robot <lkp@intel.com>
          Closes: https://lore.kernel.org/oe-kbuild-all/202311170550.bSBo44ix-lkp@intel.com/

Hi,

This series provides the minimal support for Kernel Memory Sanitizer on
s390. Kernel Memory Sanitizer is clang-only instrumentation for finding
accesses to uninitialized memory. The clang support for s390 has already
been merged [1].

With this series, I can successfully boot s390 defconfig and
debug_defconfig with kmsan.panic=1. The tool found one real
s390-specific bug (fixed in master).

Best regards,
Ilya

[1] https://reviews.llvm.org/D148596

Ilya Leoshkevich (33):
  ftrace: Unpoison ftrace_regs in ftrace_ops_list_func()
  kmsan: Make the tests compatible with kmsan.panic=1
  kmsan: Disable KMSAN when DEFERRED_STRUCT_PAGE_INIT is enabled
  kmsan: Increase the maximum store size to 4096
  kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces
  kmsan: Fix kmsan_copy_to_user() on arches with overlapping address
    spaces
  kmsan: Remove a useless assignment from
    kmsan_vmap_pages_range_noflush()
  kmsan: Remove an x86-specific #include from kmsan.h
  kmsan: Introduce kmsan_memmove_metadata()
  kmsan: Expose kmsan_get_metadata()
  kmsan: Export panic_on_kmsan
  kmsan: Allow disabling KMSAN checks for the current task
  kmsan: Introduce memset_no_sanitize_memory()
  kmsan: Support SLAB_POISON
  kmsan: Use ALIGN_DOWN() in kmsan_get_metadata()
  mm: slub: Let KMSAN access metadata
  mm: kfence: Disable KMSAN when checking the canary
  lib/string: Add KMSAN support to strlcpy() and strlcat()
  lib/zlib: Unpoison DFLTCC output buffers
  kmsan: Accept ranges starting with 0 on s390
  s390: Turn off KMSAN for boot, vdso and purgatory
  s390: Use a larger stack for KMSAN
  s390/boot: Add the KMSAN runtime stub
  s390/checksum: Add a KMSAN check
  s390/cpacf: Unpoison the results of cpacf_trng()
  s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler()
  s390/mm: Define KMSAN metadata for vmalloc and modules
  s390/string: Add KMSAN support
  s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs
  s390/uaccess: Add KMSAN support to put_user() and get_user()
  s390/unwind: Disable KMSAN checks
  s390: Implement the architecture-specific kmsan functions
  kmsan: Enable on s390

 Documentation/dev-tools/kmsan.rst   |   4 +-
 arch/s390/Kconfig                   |   1 +
 arch/s390/Makefile                  |   2 +-
 arch/s390/boot/Makefile             |   3 +
 arch/s390/boot/kmsan.c              |   6 ++
 arch/s390/boot/startup.c            |   8 ++
 arch/s390/boot/string.c             |  16 ++++
 arch/s390/include/asm/checksum.h    |   2 +
 arch/s390/include/asm/cpacf.h       |   2 +
 arch/s390/include/asm/kmsan.h       |  36 +++++++++
 arch/s390/include/asm/pgtable.h     |  10 +++
 arch/s390/include/asm/string.h      |  20 +++--
 arch/s390/include/asm/thread_info.h |   2 +-
 arch/s390/include/asm/uaccess.h     | 110 ++++++++++++++++++++--------
 arch/s390/kernel/ftrace.c           |   1 +
 arch/s390/kernel/traps.c            |   6 ++
 arch/s390/kernel/unwind_bc.c        |   4 +
 arch/s390/kernel/vdso32/Makefile    |   3 +-
 arch/s390/kernel/vdso64/Makefile    |   3 +-
 arch/s390/purgatory/Makefile        |   2 +
 include/linux/kmsan-checks.h        |  26 +++++++
 include/linux/kmsan.h               |  23 ++++++
 include/linux/kmsan_types.h         |   2 +-
 kernel/trace/ftrace.c               |   1 +
 lib/string.c                        |   6 ++
 lib/zlib_dfltcc/dfltcc.h            |   1 +
 lib/zlib_dfltcc/dfltcc_util.h       |  23 ++++++
 mm/Kconfig                          |   1 +
 mm/kfence/core.c                    |   5 +-
 mm/kmsan/core.c                     |   2 +-
 mm/kmsan/hooks.c                    |  30 +++++++-
 mm/kmsan/init.c                     |   5 +-
 mm/kmsan/instrumentation.c          |  11 +--
 mm/kmsan/kmsan.h                    |   9 +--
 mm/kmsan/kmsan_test.c               |   5 ++
 mm/kmsan/report.c                   |   7 +-
 mm/kmsan/shadow.c                   |   9 +--
 mm/slub.c                           |  12 ++-
 38 files changed, 345 insertions(+), 74 deletions(-)
 create mode 100644 arch/s390/boot/kmsan.c
 create mode 100644 arch/s390/include/asm/kmsan.h

-- 
2.41.0



^ permalink raw reply	[flat|nested] 63+ messages in thread

* [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
@ 2023-11-21 22:00 ` Ilya Leoshkevich
  2023-11-22 23:32   ` Steven Rostedt
  2023-12-08 14:16   ` Alexander Potapenko
  2023-11-21 22:00 ` [PATCH v2 02/33] kmsan: Make the tests compatible with kmsan.panic=1 Ilya Leoshkevich
                   ` (29 subsequent siblings)
  30 siblings, 2 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:00 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Architectures use assembly code to initialize ftrace_regs and call
ftrace_ops_list_func(). Therefore, from the KMSAN's point of view,
ftrace_regs is poisoned on ftrace_ops_list_func entry(). This causes
KMSAN warnings when running the ftrace testsuite.

Fix by trusting the architecture-specific assembly code and always
unpoisoning ftrace_regs in ftrace_ops_list_func.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 kernel/trace/ftrace.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 8de8bec5f366..dfb8b26966aa 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -7399,6 +7399,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
 void arch_ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
 			       struct ftrace_ops *op, struct ftrace_regs *fregs)
 {
+	kmsan_unpoison_memory(fregs, sizeof(*fregs));
 	__ftrace_ops_list_func(ip, parent_ip, NULL, fregs);
 }
 #else
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 02/33] kmsan: Make the tests compatible with kmsan.panic=1
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
  2023-11-21 22:00 ` [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func() Ilya Leoshkevich
@ 2023-11-21 22:00 ` Ilya Leoshkevich
  2023-11-21 22:00 ` [PATCH v2 03/33] kmsan: Disable KMSAN when DEFERRED_STRUCT_PAGE_INIT is enabled Ilya Leoshkevich
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:00 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

It's useful to have both tests and kmsan.panic=1 during development,
but right now the warnings, that the tests cause, lead to kernel
panics.

Temporarily set kmsan.panic=0 for the duration of the KMSAN testing.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/kmsan_test.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/mm/kmsan/kmsan_test.c b/mm/kmsan/kmsan_test.c
index 07d3a3a5a9c5..9bfd11674fe3 100644
--- a/mm/kmsan/kmsan_test.c
+++ b/mm/kmsan/kmsan_test.c
@@ -659,9 +659,13 @@ static void test_exit(struct kunit *test)
 {
 }
 
+static int orig_panic_on_kmsan;
+
 static int kmsan_suite_init(struct kunit_suite *suite)
 {
 	register_trace_console(probe_console, NULL);
+	orig_panic_on_kmsan = panic_on_kmsan;
+	panic_on_kmsan = 0;
 	return 0;
 }
 
@@ -669,6 +673,7 @@ static void kmsan_suite_exit(struct kunit_suite *suite)
 {
 	unregister_trace_console(probe_console, NULL);
 	tracepoint_synchronize_unregister();
+	panic_on_kmsan = orig_panic_on_kmsan;
 }
 
 static struct kunit_suite kmsan_test_suite = {
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 03/33] kmsan: Disable KMSAN when DEFERRED_STRUCT_PAGE_INIT is enabled
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
  2023-11-21 22:00 ` [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func() Ilya Leoshkevich
  2023-11-21 22:00 ` [PATCH v2 02/33] kmsan: Make the tests compatible with kmsan.panic=1 Ilya Leoshkevich
@ 2023-11-21 22:00 ` Ilya Leoshkevich
  2023-11-21 22:00 ` [PATCH v2 04/33] kmsan: Increase the maximum store size to 4096 Ilya Leoshkevich
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:00 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

KMSAN relies on memblock returning all available pages to it
(see kmsan_memblock_free_pages()). It partitions these pages into 3
categories: pages available to the buddy allocator, shadow pages and
origin pages. This partitioning is static.

If new pages appear after kmsan_init_runtime(), it is considered
an error. DEFERRED_STRUCT_PAGE_INIT causes this, so mark it as
incompatible with KMSAN.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/Kconfig b/mm/Kconfig
index 89971a894b60..4f2f99339fc7 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -985,6 +985,7 @@ config DEFERRED_STRUCT_PAGE_INIT
 	depends on SPARSEMEM
 	depends on !NEED_PER_CPU_KM
 	depends on 64BIT
+	depends on !KMSAN
 	select PADATA
 	help
 	  Ordinarily all struct pages are initialised during early boot in a
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 04/33] kmsan: Increase the maximum store size to 4096
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (2 preceding siblings ...)
  2023-11-21 22:00 ` [PATCH v2 03/33] kmsan: Disable KMSAN when DEFERRED_STRUCT_PAGE_INIT is enabled Ilya Leoshkevich
@ 2023-11-21 22:00 ` Ilya Leoshkevich
  2023-12-08 16:31   ` Alexander Potapenko
  2023-11-21 22:00 ` [PATCH v2 05/33] kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces Ilya Leoshkevich
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:00 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

The inline assembly block in s390's chsc() stores that much.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/instrumentation.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c
index cc3907a9c33a..470b0b4afcc4 100644
--- a/mm/kmsan/instrumentation.c
+++ b/mm/kmsan/instrumentation.c
@@ -110,11 +110,10 @@ void __msan_instrument_asm_store(void *addr, uintptr_t size)
 
 	ua_flags = user_access_save();
 	/*
-	 * Most of the accesses are below 32 bytes. The two exceptions so far
-	 * are clwb() (64 bytes) and FPU state (512 bytes).
-	 * It's unlikely that the assembly will touch more than 512 bytes.
+	 * Most of the accesses are below 32 bytes. The exceptions so far are
+	 * clwb() (64 bytes), FPU state (512 bytes) and chsc() (4096 bytes).
 	 */
-	if (size > 512) {
+	if (size > 4096) {
 		WARN_ONCE(1, "assembly store size too big: %ld\n", size);
 		size = 8;
 	}
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 05/33] kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (3 preceding siblings ...)
  2023-11-21 22:00 ` [PATCH v2 04/33] kmsan: Increase the maximum store size to 4096 Ilya Leoshkevich
@ 2023-11-21 22:00 ` Ilya Leoshkevich
  2023-12-11  9:52   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 08/33] kmsan: Remove an x86-specific #include from kmsan.h Ilya Leoshkevich
                   ` (25 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:00 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Comparing pointers with TASK_SIZE does not make sense when kernel and
userspace overlap. Skip the comparison when this is the case.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/instrumentation.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c
index 470b0b4afcc4..8a1bbbc723ab 100644
--- a/mm/kmsan/instrumentation.c
+++ b/mm/kmsan/instrumentation.c
@@ -20,7 +20,8 @@
 
 static inline bool is_bad_asm_addr(void *addr, uintptr_t size, bool is_store)
 {
-	if ((u64)addr < TASK_SIZE)
+	if (IS_ENABLED(CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE) &&
+	    (u64)addr < TASK_SIZE)
 		return true;
 	if (!kmsan_get_metadata(addr, KMSAN_META_SHADOW))
 		return true;
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 08/33] kmsan: Remove an x86-specific #include from kmsan.h
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (4 preceding siblings ...)
  2023-11-21 22:00 ` [PATCH v2 05/33] kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 09/33] kmsan: Introduce kmsan_memmove_metadata() Ilya Leoshkevich
                   ` (24 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Replace the x86-specific asm/pgtable_64_types.h #include with the
linux/pgtable.h one, which all architectures have.

While at it, sort the headers alphabetically for the sake of
consistency with other KMSAN code.

Fixes: f80be4571b19 ("kmsan: add KMSAN runtime core")
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/kmsan.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h
index a14744205435..adf443bcffe8 100644
--- a/mm/kmsan/kmsan.h
+++ b/mm/kmsan/kmsan.h
@@ -10,14 +10,14 @@
 #ifndef __MM_KMSAN_KMSAN_H
 #define __MM_KMSAN_KMSAN_H
 
-#include <asm/pgtable_64_types.h>
 #include <linux/irqflags.h>
+#include <linux/mm.h>
+#include <linux/nmi.h>
+#include <linux/pgtable.h>
+#include <linux/printk.h>
 #include <linux/sched.h>
 #include <linux/stackdepot.h>
 #include <linux/stacktrace.h>
-#include <linux/nmi.h>
-#include <linux/mm.h>
-#include <linux/printk.h>
 
 #define KMSAN_ALLOCA_MAGIC_ORIGIN 0xabcd0100
 #define KMSAN_CHAIN_MAGIC_ORIGIN 0xabcd0200
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 09/33] kmsan: Introduce kmsan_memmove_metadata()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (5 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 08/33] kmsan: Remove an x86-specific #include from kmsan.h Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 16:51   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 11/33] kmsan: Export panic_on_kmsan Ilya Leoshkevich
                   ` (23 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

It is useful to manually copy metadata in order to describe the effects
of memmove()-like logic in uninstrumented code or inline asm. Introduce
kmsan_memmove_metadata() for this purpose.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 include/linux/kmsan-checks.h | 14 ++++++++++++++
 mm/kmsan/hooks.c             | 11 +++++++++++
 2 files changed, 25 insertions(+)

diff --git a/include/linux/kmsan-checks.h b/include/linux/kmsan-checks.h
index c4cae333deec..5218973f0ad0 100644
--- a/include/linux/kmsan-checks.h
+++ b/include/linux/kmsan-checks.h
@@ -61,6 +61,17 @@ void kmsan_check_memory(const void *address, size_t size);
 void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
 			size_t left);
 
+/**
+ * kmsan_memmove_metadata() - Copy kernel memory range metadata.
+ * @dst: start of the destination kernel memory range.
+ * @src: start of the source kernel memory range.
+ * @n:   size of the memory ranges.
+ *
+ * KMSAN will treat the destination range as if its contents were memmove()d
+ * from the source range.
+ */
+void kmsan_memmove_metadata(void *dst, const void *src, size_t n);
+
 #else
 
 static inline void kmsan_poison_memory(const void *address, size_t size,
@@ -77,6 +88,9 @@ static inline void kmsan_copy_to_user(void __user *to, const void *from,
 				      size_t to_copy, size_t left)
 {
 }
+static inline void kmsan_memmove_metadata(void *dst, const void *src, size_t n)
+{
+}
 
 #endif
 
diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
index eafc45f937eb..4d477a0a356c 100644
--- a/mm/kmsan/hooks.c
+++ b/mm/kmsan/hooks.c
@@ -286,6 +286,17 @@ void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
 }
 EXPORT_SYMBOL(kmsan_copy_to_user);
 
+void kmsan_memmove_metadata(void *dst, const void *src, size_t n)
+{
+	if (!kmsan_enabled || kmsan_in_runtime())
+		return;
+
+	kmsan_enter_runtime();
+	kmsan_internal_memmove_metadata(dst, (void *)src, n);
+	kmsan_leave_runtime();
+}
+EXPORT_SYMBOL(kmsan_memmove_metadata);
+
 /* Helper function to check an URB. */
 void kmsan_handle_urb(const struct urb *urb, bool is_out)
 {
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 11/33] kmsan: Export panic_on_kmsan
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (6 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 09/33] kmsan: Introduce kmsan_memmove_metadata() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task Ilya Leoshkevich
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

When building the kmsan test as a module, modpost fails with the
following error message:

    ERROR: modpost: "panic_on_kmsan" [mm/kmsan/kmsan_test.ko] undefined!

Export panic_on_kmsan in order to improve the KMSAN usability for
modules.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/report.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/kmsan/report.c b/mm/kmsan/report.c
index 02736ec757f2..c79d3b0d2d0d 100644
--- a/mm/kmsan/report.c
+++ b/mm/kmsan/report.c
@@ -20,6 +20,7 @@ static DEFINE_RAW_SPINLOCK(kmsan_report_lock);
 /* Protected by kmsan_report_lock */
 static char report_local_descr[DESCR_SIZE];
 int panic_on_kmsan __read_mostly;
+EXPORT_SYMBOL_GPL(panic_on_kmsan);
 
 #ifdef MODULE_PARAM_PREFIX
 #undef MODULE_PARAM_PREFIX
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (7 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 11/33] kmsan: Export panic_on_kmsan Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-11 11:50   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory() Ilya Leoshkevich
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Like for KASAN, it's useful to temporarily disable KMSAN checks around,
e.g., redzone accesses. Introduce kmsan_disable_current() and
kmsan_enable_current(), which are similar to their KASAN counterparts.

Even though it's not strictly necessary, make them reentrant, in order
to match the KASAN behavior. Repurpose the allow_reporting field for
this.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 Documentation/dev-tools/kmsan.rst |  4 ++--
 include/linux/kmsan-checks.h      | 12 ++++++++++++
 include/linux/kmsan_types.h       |  2 +-
 mm/kmsan/core.c                   |  2 +-
 mm/kmsan/hooks.c                  | 14 +++++++++++++-
 mm/kmsan/report.c                 |  6 +++---
 6 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/Documentation/dev-tools/kmsan.rst b/Documentation/dev-tools/kmsan.rst
index 323eedad53cd..022a823f5f1b 100644
--- a/Documentation/dev-tools/kmsan.rst
+++ b/Documentation/dev-tools/kmsan.rst
@@ -338,11 +338,11 @@ Per-task KMSAN state
 ~~~~~~~~~~~~~~~~~~~~
 
 Every task_struct has an associated KMSAN task state that holds the KMSAN
-context (see above) and a per-task flag disallowing KMSAN reports::
+context (see above) and a per-task counter disallowing KMSAN reports::
 
   struct kmsan_context {
     ...
-    bool allow_reporting;
+    unsigned int depth;
     struct kmsan_context_state cstate;
     ...
   }
diff --git a/include/linux/kmsan-checks.h b/include/linux/kmsan-checks.h
index 5218973f0ad0..bab2603685f7 100644
--- a/include/linux/kmsan-checks.h
+++ b/include/linux/kmsan-checks.h
@@ -72,6 +72,10 @@ void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
  */
 void kmsan_memmove_metadata(void *dst, const void *src, size_t n);
 
+void kmsan_enable_current(void);
+
+void kmsan_disable_current(void);
+
 #else
 
 static inline void kmsan_poison_memory(const void *address, size_t size,
@@ -92,6 +96,14 @@ static inline void kmsan_memmove_metadata(void *dst, const void *src, size_t n)
 {
 }
 
+static inline void kmsan_enable_current(void)
+{
+}
+
+static inline void kmsan_disable_current(void)
+{
+}
+
 #endif
 
 #endif /* _LINUX_KMSAN_CHECKS_H */
diff --git a/include/linux/kmsan_types.h b/include/linux/kmsan_types.h
index 8bfa6c98176d..27bb146ece95 100644
--- a/include/linux/kmsan_types.h
+++ b/include/linux/kmsan_types.h
@@ -29,7 +29,7 @@ struct kmsan_context_state {
 struct kmsan_ctx {
 	struct kmsan_context_state cstate;
 	int kmsan_in_runtime;
-	bool allow_reporting;
+	unsigned int depth;
 };
 
 #endif /* _LINUX_KMSAN_TYPES_H */
diff --git a/mm/kmsan/core.c b/mm/kmsan/core.c
index c19f47af0424..b8767378cf8a 100644
--- a/mm/kmsan/core.c
+++ b/mm/kmsan/core.c
@@ -43,7 +43,7 @@ void kmsan_internal_task_create(struct task_struct *task)
 	struct thread_info *info = current_thread_info();
 
 	__memset(ctx, 0, sizeof(*ctx));
-	ctx->allow_reporting = true;
+	ctx->depth = 0;
 	kmsan_internal_unpoison_memory(info, sizeof(*info), false);
 }
 
diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
index 4d477a0a356c..7b5814412e9f 100644
--- a/mm/kmsan/hooks.c
+++ b/mm/kmsan/hooks.c
@@ -44,7 +44,7 @@ void kmsan_task_exit(struct task_struct *task)
 	if (!kmsan_enabled || kmsan_in_runtime())
 		return;
 
-	ctx->allow_reporting = false;
+	ctx->depth++;
 }
 
 void kmsan_slab_alloc(struct kmem_cache *s, void *object, gfp_t flags)
@@ -434,3 +434,15 @@ void kmsan_check_memory(const void *addr, size_t size)
 					   REASON_ANY);
 }
 EXPORT_SYMBOL(kmsan_check_memory);
+
+void kmsan_enable_current(void)
+{
+	current->kmsan_ctx.depth--;
+}
+EXPORT_SYMBOL(kmsan_enable_current);
+
+void kmsan_disable_current(void)
+{
+	current->kmsan_ctx.depth++;
+}
+EXPORT_SYMBOL(kmsan_disable_current);
diff --git a/mm/kmsan/report.c b/mm/kmsan/report.c
index c79d3b0d2d0d..edcf53ca428e 100644
--- a/mm/kmsan/report.c
+++ b/mm/kmsan/report.c
@@ -158,12 +158,12 @@ void kmsan_report(depot_stack_handle_t origin, void *address, int size,
 
 	if (!kmsan_enabled)
 		return;
-	if (!current->kmsan_ctx.allow_reporting)
+	if (current->kmsan_ctx.depth)
 		return;
 	if (!origin)
 		return;
 
-	current->kmsan_ctx.allow_reporting = false;
+	current->kmsan_ctx.depth++;
 	ua_flags = user_access_save();
 	raw_spin_lock(&kmsan_report_lock);
 	pr_err("=====================================================\n");
@@ -216,5 +216,5 @@ void kmsan_report(depot_stack_handle_t origin, void *address, int size,
 	if (panic_on_kmsan)
 		panic("kmsan.panic set ...\n");
 	user_access_restore(ua_flags);
-	current->kmsan_ctx.allow_reporting = true;
+	current->kmsan_ctx.depth--;
 }
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (8 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 13:48   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 14/33] kmsan: Support SLAB_POISON Ilya Leoshkevich
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Add a wrapper for memset() that prevents unpoisoning. This is useful
for filling memory allocator redzones.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 include/linux/kmsan.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/linux/kmsan.h b/include/linux/kmsan.h
index ff8fd95733fa..439df72c8dc6 100644
--- a/include/linux/kmsan.h
+++ b/include/linux/kmsan.h
@@ -345,4 +345,13 @@ static inline void *kmsan_get_metadata(void *addr, bool is_origin)
 
 #endif
 
+/**
+ * memset_no_sanitize_memory() - memset() without the KMSAN instrumentation.
+ */
+__no_sanitize_memory
+static inline void *memset_no_sanitize_memory(void *s, int c, size_t n)
+{
+	return memset(s, c, n);
+}
+
 #endif /* _LINUX_KMSAN_H */
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 14/33] kmsan: Support SLAB_POISON
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (9 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 13:51   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 15/33] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata() Ilya Leoshkevich
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Avoid false KMSAN negatives with SLUB_DEBUG by allowing
kmsan_slab_free() to poison the freed memory, and by preventing
init_object() from unpoisoning new allocations. The usage of
memset_no_sanitize_memory() does not degrade the generated code
quality.

There are two alternatives to this approach. First, init_object()
can be marked with __no_sanitize_memory. This annotation should be used
with great care, because it drops all instrumentation from the
function, and any shadow writes will be lost. Even though this is not a
concern with the current init_object() implementation, this may change
in the future.

Second, kmsan_poison_memory() calls may be added after memset() calls.
The downside is that init_object() is called from
free_debug_processing(), in which case poisoning will erase the
distinction between simply uninitialized memory and UAF.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/hooks.c |  2 +-
 mm/slub.c        | 10 ++++++----
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
index 7b5814412e9f..7a30274b893c 100644
--- a/mm/kmsan/hooks.c
+++ b/mm/kmsan/hooks.c
@@ -76,7 +76,7 @@ void kmsan_slab_free(struct kmem_cache *s, void *object)
 		return;
 
 	/* RCU slabs could be legally used after free within the RCU period */
-	if (unlikely(s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)))
+	if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU))
 		return;
 	/*
 	 * If there's a constructor, freed memory must remain in the same state
diff --git a/mm/slub.c b/mm/slub.c
index 63d281dfacdb..169e5f645ea8 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1030,7 +1030,8 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
 	unsigned int poison_size = s->object_size;
 
 	if (s->flags & SLAB_RED_ZONE) {
-		memset(p - s->red_left_pad, val, s->red_left_pad);
+		memset_no_sanitize_memory(p - s->red_left_pad, val,
+					  s->red_left_pad);
 
 		if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {
 			/*
@@ -1043,12 +1044,13 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
 	}
 
 	if (s->flags & __OBJECT_POISON) {
-		memset(p, POISON_FREE, poison_size - 1);
-		p[poison_size - 1] = POISON_END;
+		memset_no_sanitize_memory(p, POISON_FREE, poison_size - 1);
+		memset_no_sanitize_memory(p + poison_size - 1, POISON_END, 1);
 	}
 
 	if (s->flags & SLAB_RED_ZONE)
-		memset(p + poison_size, val, s->inuse - poison_size);
+		memset_no_sanitize_memory(p + poison_size, val,
+					  s->inuse - poison_size);
 }
 
 static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 15/33] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (10 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 14/33] kmsan: Support SLAB_POISON Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 16/33] mm: slub: Let KMSAN access metadata Ilya Leoshkevich
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Improve the readability by replacing the custom aligning logic with
ALIGN_DOWN(). Unlike other places where a similar sequence is used,
there is no size parameter that needs to be adjusted, so the standard
macro fits.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/shadow.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c
index 2d57408c78ae..9c58f081d84f 100644
--- a/mm/kmsan/shadow.c
+++ b/mm/kmsan/shadow.c
@@ -123,14 +123,12 @@ struct shadow_origin_ptr kmsan_get_shadow_origin_ptr(void *address, u64 size,
  */
 void *kmsan_get_metadata(void *address, bool is_origin)
 {
-	u64 addr = (u64)address, pad, off;
+	u64 addr = (u64)address, off;
 	struct page *page;
 	void *ret;
 
-	if (is_origin && !IS_ALIGNED(addr, KMSAN_ORIGIN_SIZE)) {
-		pad = addr % KMSAN_ORIGIN_SIZE;
-		addr -= pad;
-	}
+	if (is_origin)
+		addr = ALIGN_DOWN(addr, KMSAN_ORIGIN_SIZE);
 	address = (void *)addr;
 	if (kmsan_internal_is_vmalloc_addr(address) ||
 	    kmsan_internal_is_module_addr(address))
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 16/33] mm: slub: Let KMSAN access metadata
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (11 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 15/33] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-30 15:26   ` Vlastimil Babka
  2023-11-21 22:01 ` [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary Ilya Leoshkevich
                   ` (17 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Building the kernel with CONFIG_SLUB_DEBUG and CONFIG_KMSAN causes
KMSAN to complain about touching redzones in kfree().

Fix by extending the existing KASAN-related metadata_access_enable()
and metadata_access_disable() functions to KMSAN.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/slub.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mm/slub.c b/mm/slub.c
index 169e5f645ea8..6e61c27951a4 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -700,10 +700,12 @@ static int disable_higher_order_debug;
 static inline void metadata_access_enable(void)
 {
 	kasan_disable_current();
+	kmsan_disable_current();
 }
 
 static inline void metadata_access_disable(void)
 {
+	kmsan_enable_current();
 	kasan_enable_current();
 }
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (12 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 16/33] mm: slub: Let KMSAN access metadata Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 12:53   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat() Ilya Leoshkevich
                   ` (16 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

KMSAN warns about check_canary() accessing the canary.

The reason is that, even though set_canary() is properly instrumented
and sets shadow, slub explicitly poisons the canary's address range
afterwards.

Unpoisoning the canary is not the right thing to do: only
check_canary() is supposed to ever touch it. Instead, disable KMSAN
checks around canary read accesses.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kfence/core.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/kfence/core.c b/mm/kfence/core.c
index 3872528d0963..a2ea8e5a1ad9 100644
--- a/mm/kfence/core.c
+++ b/mm/kfence/core.c
@@ -306,7 +306,7 @@ metadata_update_state(struct kfence_metadata *meta, enum kfence_object_state nex
 }
 
 /* Check canary byte at @addr. */
-static inline bool check_canary_byte(u8 *addr)
+__no_kmsan_checks static inline bool check_canary_byte(u8 *addr)
 {
 	struct kfence_metadata *meta;
 	unsigned long flags;
@@ -341,7 +341,8 @@ static inline void set_canary(const struct kfence_metadata *meta)
 		*((u64 *)addr) = KFENCE_CANARY_PATTERN_U64;
 }
 
-static inline void check_canary(const struct kfence_metadata *meta)
+__no_kmsan_checks static inline void
+check_canary(const struct kfence_metadata *meta)
 {
 	const unsigned long pageaddr = ALIGN_DOWN(meta->addr, PAGE_SIZE);
 	unsigned long addr = pageaddr;
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (13 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 16:50   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers Ilya Leoshkevich
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Currently KMSAN does not fully propagate metadata in strlcpy() and
strlcat(), because they are built with -ffreestanding and call
memcpy(). In this combination memcpy() calls are not instrumented.

Fix by copying the metadata manually. Add the __STDC_HOSTED__ #ifdef in
case the code is compiled with different flags in the future.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/string.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/lib/string.c b/lib/string.c
index be26623953d2..e83c6dd77ec6 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -111,6 +111,9 @@ size_t strlcpy(char *dest, const char *src, size_t size)
 	if (size) {
 		size_t len = (ret >= size) ? size - 1 : ret;
 		__builtin_memcpy(dest, src, len);
+#if __STDC_HOSTED__ == 0
+		kmsan_memmove_metadata(dest, src, len);
+#endif
 		dest[len] = '\0';
 	}
 	return ret;
@@ -261,6 +264,9 @@ size_t strlcat(char *dest, const char *src, size_t count)
 	if (len >= count)
 		len = count-1;
 	__builtin_memcpy(dest, src, len);
+#if __STDC_HOSTED__ == 0
+	kmsan_memmove_metadata(dest, src, len);
+#endif
 	dest[len] = 0;
 	return res;
 }
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (14 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 13:32   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 20/33] kmsan: Accept ranges starting with 0 on s390 Ilya Leoshkevich
                   ` (14 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

The constraints of the DFLTCC inline assembly are not precise: they
do not communicate the size of the output buffers to the compiler, so
it cannot automatically instrument it.

Add the manual kmsan_unpoison_memory() calls for the output buffers.
The logic is the same as in [1].

[1] https://github.com/zlib-ng/zlib-ng/commit/1f5ddcc009ac3511e99fc88736a9e1a6381168c5

Reported-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 lib/zlib_dfltcc/dfltcc.h      |  1 +
 lib/zlib_dfltcc/dfltcc_util.h | 23 +++++++++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/lib/zlib_dfltcc/dfltcc.h b/lib/zlib_dfltcc/dfltcc.h
index b96232bdd44d..0f2a16d7a48a 100644
--- a/lib/zlib_dfltcc/dfltcc.h
+++ b/lib/zlib_dfltcc/dfltcc.h
@@ -80,6 +80,7 @@ struct dfltcc_param_v0 {
     uint8_t csb[1152];
 };
 
+static_assert(offsetof(struct dfltcc_param_v0, csb) == 384);
 static_assert(sizeof(struct dfltcc_param_v0) == 1536);
 
 #define CVT_CRC32 0
diff --git a/lib/zlib_dfltcc/dfltcc_util.h b/lib/zlib_dfltcc/dfltcc_util.h
index 4a46b5009f0d..ce2e039a55b5 100644
--- a/lib/zlib_dfltcc/dfltcc_util.h
+++ b/lib/zlib_dfltcc/dfltcc_util.h
@@ -2,6 +2,7 @@
 #ifndef DFLTCC_UTIL_H
 #define DFLTCC_UTIL_H
 
+#include "dfltcc.h"
 #include <linux/zutil.h>
 
 /*
@@ -20,6 +21,7 @@ typedef enum {
 #define DFLTCC_CMPR 2
 #define DFLTCC_XPND 4
 #define HBT_CIRCULAR (1 << 7)
+#define DFLTCC_FN_MASK ((1 << 7) - 1)
 #define HB_BITS 15
 #define HB_SIZE (1 << HB_BITS)
 
@@ -34,6 +36,7 @@ static inline dfltcc_cc dfltcc(
 )
 {
     Byte *t2 = op1 ? *op1 : NULL;
+    unsigned char *orig_t2 = t2;
     size_t t3 = len1 ? *len1 : 0;
     const Byte *t4 = op2 ? *op2 : NULL;
     size_t t5 = len2 ? *len2 : 0;
@@ -59,6 +62,26 @@ static inline dfltcc_cc dfltcc(
                      : "cc", "memory");
     t2 = r2; t3 = r3; t4 = r4; t5 = r5;
 
+    switch (fn & DFLTCC_FN_MASK) {
+    case DFLTCC_QAF:
+        kmsan_unpoison_memory(param, sizeof(struct dfltcc_qaf_param));
+        break;
+    case DFLTCC_GDHT:
+        kmsan_unpoison_memory(param, offsetof(struct dfltcc_param_v0, csb));
+        break;
+    case DFLTCC_CMPR:
+        kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
+        kmsan_unpoison_memory(
+                orig_t2,
+                t2 - orig_t2 +
+                    (((struct dfltcc_param_v0 *)param)->sbb == 0 ? 0 : 1));
+        break;
+    case DFLTCC_XPND:
+        kmsan_unpoison_memory(param, sizeof(struct dfltcc_param_v0));
+        kmsan_unpoison_memory(orig_t2, t2 - orig_t2);
+        break;
+    }
+
     if (op1)
         *op1 = t2;
     if (len1)
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 20/33] kmsan: Accept ranges starting with 0 on s390
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (15 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 21/33] s390: Turn off KMSAN for boot, vdso and purgatory Ilya Leoshkevich
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

On s390 the virtual address 0 is valid (current CPU's lowcore is mapped
there), therefore KMSAN should not complain about it.

Disable the respective check on s390. There doesn't seem to be a
Kconfig option to describe this situation, so explicitly check for
s390.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 mm/kmsan/init.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/mm/kmsan/init.c b/mm/kmsan/init.c
index ffedf4dbc49d..7a3df4d359f8 100644
--- a/mm/kmsan/init.c
+++ b/mm/kmsan/init.c
@@ -33,7 +33,10 @@ static void __init kmsan_record_future_shadow_range(void *start, void *end)
 	bool merged = false;
 
 	KMSAN_WARN_ON(future_index == NUM_FUTURE_RANGES);
-	KMSAN_WARN_ON((nstart >= nend) || !nstart || !nend);
+	KMSAN_WARN_ON((nstart >= nend) ||
+		      /* Virtual address 0 is valid on s390. */
+		      (!IS_ENABLED(CONFIG_S390) && !nstart) ||
+		      !nend);
 	nstart = ALIGN_DOWN(nstart, PAGE_SIZE);
 	nend = ALIGN(nend, PAGE_SIZE);
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 21/33] s390: Turn off KMSAN for boot, vdso and purgatory
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (16 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 20/33] kmsan: Accept ranges starting with 0 on s390 Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 22/33] s390: Use a larger stack for KMSAN Ilya Leoshkevich
                   ` (12 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

All other sanitizers are disabled for these components as well.
While at it, add a comment to boot and purgatory.

Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/boot/Makefile          | 2 ++
 arch/s390/kernel/vdso32/Makefile | 3 ++-
 arch/s390/kernel/vdso64/Makefile | 3 ++-
 arch/s390/purgatory/Makefile     | 2 ++
 4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index c7c81e5f9218..fb10fcd21221 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -3,11 +3,13 @@
 # Makefile for the linux s390-specific parts of the memory manager.
 #
 
+# Tooling runtimes are unavailable and cannot be linked for early boot code
 KCOV_INSTRUMENT := n
 GCOV_PROFILE := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n
 
 KBUILD_AFLAGS := $(KBUILD_AFLAGS_DECOMPRESSOR)
 KBUILD_CFLAGS := $(KBUILD_CFLAGS_DECOMPRESSOR)
diff --git a/arch/s390/kernel/vdso32/Makefile b/arch/s390/kernel/vdso32/Makefile
index caec7db6f966..7cbec6b0b11f 100644
--- a/arch/s390/kernel/vdso32/Makefile
+++ b/arch/s390/kernel/vdso32/Makefile
@@ -32,11 +32,12 @@ obj-y += vdso32_wrapper.o
 targets += vdso32.lds
 CPPFLAGS_vdso32.lds += -P -C -U$(ARCH)
 
-# Disable gcov profiling, ubsan and kasan for VDSO code
+# Disable gcov profiling, ubsan, kasan and kmsan for VDSO code
 GCOV_PROFILE := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n
 
 # Force dependency (incbin is bad)
 $(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
diff --git a/arch/s390/kernel/vdso64/Makefile b/arch/s390/kernel/vdso64/Makefile
index e3c9085f8fa7..6f3252712f64 100644
--- a/arch/s390/kernel/vdso64/Makefile
+++ b/arch/s390/kernel/vdso64/Makefile
@@ -36,11 +36,12 @@ obj-y += vdso64_wrapper.o
 targets += vdso64.lds
 CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
 
-# Disable gcov profiling, ubsan and kasan for VDSO code
+# Disable gcov profiling, ubsan, kasan and kmsan for VDSO code
 GCOV_PROFILE := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n
 
 # Force dependency (incbin is bad)
 $(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
diff --git a/arch/s390/purgatory/Makefile b/arch/s390/purgatory/Makefile
index 4e930f566878..4e421914e50f 100644
--- a/arch/s390/purgatory/Makefile
+++ b/arch/s390/purgatory/Makefile
@@ -15,11 +15,13 @@ CFLAGS_sha256.o := -D__DISABLE_EXPORTS -D__NO_FORTIFY
 $(obj)/mem.o: $(srctree)/arch/s390/lib/mem.S FORCE
 	$(call if_changed_rule,as_o_S)
 
+# Tooling runtimes are unavailable and cannot be linked for purgatory code
 KCOV_INSTRUMENT := n
 GCOV_PROFILE := n
 UBSAN_SANITIZE := n
 KASAN_SANITIZE := n
 KCSAN_SANITIZE := n
+KMSAN_SANITIZE := n
 
 KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes
 KBUILD_CFLAGS += -Wno-pointer-sign -Wno-sign-compare
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 22/33] s390: Use a larger stack for KMSAN
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (17 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 21/33] s390: Turn off KMSAN for boot, vdso and purgatory Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 23/33] s390/boot: Add the KMSAN runtime stub Ilya Leoshkevich
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Adjust the stack size for the KMSAN-enabled kernel like it was done
for the KASAN-enabled one in commit 7fef92ccadd7 ("s390/kasan: double
the stack size"). Both tools have similar requirements.

Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/Makefile                  | 2 +-
 arch/s390/include/asm/thread_info.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 73873e451686..a7f5386d25ad 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -34,7 +34,7 @@ KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_DEBUG_INFO_DWARF4), $(call cc-option
 KBUILD_CFLAGS_DECOMPRESSOR += $(if $(CONFIG_CC_NO_ARRAY_BOUNDS),-Wno-array-bounds)
 
 UTS_MACHINE	:= s390x
-STACK_SIZE	:= $(if $(CONFIG_KASAN),65536,16384)
+STACK_SIZE	:= $(if $(CONFIG_KASAN),65536,$(if $(CONFIG_KMSAN),65536,16384))
 CHECKFLAGS	+= -D__s390__ -D__s390x__
 
 export LD_BFD
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h
index a674c7d25da5..d02a709717b8 100644
--- a/arch/s390/include/asm/thread_info.h
+++ b/arch/s390/include/asm/thread_info.h
@@ -16,7 +16,7 @@
 /*
  * General size of kernel stacks
  */
-#ifdef CONFIG_KASAN
+#if defined(CONFIG_KASAN) || defined(CONFIG_KMSAN)
 #define THREAD_SIZE_ORDER 4
 #else
 #define THREAD_SIZE_ORDER 2
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 23/33] s390/boot: Add the KMSAN runtime stub
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (18 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 22/33] s390: Use a larger stack for KMSAN Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 16:56   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 24/33] s390/checksum: Add a KMSAN check Ilya Leoshkevich
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

It should be possible to have inline functions in the s390 header
files, which call kmsan_unpoison_memory(). The problem is that these
header files might be included by the decompressor, which does not
contain KMSAN runtime, causing linker errors.

Not compiling these calls if __SANITIZE_MEMORY__ is not defined -
either by changing kmsan-checks.h or at the call sites - may cause
unintended side effects, since calling these functions from an
uninstrumented code that is linked into the kernel is valid use case.

One might want to explicitly distinguish between the kernel and the
decompressor. Checking for a decompressor-specific #define is quite
heavy-handed, and will have to be done at all call sites.

A more generic approach is to provide a dummy kmsan_unpoison_memory()
definition. This produces some runtime overhead, but only when building
with CONFIG_KMSAN. The benefit is that it does not disturb the existing
KMSAN build logic and call sites don't need to be changed.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/boot/Makefile | 1 +
 arch/s390/boot/kmsan.c  | 6 ++++++
 2 files changed, 7 insertions(+)
 create mode 100644 arch/s390/boot/kmsan.c

diff --git a/arch/s390/boot/Makefile b/arch/s390/boot/Makefile
index fb10fcd21221..096216a72e98 100644
--- a/arch/s390/boot/Makefile
+++ b/arch/s390/boot/Makefile
@@ -44,6 +44,7 @@ obj-$(findstring y, $(CONFIG_PROTECTED_VIRTUALIZATION_GUEST) $(CONFIG_PGSTE))	+=
 obj-$(CONFIG_RANDOMIZE_BASE)	+= kaslr.o
 obj-y	+= $(if $(CONFIG_KERNEL_UNCOMPRESSED),,decompressor.o) info.o
 obj-$(CONFIG_KERNEL_ZSTD) += clz_ctz.o
+obj-$(CONFIG_KMSAN) += kmsan.o
 obj-all := $(obj-y) piggy.o syms.o
 
 targets	:= bzImage section_cmp.boot.data section_cmp.boot.preserved.data $(obj-y)
diff --git a/arch/s390/boot/kmsan.c b/arch/s390/boot/kmsan.c
new file mode 100644
index 000000000000..e7b3ac48143e
--- /dev/null
+++ b/arch/s390/boot/kmsan.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/kmsan-checks.h>
+
+void kmsan_unpoison_memory(const void *address, size_t size)
+{
+}
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 24/33] s390/checksum: Add a KMSAN check
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (19 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 23/33] s390/boot: Add the KMSAN runtime stub Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 13:38   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 25/33] s390/cpacf: Unpoison the results of cpacf_trng() Ilya Leoshkevich
                   ` (9 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Add a KMSAN check to the CKSM inline assembly, similar to how it was
done for ASAN in commit e42ac7789df6 ("s390/checksum: always use cksm
instruction").

Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/include/asm/checksum.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h
index 69837eec2ff5..55ba0ddd8eab 100644
--- a/arch/s390/include/asm/checksum.h
+++ b/arch/s390/include/asm/checksum.h
@@ -13,6 +13,7 @@
 #define _S390_CHECKSUM_H
 
 #include <linux/kasan-checks.h>
+#include <linux/kmsan-checks.h>
 #include <linux/in6.h>
 
 /*
@@ -35,6 +36,7 @@ static inline __wsum csum_partial(const void *buff, int len, __wsum sum)
 	};
 
 	kasan_check_read(buff, len);
+	kmsan_check_memory(buff, len);
 	asm volatile(
 		"0:	cksm	%[sum],%[rp]\n"
 		"	jo	0b\n"
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 25/33] s390/cpacf: Unpoison the results of cpacf_trng()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (20 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 24/33] s390/checksum: Add a KMSAN check Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-11 10:36   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 26/33] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler() Ilya Leoshkevich
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Prevent KMSAN from complaining about buffers filled by cpacf_trng()
being uninitialized.

Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/include/asm/cpacf.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/arch/s390/include/asm/cpacf.h b/arch/s390/include/asm/cpacf.h
index b378e2b57ad8..a72b92770c4b 100644
--- a/arch/s390/include/asm/cpacf.h
+++ b/arch/s390/include/asm/cpacf.h
@@ -473,6 +473,8 @@ static inline void cpacf_trng(u8 *ucbuf, unsigned long ucbuf_len,
 		: [ucbuf] "+&d" (u.pair), [cbuf] "+&d" (c.pair)
 		: [fc] "K" (CPACF_PRNO_TRNG), [opc] "i" (CPACF_PRNO)
 		: "cc", "memory", "0");
+	kmsan_unpoison_memory(ucbuf, ucbuf_len);
+	kmsan_unpoison_memory(cbuf, cbuf_len);
 }
 
 /**
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 26/33] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (21 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 25/33] s390/cpacf: Unpoison the results of cpacf_trng() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-08 14:18   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 27/33] s390/mm: Define KMSAN metadata for vmalloc and modules Ilya Leoshkevich
                   ` (7 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

s390 uses assembly code to initialize ftrace_regs and call
kprobe_ftrace_handler(). Therefore, from the KMSAN's point of view,
ftrace_regs is poisoned on kprobe_ftrace_handler() entry. This causes
KMSAN warnings when running the ftrace testsuite.

Fix by trusting the assembly code and always unpoisoning ftrace_regs in
kprobe_ftrace_handler().

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/kernel/ftrace.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/s390/kernel/ftrace.c b/arch/s390/kernel/ftrace.c
index c46381ea04ec..3bad34eaa51e 100644
--- a/arch/s390/kernel/ftrace.c
+++ b/arch/s390/kernel/ftrace.c
@@ -300,6 +300,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
 	if (bit < 0)
 		return;
 
+	kmsan_unpoison_memory(fregs, sizeof(*fregs));
 	regs = ftrace_get_regs(fregs);
 	p = get_kprobe((kprobe_opcode_t *)ip);
 	if (!regs || unlikely(!p) || kprobe_disabled(p))
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 27/33] s390/mm: Define KMSAN metadata for vmalloc and modules
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (22 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 26/33] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-11 10:13   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 28/33] s390/string: Add KMSAN support Ilya Leoshkevich
                   ` (6 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

The pages for the KMSAN metadata associated with most kernel mappings
are taken from memblock by the common code. However, vmalloc and module
metadata needs to be defined by the architectures.

Be a little bit more careful than x86: allocate exactly MODULES_LEN
for the module shadow and origins, and then take 2/3 of vmalloc for
the vmalloc shadow and origins. This ensures that users passing small
vmalloc= values on the command line do not cause module metadata
collisions.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/boot/startup.c        |  8 ++++++++
 arch/s390/include/asm/pgtable.h | 10 ++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 8104e0e3d188..e37e7ffda430 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -253,9 +253,17 @@ static unsigned long setup_kernel_memory_layout(void)
 	MODULES_END = round_down(__abs_lowcore, _SEGMENT_SIZE);
 	MODULES_VADDR = MODULES_END - MODULES_LEN;
 	VMALLOC_END = MODULES_VADDR;
+#ifdef CONFIG_KMSAN
+	VMALLOC_END -= MODULES_LEN * 2;
+#endif
 
 	/* allow vmalloc area to occupy up to about 1/2 of the rest virtual space left */
 	vmalloc_size = min(vmalloc_size, round_down(VMALLOC_END / 2, _REGION3_SIZE));
+#ifdef CONFIG_KMSAN
+	/* take 2/3 of vmalloc area for KMSAN shadow and origins */
+	vmalloc_size = round_down(vmalloc_size / 3, _REGION3_SIZE);
+	VMALLOC_END -= vmalloc_size * 2;
+#endif
 	VMALLOC_START = VMALLOC_END - vmalloc_size;
 
 	/* split remaining virtual space between 1:1 mapping & vmemmap array */
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index 601e87fa8a9a..d764abeb9e6d 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -107,6 +107,16 @@ static inline int is_module_addr(void *addr)
 	return 1;
 }
 
+#ifdef CONFIG_KMSAN
+#define KMSAN_VMALLOC_SIZE (VMALLOC_END - VMALLOC_START)
+#define KMSAN_VMALLOC_SHADOW_START VMALLOC_END
+#define KMSAN_VMALLOC_ORIGIN_START (KMSAN_VMALLOC_SHADOW_START + \
+				    KMSAN_VMALLOC_SIZE)
+#define KMSAN_MODULES_SHADOW_START (KMSAN_VMALLOC_ORIGIN_START + \
+				    KMSAN_VMALLOC_SIZE)
+#define KMSAN_MODULES_ORIGIN_START (KMSAN_MODULES_SHADOW_START + MODULES_LEN)
+#endif
+
 /*
  * A 64 bit pagetable entry of S390 has following format:
  * |			 PFRA			      |0IPC|  OS  |
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 28/33] s390/string: Add KMSAN support
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (23 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 27/33] s390/mm: Define KMSAN metadata for vmalloc and modules Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-11 10:49   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 29/33] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs Ilya Leoshkevich
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Add KMSAN support for the s390 implementations of the string functions.
Do this similar to how it's already done for KASAN, except that the
optimized memset{16,32,64}() functions need to be disabled: it's
important for KMSAN to know that they initialized something.

The way boot code is built with regard to string functions is
problematic, since most files think it's configured with sanitizers,
but boot/string.c doesn't. This creates various problems with the
memset64() definitions, depending on whether the code is built with
sanitizers or fortify. This should probably be streamlined, but in the
meantime resolve the issues by introducing the IN_BOOT_STRING_C macro,
similar to the existing IN_ARCH_STRING_C macro.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/boot/string.c        | 16 ++++++++++++++++
 arch/s390/include/asm/string.h | 20 +++++++++++++++-----
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index faccb33b462c..f6b9b1df48a8 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -1,11 +1,18 @@
 // SPDX-License-Identifier: GPL-2.0
+#define IN_BOOT_STRING_C 1
 #include <linux/ctype.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #undef CONFIG_KASAN
 #undef CONFIG_KASAN_GENERIC
+#undef CONFIG_KMSAN
 #include "../lib/string.c"
 
+/*
+ * Duplicate some functions from the common lib/string.c
+ * instead of fully including it.
+ */
+
 int strncmp(const char *cs, const char *ct, size_t count)
 {
 	unsigned char c1, c2;
@@ -22,6 +29,15 @@ int strncmp(const char *cs, const char *ct, size_t count)
 	return 0;
 }
 
+void *memset64(uint64_t *s, uint64_t v, size_t count)
+{
+	uint64_t *xs = s;
+
+	while (count--)
+		*xs++ = v;
+	return s;
+}
+
 char *skip_spaces(const char *str)
 {
 	while (isspace(*str))
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index 351685de53d2..2ab868cbae6c 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -15,15 +15,12 @@
 #define __HAVE_ARCH_MEMCPY	/* gcc builtin & arch function */
 #define __HAVE_ARCH_MEMMOVE	/* gcc builtin & arch function */
 #define __HAVE_ARCH_MEMSET	/* gcc builtin & arch function */
-#define __HAVE_ARCH_MEMSET16	/* arch function */
-#define __HAVE_ARCH_MEMSET32	/* arch function */
-#define __HAVE_ARCH_MEMSET64	/* arch function */
 
 void *memcpy(void *dest, const void *src, size_t n);
 void *memset(void *s, int c, size_t n);
 void *memmove(void *dest, const void *src, size_t n);
 
-#ifndef CONFIG_KASAN
+#if !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN)
 #define __HAVE_ARCH_MEMCHR	/* inline & arch function */
 #define __HAVE_ARCH_MEMCMP	/* arch function */
 #define __HAVE_ARCH_MEMSCAN	/* inline & arch function */
@@ -36,6 +33,9 @@ void *memmove(void *dest, const void *src, size_t n);
 #define __HAVE_ARCH_STRNCPY	/* arch function */
 #define __HAVE_ARCH_STRNLEN	/* inline & arch function */
 #define __HAVE_ARCH_STRSTR	/* arch function */
+#define __HAVE_ARCH_MEMSET16	/* arch function */
+#define __HAVE_ARCH_MEMSET32	/* arch function */
+#define __HAVE_ARCH_MEMSET64	/* arch function */
 
 /* Prototypes for non-inlined arch strings functions. */
 int memcmp(const void *s1, const void *s2, size_t n);
@@ -44,7 +44,7 @@ size_t strlcat(char *dest, const char *src, size_t n);
 char *strncat(char *dest, const char *src, size_t n);
 char *strncpy(char *dest, const char *src, size_t n);
 char *strstr(const char *s1, const char *s2);
-#endif /* !CONFIG_KASAN */
+#endif /* !defined(CONFIG_KASAN) && !defined(CONFIG_KMSAN) */
 
 #undef __HAVE_ARCH_STRCHR
 #undef __HAVE_ARCH_STRNCHR
@@ -74,20 +74,30 @@ void *__memset16(uint16_t *s, uint16_t v, size_t count);
 void *__memset32(uint32_t *s, uint32_t v, size_t count);
 void *__memset64(uint64_t *s, uint64_t v, size_t count);
 
+#ifdef __HAVE_ARCH_MEMSET16
 static inline void *memset16(uint16_t *s, uint16_t v, size_t count)
 {
 	return __memset16(s, v, count * sizeof(v));
 }
+#endif
 
+#ifdef __HAVE_ARCH_MEMSET32
 static inline void *memset32(uint32_t *s, uint32_t v, size_t count)
 {
 	return __memset32(s, v, count * sizeof(v));
 }
+#endif
 
+#ifdef __HAVE_ARCH_MEMSET64
+#ifdef IN_BOOT_STRING_C
+void *memset64(uint64_t *s, uint64_t v, size_t count);
+#else
 static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
 {
 	return __memset64(s, v, count * sizeof(v));
 }
+#endif
+#endif
 
 #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))
 
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 29/33] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (24 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 28/33] s390/string: Add KMSAN support Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 30/33] s390/uaccess: Add KMSAN support to put_user() and get_user() Ilya Leoshkevich
                   ` (4 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

This is normally done by the generic entry code, but the
kernel_stack_overflow() flow bypasses it.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/kernel/traps.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 1d2aa448d103..f299b1203a20 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -27,6 +27,7 @@
 #include <linux/uaccess.h>
 #include <linux/cpu.h>
 #include <linux/entry-common.h>
+#include <linux/kmsan.h>
 #include <asm/asm-extable.h>
 #include <asm/fpu/api.h>
 #include <asm/vtime.h>
@@ -260,6 +261,11 @@ static void monitor_event_exception(struct pt_regs *regs)
 
 void kernel_stack_overflow(struct pt_regs *regs)
 {
+	/*
+	 * Normally regs are unpoisoned by the generic entry code, but
+	 * kernel_stack_overflow() is a rare case that is called bypassing it.
+	 */
+	kmsan_unpoison_entry_regs(regs);
 	bust_spinlocks(1);
 	printk("Kernel stack overflow.\n");
 	show_regs(regs);
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 30/33] s390/uaccess: Add KMSAN support to put_user() and get_user()
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (25 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 29/33] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-11 10:46   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 31/33] s390/unwind: Disable KMSAN checks Ilya Leoshkevich
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

put_user() uses inline assembly with precise constraints, so Clang is
in principle capable of instrumenting it automatically. Unfortunately,
one of the constraints contains a dereferenced user pointer, and Clang
does not currently distinguish user and kernel pointers. Therefore
KMSAN attempts to access shadow for user pointers, which is not a right
thing to do.

An obvious fix to add __no_sanitize_memory to __put_user_fn() does not
work, since it's __always_inline. And __always_inline cannot be removed
due to the __put_user_bad() trick.

A different obvious fix of using the "a" instead of the "+Q" constraint
degrades the code quality, which is very important here, since it's a
hot path.

Instead, repurpose the __put_user_asm() macro to define
__put_user_{char,short,int,long}_noinstr() functions and mark them with
__no_sanitize_memory. For the non-KMSAN builds make them
__always_inline in order to keep the generated code quality. Also
define __put_user_{char,short,int,long}() functions, which call the
aforementioned ones and which *are* instrumented, because they call
KMSAN hooks, which may be implemented as macros.

The same applies to get_user() as well.

Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/include/asm/uaccess.h | 110 ++++++++++++++++++++++----------
 1 file changed, 78 insertions(+), 32 deletions(-)

diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 81ae8a98e7ec..b0715b88b55a 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -78,13 +78,23 @@ union oac {
 
 int __noreturn __put_user_bad(void);
 
-#define __put_user_asm(to, from, size)					\
-({									\
+#ifdef CONFIG_KMSAN
+#define GET_PUT_USER_NOINSTR_ATTRIBUTES inline __no_sanitize_memory
+#else
+#define GET_PUT_USER_NOINSTR_ATTRIBUTES __always_inline
+#endif
+
+#define DEFINE_PUT_USER(type)						\
+static GET_PUT_USER_NOINSTR_ATTRIBUTES int				\
+__put_user_##type##_noinstr(unsigned type __user *to,			\
+			    unsigned type *from,			\
+			    unsigned long size)				\
+{									\
 	union oac __oac_spec = {					\
 		.oac1.as = PSW_BITS_AS_SECONDARY,			\
 		.oac1.a = 1,						\
 	};								\
-	int __rc;							\
+	int rc;								\
 									\
 	asm volatile(							\
 		"	lr	0,%[spec]\n"				\
@@ -93,12 +103,28 @@ int __noreturn __put_user_bad(void);
 		"2:\n"							\
 		EX_TABLE_UA_STORE(0b, 2b, %[rc])			\
 		EX_TABLE_UA_STORE(1b, 2b, %[rc])			\
-		: [rc] "=&d" (__rc), [_to] "+Q" (*(to))			\
+		: [rc] "=&d" (rc), [_to] "+Q" (*(to))			\
 		: [_size] "d" (size), [_from] "Q" (*(from)),		\
 		  [spec] "d" (__oac_spec.val)				\
 		: "cc", "0");						\
-	__rc;								\
-})
+	return rc;							\
+}									\
+									\
+static __always_inline int						\
+__put_user_##type(unsigned type __user *to, unsigned type *from,	\
+		  unsigned long size)					\
+{									\
+	int rc;								\
+									\
+	rc = __put_user_##type##_noinstr(to, from, size);		\
+	instrument_put_user(*from, to, size);				\
+	return rc;							\
+}
+
+DEFINE_PUT_USER(char);
+DEFINE_PUT_USER(short);
+DEFINE_PUT_USER(int);
+DEFINE_PUT_USER(long);
 
 static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned long size)
 {
@@ -106,24 +132,24 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon
 
 	switch (size) {
 	case 1:
-		rc = __put_user_asm((unsigned char __user *)ptr,
-				    (unsigned char *)x,
-				    size);
+		rc = __put_user_char((unsigned char __user *)ptr,
+				     (unsigned char *)x,
+				     size);
 		break;
 	case 2:
-		rc = __put_user_asm((unsigned short __user *)ptr,
-				    (unsigned short *)x,
-				    size);
+		rc = __put_user_short((unsigned short __user *)ptr,
+				      (unsigned short *)x,
+				      size);
 		break;
 	case 4:
-		rc = __put_user_asm((unsigned int __user *)ptr,
+		rc = __put_user_int((unsigned int __user *)ptr,
 				    (unsigned int *)x,
 				    size);
 		break;
 	case 8:
-		rc = __put_user_asm((unsigned long __user *)ptr,
-				    (unsigned long *)x,
-				    size);
+		rc = __put_user_long((unsigned long __user *)ptr,
+				     (unsigned long *)x,
+				     size);
 		break;
 	default:
 		__put_user_bad();
@@ -134,13 +160,17 @@ static __always_inline int __put_user_fn(void *x, void __user *ptr, unsigned lon
 
 int __noreturn __get_user_bad(void);
 
-#define __get_user_asm(to, from, size)					\
-({									\
+#define DEFINE_GET_USER(type)						\
+static GET_PUT_USER_NOINSTR_ATTRIBUTES int				\
+__get_user_##type##_noinstr(unsigned type *to,				\
+			    unsigned type __user *from,			\
+			    unsigned long size)				\
+{									\
 	union oac __oac_spec = {					\
 		.oac2.as = PSW_BITS_AS_SECONDARY,			\
 		.oac2.a = 1,						\
 	};								\
-	int __rc;							\
+	int rc;								\
 									\
 	asm volatile(							\
 		"	lr	0,%[spec]\n"				\
@@ -149,13 +179,29 @@ int __noreturn __get_user_bad(void);
 		"2:\n"							\
 		EX_TABLE_UA_LOAD_MEM(0b, 2b, %[rc], %[_to], %[_ksize])	\
 		EX_TABLE_UA_LOAD_MEM(1b, 2b, %[rc], %[_to], %[_ksize])	\
-		: [rc] "=&d" (__rc), "=Q" (*(to))			\
+		: [rc] "=&d" (rc), "=Q" (*(to))				\
 		: [_size] "d" (size), [_from] "Q" (*(from)),		\
 		  [spec] "d" (__oac_spec.val), [_to] "a" (to),		\
 		  [_ksize] "K" (size)					\
 		: "cc", "0");						\
-	__rc;								\
-})
+	return rc;							\
+}									\
+									\
+static __always_inline int						\
+__get_user_##type(unsigned type *to, unsigned type __user *from,	\
+		  unsigned long size)					\
+{									\
+	int rc;								\
+									\
+	rc = __get_user_##type##_noinstr(to, from, size);		\
+	instrument_get_user(*to);					\
+	return rc;							\
+}
+
+DEFINE_GET_USER(char);
+DEFINE_GET_USER(short);
+DEFINE_GET_USER(int);
+DEFINE_GET_USER(long);
 
 static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsigned long size)
 {
@@ -163,24 +209,24 @@ static __always_inline int __get_user_fn(void *x, const void __user *ptr, unsign
 
 	switch (size) {
 	case 1:
-		rc = __get_user_asm((unsigned char *)x,
-				    (unsigned char __user *)ptr,
-				    size);
+		rc = __get_user_char((unsigned char *)x,
+				     (unsigned char __user *)ptr,
+				     size);
 		break;
 	case 2:
-		rc = __get_user_asm((unsigned short *)x,
-				    (unsigned short __user *)ptr,
-				    size);
+		rc = __get_user_short((unsigned short *)x,
+				      (unsigned short __user *)ptr,
+				      size);
 		break;
 	case 4:
-		rc = __get_user_asm((unsigned int *)x,
+		rc = __get_user_int((unsigned int *)x,
 				    (unsigned int __user *)ptr,
 				    size);
 		break;
 	case 8:
-		rc = __get_user_asm((unsigned long *)x,
-				    (unsigned long __user *)ptr,
-				    size);
+		rc = __get_user_long((unsigned long *)x,
+				     (unsigned long __user *)ptr,
+				     size);
 		break;
 	default:
 		__get_user_bad();
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 31/33] s390/unwind: Disable KMSAN checks
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (26 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 30/33] s390/uaccess: Add KMSAN support to put_user() and get_user() Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-21 22:01 ` [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions Ilya Leoshkevich
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

The unwind code can read uninitialized frames. Furthermore, even in
the good case, KMSAN does not emit shadow for backchains. Therefore
disable it for the unwinding functions.

Reviewed-by: Alexander Potapenko <glider@google.com>
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/kernel/unwind_bc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/s390/kernel/unwind_bc.c b/arch/s390/kernel/unwind_bc.c
index 0ece156fdd7c..cd44be2b6ce8 100644
--- a/arch/s390/kernel/unwind_bc.c
+++ b/arch/s390/kernel/unwind_bc.c
@@ -49,6 +49,8 @@ static inline bool is_final_pt_regs(struct unwind_state *state,
 	       READ_ONCE_NOCHECK(regs->psw.mask) & PSW_MASK_PSTATE;
 }
 
+/* Avoid KMSAN false positives from touching uninitialized frames. */
+__no_kmsan_checks
 bool unwind_next_frame(struct unwind_state *state)
 {
 	struct stack_info *info = &state->stack_info;
@@ -118,6 +120,8 @@ bool unwind_next_frame(struct unwind_state *state)
 }
 EXPORT_SYMBOL_GPL(unwind_next_frame);
 
+/* Avoid KMSAN false positives from touching uninitialized frames. */
+__no_kmsan_checks
 void __unwind_start(struct unwind_state *state, struct task_struct *task,
 		    struct pt_regs *regs, unsigned long first_frame)
 {
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (27 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 31/33] s390/unwind: Disable KMSAN checks Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-12-11 10:26   ` Alexander Potapenko
  2023-11-21 22:01 ` [PATCH v2 33/33] kmsan: Enable on s390 Ilya Leoshkevich
       [not found] ` <20231121220155.1217090-11-iii@linux.ibm.com>
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

arch_kmsan_get_meta_or_null() finds the lowcore shadow by querying the
prefix and calling kmsan_get_metadata() again.

kmsan_virt_addr_valid() delegates to virt_addr_valid().

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/include/asm/kmsan.h | 36 +++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
 create mode 100644 arch/s390/include/asm/kmsan.h

diff --git a/arch/s390/include/asm/kmsan.h b/arch/s390/include/asm/kmsan.h
new file mode 100644
index 000000000000..afec71e9e9ac
--- /dev/null
+++ b/arch/s390/include/asm/kmsan.h
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_S390_KMSAN_H
+#define _ASM_S390_KMSAN_H
+
+#include <asm/lowcore.h>
+#include <asm/page.h>
+#include <linux/kmsan.h>
+#include <linux/mmzone.h>
+#include <linux/stddef.h>
+
+#ifndef MODULE
+
+static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
+{
+	if (addr >= (void *)&S390_lowcore &&
+	    addr < (void *)(&S390_lowcore + 1)) {
+		/*
+		 * Different lowcores accessed via S390_lowcore are described
+		 * by the same struct page. Resolve the prefix manually in
+		 * order to get a distinct struct page.
+		 */
+		addr += (void *)lowcore_ptr[raw_smp_processor_id()] -
+			(void *)&S390_lowcore;
+		return kmsan_get_metadata(addr, is_origin);
+	}
+	return NULL;
+}
+
+static inline bool kmsan_virt_addr_valid(void *addr)
+{
+	return virt_addr_valid(addr);
+}
+
+#endif /* !MODULE */
+
+#endif /* _ASM_S390_KMSAN_H */
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* [PATCH v2 33/33] kmsan: Enable on s390
  2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
                   ` (28 preceding siblings ...)
  2023-11-21 22:01 ` [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions Ilya Leoshkevich
@ 2023-11-21 22:01 ` Ilya Leoshkevich
  2023-11-29  9:19   ` Alexander Potapenko
       [not found] ` <20231121220155.1217090-11-iii@linux.ibm.com>
  30 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-21 22:01 UTC (permalink / raw)
  To: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Steven Rostedt,
	Vasily Gorbik, Vlastimil Babka
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle, Ilya Leoshkevich

Now that everything else is in place, enable KMSAN in Kconfig.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
 arch/s390/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 3bec98d20283..160ad2220c53 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -153,6 +153,7 @@ config S390
 	select HAVE_ARCH_KASAN
 	select HAVE_ARCH_KASAN_VMALLOC
 	select HAVE_ARCH_KCSAN
+	select HAVE_ARCH_KMSAN
 	select HAVE_ARCH_KFENCE
 	select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
 	select HAVE_ARCH_SECCOMP_FILTER
-- 
2.41.0



^ permalink raw reply related	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func()
  2023-11-21 22:00 ` [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func() Ilya Leoshkevich
@ 2023-11-22 23:32   ` Steven Rostedt
  2023-12-08 14:16   ` Alexander Potapenko
  1 sibling, 0 replies; 63+ messages in thread
From: Steven Rostedt @ 2023-11-22 23:32 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Alexander Potapenko, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, 21 Nov 2023 23:00:55 +0100
Ilya Leoshkevich <iii@linux.ibm.com> wrote:

> Architectures use assembly code to initialize ftrace_regs and call
> ftrace_ops_list_func(). Therefore, from the KMSAN's point of view,
> ftrace_regs is poisoned on ftrace_ops_list_func entry(). This causes
> KMSAN warnings when running the ftrace testsuite.
> 
> Fix by trusting the architecture-specific assembly code and always
> unpoisoning ftrace_regs in ftrace_ops_list_func.

You must be very trusting to trust architecture-specific assembly code ;-)

Acked-by: Steven Rostedt (Google) <rostedt@goodmis.org>

-- Steve


> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>  kernel/trace/ftrace.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
> index 8de8bec5f366..dfb8b26966aa 100644
> --- a/kernel/trace/ftrace.c
> +++ b/kernel/trace/ftrace.c
> @@ -7399,6 +7399,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
>  void arch_ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,
>  			       struct ftrace_ops *op, struct ftrace_regs *fregs)
>  {
> +	kmsan_unpoison_memory(fregs, sizeof(*fregs));
>  	__ftrace_ops_list_func(ip, parent_ip, NULL, fregs);
>  }
>  #else



^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 33/33] kmsan: Enable on s390
  2023-11-21 22:01 ` [PATCH v2 33/33] kmsan: Enable on s390 Ilya Leoshkevich
@ 2023-11-29  9:19   ` Alexander Potapenko
  2023-11-29  9:58     ` Ilya Leoshkevich
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-11-29  9:19 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

Hi Ilya,

Sorry for this taking so long, I'll probably take a closer look next week.
Overall, the s390 part looks good to me, but I wanted to check the x86
behavior once again (and perhaps figure out how to avoid introducing
another way to disable KMSAN).
Do you happen to have a Git repo with your patches somewhere?


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 33/33] kmsan: Enable on s390
  2023-11-29  9:19   ` Alexander Potapenko
@ 2023-11-29  9:58     ` Ilya Leoshkevich
  0 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-11-29  9:58 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Wed, 2023-11-29 at 10:19 +0100, Alexander Potapenko wrote:
> Hi Ilya,
> 
> Sorry for this taking so long, I'll probably take a closer look next
> week.
> Overall, the s390 part looks good to me, but I wanted to check the
> x86
> behavior once again (and perhaps figure out how to avoid introducing
> another way to disable KMSAN).
> Do you happen to have a Git repo with your patches somewhere?

Hi, yes, the latest version of the patches is available at [1].

[1] https://github.com/iii-i/linux/tree/kmsan


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 16/33] mm: slub: Let KMSAN access metadata
  2023-11-21 22:01 ` [PATCH v2 16/33] mm: slub: Let KMSAN access metadata Ilya Leoshkevich
@ 2023-11-30 15:26   ` Vlastimil Babka
  0 siblings, 0 replies; 63+ messages in thread
From: Vlastimil Babka @ 2023-11-30 15:26 UTC (permalink / raw)
  To: Ilya Leoshkevich, Alexander Gordeev, Alexander Potapenko,
	Andrew Morton, Christoph Lameter, David Rientjes, Heiko Carstens,
	Joonsoo Kim, Marco Elver, Masami Hiramatsu, Pekka Enberg,
	Steven Rostedt, Vasily Gorbik
  Cc: Christian Borntraeger, Dmitry Vyukov, Hyeonggon Yoo, kasan-dev,
	linux-kernel, linux-mm, linux-s390, linux-trace-kernel,
	Mark Rutland, Roman Gushchin, Sven Schnelle

On 11/21/23 23:01, Ilya Leoshkevich wrote:
> Building the kernel with CONFIG_SLUB_DEBUG and CONFIG_KMSAN causes
> KMSAN to complain about touching redzones in kfree().
> 
> Fix by extending the existing KASAN-related metadata_access_enable()
> and metadata_access_disable() functions to KMSAN.
> 
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>

Acked-by: Vlastimil Babka <vbabka@suse.cz>

> ---
>  mm/slub.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/mm/slub.c b/mm/slub.c
> index 169e5f645ea8..6e61c27951a4 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -700,10 +700,12 @@ static int disable_higher_order_debug;
>  static inline void metadata_access_enable(void)
>  {
>  	kasan_disable_current();
> +	kmsan_disable_current();
>  }
>  
>  static inline void metadata_access_disable(void)
>  {
> +	kmsan_enable_current();
>  	kasan_enable_current();
>  }
>  



^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary
  2023-11-21 22:01 ` [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary Ilya Leoshkevich
@ 2023-12-08 12:53   ` Alexander Potapenko
  2023-12-08 13:55     ` Alexander Potapenko
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 12:53 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> KMSAN warns about check_canary() accessing the canary.
>
> The reason is that, even though set_canary() is properly instrumented
> and sets shadow, slub explicitly poisons the canary's address range
> afterwards.
>
> Unpoisoning the canary is not the right thing to do: only
> check_canary() is supposed to ever touch it. Instead, disable KMSAN
> checks around canary read accesses.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers
  2023-11-21 22:01 ` [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers Ilya Leoshkevich
@ 2023-12-08 13:32   ` Alexander Potapenko
  2023-12-08 14:14     ` Ilya Leoshkevich
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 13:32 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:07 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> The constraints of the DFLTCC inline assembly are not precise: they
> do not communicate the size of the output buffers to the compiler, so
> it cannot automatically instrument it.

KMSAN usually does a poor job instrumenting inline assembly.
Wouldn't be it better to switch to pure C ZLIB implementation, making
ZLIB_DFLTCC depend on !KMSAN?


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 24/33] s390/checksum: Add a KMSAN check
  2023-11-21 22:01 ` [PATCH v2 24/33] s390/checksum: Add a KMSAN check Ilya Leoshkevich
@ 2023-12-08 13:38   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 13:38 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Add a KMSAN check to the CKSM inline assembly, similar to how it was
> done for ASAN in commit e42ac7789df6 ("s390/checksum: always use cksm
> instruction").
>
> Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory()
  2023-11-21 22:01 ` [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory() Ilya Leoshkevich
@ 2023-12-08 13:48   ` Alexander Potapenko
       [not found]     ` <69e7bc8e8c8a38c429a793e991e0509cb97a53e1.camel@linux.ibm.com>
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 13:48 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:06 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Add a wrapper for memset() that prevents unpoisoning.

We have __memset() already, won't it work for this case?
On the other hand, I am not sure you want to preserve the redzone in
its previous state (unless it's known to be poisoned).
You might consider explicitly unpoisoning the redzone instead.

...

> +__no_sanitize_memory
> +static inline void *memset_no_sanitize_memory(void *s, int c, size_t n)
> +{
> +       return memset(s, c, n);
> +}

I think depending on the compiler optimizations this might end up
being a call to normal memset, that would still change the shadow
bytes.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 14/33] kmsan: Support SLAB_POISON
  2023-11-21 22:01 ` [PATCH v2 14/33] kmsan: Support SLAB_POISON Ilya Leoshkevich
@ 2023-12-08 13:51   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 13:51 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Avoid false KMSAN negatives with SLUB_DEBUG by allowing
> kmsan_slab_free() to poison the freed memory, and by preventing
> init_object() from unpoisoning new allocations. The usage of
> memset_no_sanitize_memory() does not degrade the generated code
> quality.
>
> There are two alternatives to this approach. First, init_object()
> can be marked with __no_sanitize_memory. This annotation should be used
> with great care, because it drops all instrumentation from the
> function, and any shadow writes will be lost. Even though this is not a
> concern with the current init_object() implementation, this may change
> in the future.
>
> Second, kmsan_poison_memory() calls may be added after memset() calls.
> The downside is that init_object() is called from
> free_debug_processing(), in which case poisoning will erase the
> distinction between simply uninitialized memory and UAF.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>  mm/kmsan/hooks.c |  2 +-
>  mm/slub.c        | 10 ++++++----
>  2 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/mm/kmsan/hooks.c b/mm/kmsan/hooks.c
> index 7b5814412e9f..7a30274b893c 100644
> --- a/mm/kmsan/hooks.c
> +++ b/mm/kmsan/hooks.c
> @@ -76,7 +76,7 @@ void kmsan_slab_free(struct kmem_cache *s, void *object)
>                 return;
>
>         /* RCU slabs could be legally used after free within the RCU period */
> -       if (unlikely(s->flags & (SLAB_TYPESAFE_BY_RCU | SLAB_POISON)))
> +       if (unlikely(s->flags & SLAB_TYPESAFE_BY_RCU))
>                 return;
>         /*
>          * If there's a constructor, freed memory must remain in the same state
> diff --git a/mm/slub.c b/mm/slub.c
> index 63d281dfacdb..169e5f645ea8 100644
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -1030,7 +1030,8 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
>         unsigned int poison_size = s->object_size;
>
>         if (s->flags & SLAB_RED_ZONE) {
> -               memset(p - s->red_left_pad, val, s->red_left_pad);
> +               memset_no_sanitize_memory(p - s->red_left_pad, val,

As I wrote in patch 13/33, let's try to use __memset() here (with a
comment that we want to preserve the previously poisoned memory)


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary
  2023-12-08 12:53   ` Alexander Potapenko
@ 2023-12-08 13:55     ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 13:55 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Fri, Dec 8, 2023 at 1:53 PM Alexander Potapenko <glider@google.com> wrote:
>
> On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
> >
> > KMSAN warns about check_canary() accessing the canary.
> >
> > The reason is that, even though set_canary() is properly instrumented
> > and sets shadow, slub explicitly poisons the canary's address range
> > afterwards.
> >
> > Unpoisoning the canary is not the right thing to do: only
> > check_canary() is supposed to ever touch it. Instead, disable KMSAN
> > checks around canary read accesses.
> >
> > Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> Reviewed-by: Alexander Potapenko <glider@google.com>

and even

Tested-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers
  2023-12-08 13:32   ` Alexander Potapenko
@ 2023-12-08 14:14     ` Ilya Leoshkevich
  2023-12-08 14:25       ` Alexander Potapenko
  0 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-12-08 14:14 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle,
	Mikhail Zaslonko

On Fri, 2023-12-08 at 14:32 +0100, Alexander Potapenko wrote:
> On Tue, Nov 21, 2023 at 11:07 PM Ilya Leoshkevich <iii@linux.ibm.com>
> wrote:
> > 
> > The constraints of the DFLTCC inline assembly are not precise: they
> > do not communicate the size of the output buffers to the compiler,
> > so
> > it cannot automatically instrument it.
> 
> KMSAN usually does a poor job instrumenting inline assembly.
> Wouldn't be it better to switch to pure C ZLIB implementation, making
> ZLIB_DFLTCC depend on !KMSAN?

Normally I would agree, but the kernel DFLTCC code base is synced with
the zlib-ng code base to the extent that it uses the zlib-ng code style
instead of the kernel code style, and MSAN annotations are already a
part of the zlib-ng code base. So I would prefer to keep them for
consistency.

The code is also somewhat tricky in the are of buffer management, so I
find it beneficial to have it checked for uninitialized memory
accesses.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func()
  2023-11-21 22:00 ` [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func() Ilya Leoshkevich
  2023-11-22 23:32   ` Steven Rostedt
@ 2023-12-08 14:16   ` Alexander Potapenko
  2023-12-08 14:31     ` Steven Rostedt
  1 sibling, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 14:16 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Architectures use assembly code to initialize ftrace_regs and call
> ftrace_ops_list_func(). Therefore, from the KMSAN's point of view,
> ftrace_regs is poisoned on ftrace_ops_list_func entry(). This causes
> KMSAN warnings when running the ftrace testsuite.

I couldn't reproduce these warnings on x86, hope you really need this
change on s390 :)

> Fix by trusting the architecture-specific assembly code and always
> unpoisoning ftrace_regs in ftrace_ops_list_func.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 26/33] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler()
  2023-11-21 22:01 ` [PATCH v2 26/33] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler() Ilya Leoshkevich
@ 2023-12-08 14:18   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 14:18 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> s390 uses assembly code to initialize ftrace_regs and call
> kprobe_ftrace_handler(). Therefore, from the KMSAN's point of view,
> ftrace_regs is poisoned on kprobe_ftrace_handler() entry. This causes
> KMSAN warnings when running the ftrace testsuite.
>
> Fix by trusting the assembly code and always unpoisoning ftrace_regs in
> kprobe_ftrace_handler().
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers
  2023-12-08 14:14     ` Ilya Leoshkevich
@ 2023-12-08 14:25       ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 14:25 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle,
	Mikhail Zaslonko

On Fri, Dec 8, 2023 at 3:14 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> On Fri, 2023-12-08 at 14:32 +0100, Alexander Potapenko wrote:
> > On Tue, Nov 21, 2023 at 11:07 PM Ilya Leoshkevich <iii@linux.ibm.com>
> > wrote:
> > >
> > > The constraints of the DFLTCC inline assembly are not precise: they
> > > do not communicate the size of the output buffers to the compiler,
> > > so
> > > it cannot automatically instrument it.
> >
> > KMSAN usually does a poor job instrumenting inline assembly.
> > Wouldn't be it better to switch to pure C ZLIB implementation, making
> > ZLIB_DFLTCC depend on !KMSAN?
>
> Normally I would agree, but the kernel DFLTCC code base is synced with
> the zlib-ng code base to the extent that it uses the zlib-ng code style
> instead of the kernel code style, and MSAN annotations are already a
> part of the zlib-ng code base. So I would prefer to keep them for
> consistency.

Hm, I didn't realize this code is being taken from elsewhere.
If so, maybe we should come up with an annotation that can be
contributed to zlib-ng, so that it doesn't cause merge conflicts every
time Mikhail is doing an update?
(leaving this up to you to decide).

If you decide to go with the current solution, please consider adding
an #include for kmsan-checks.h, which introduces
kmsan_unpoison_memory().


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func()
  2023-12-08 14:16   ` Alexander Potapenko
@ 2023-12-08 14:31     ` Steven Rostedt
  0 siblings, 0 replies; 63+ messages in thread
From: Steven Rostedt @ 2023-12-08 14:31 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Ilya Leoshkevich, Alexander Gordeev, Andrew Morton,
	Christoph Lameter, David Rientjes, Heiko Carstens, Joonsoo Kim,
	Marco Elver, Masami Hiramatsu, Pekka Enberg, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Fri, 8 Dec 2023 15:16:10 +0100
Alexander Potapenko <glider@google.com> wrote:

> On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
> >
> > Architectures use assembly code to initialize ftrace_regs and call
> > ftrace_ops_list_func(). Therefore, from the KMSAN's point of view,
> > ftrace_regs is poisoned on ftrace_ops_list_func entry(). This causes
> > KMSAN warnings when running the ftrace testsuite.  
> 
> I couldn't reproduce these warnings on x86, hope you really need this
> change on s390 :)

On x86, ftrace_regs sits on the stack. And IIUC, s390 doesn't have the same
concept of a "stack" as other architectures. Perhaps that's the reason s390
needs this?

-- Steve


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory()
       [not found]     ` <69e7bc8e8c8a38c429a793e991e0509cb97a53e1.camel@linux.ibm.com>
@ 2023-12-08 15:25       ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 15:25 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

> A problem with __memset() is that, at least for me, it always ends
> up being a call. There is a use case where we need to write only 1
> byte, so I thought that introducing a call there (when compiling
> without KMSAN) would be unacceptable.

Wonder what happens with that use case if we e.g. build with fortify-source.
Calling memset() for a single byte might be indicating the code is not hot.

> > ...
> >
> > > +__no_sanitize_memory
> > > +static inline void *memset_no_sanitize_memory(void *s, int c,
> > > size_t n)
> > > +{
> > > +       return memset(s, c, n);
> > > +}
> >
> > I think depending on the compiler optimizations this might end up
> > being a call to normal memset, that would still change the shadow
> > bytes.
>
> Interesting, do you have some specific scenario in mind? I vaguely
> remember that in the past there were cases when sanitizer annotations
> were lost after inlining, but I thought they were sorted out?

Sanitizer annotations are indeed lost after inlining, and we cannot do
much about that.
They are implemented using function attributes, and if a function
dissolves after inlining, we cannot possibly know which instructions
belonged to it.

Consider the following example (also available at
https://godbolt.org/z/5r7817G8e):

==================================
void *kmalloc(int size);

__attribute__((no_sanitize("kernel-memory")))
__attribute__((always_inline))
static void *memset_nosanitize(void *s, int c, int n) {
  return __builtin_memset(s, c, n);
}

void *do_something_nosanitize(int size) {
  void *ptr = kmalloc(size);
  memset_nosanitize(ptr, 0, size);
  return ptr;
}

void *do_something_sanitize(int size) {
  void *ptr = kmalloc(size);
  __builtin_memset(ptr, 0, size);
  return ptr;
}
==================================

If memset_nosanitize() has __attribute__((always_inline)), the
compiler generates the same LLVM IR calling __msan_memset() for both
do_something_nosanitize() and do_something_sanitize().
If we comment out this attribute, do_something_nosanitize() calls
memset_nosanitize(), which doesn't have the sanitize_memory attribute.

But even now __builtin_memset() is still calling __msan_memset(),
because __attribute__((no_sanitize("kernel-memory"))) somewhat
counterintuitively still preserves some instrumentation (see
include/linux/compiler-clang.h for details).
Replacing __attribute__((no_sanitize("kernel-memory"))) with
__attribute__((disable_sanitizer_instrumentation)) fixes this
situation:

define internal fastcc noundef ptr @memset_nosanitize(void*, int,
int)(ptr noundef returned writeonly %s, i32 noundef %n) unnamed_addr
#2 {
entry:
%conv = sext i32 %n to i64
tail call void @llvm.memset.p0.i64(ptr align 1 %s, i8 0, i64 %conv, i1 false)
ret ptr %s
}

>
> And, in any case, if this were to happen, would not it be considered a
> compiler bug that needs fixing there, and not in the kernel?

As stated above, I don't think this is more or less working as intended.
If we really want the ability to inline __memset(), we could transform
it into memset() in non-sanitizer builds, but perhaps having a call is
also acceptable?


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 04/33] kmsan: Increase the maximum store size to 4096
  2023-11-21 22:00 ` [PATCH v2 04/33] kmsan: Increase the maximum store size to 4096 Ilya Leoshkevich
@ 2023-12-08 16:31   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 16:31 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:07 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> The inline assembly block in s390's chsc() stores that much.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat()
  2023-11-21 22:01 ` [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat() Ilya Leoshkevich
@ 2023-12-08 16:50   ` Alexander Potapenko
  2023-12-13  0:53     ` Ilya Leoshkevich
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 16:50 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Currently KMSAN does not fully propagate metadata in strlcpy() and
> strlcat(), because they are built with -ffreestanding and call
> memcpy(). In this combination memcpy() calls are not instrumented.

Is this something specific to s390?

> Fix by copying the metadata manually. Add the __STDC_HOSTED__ #ifdef in
> case the code is compiled with different flags in the future.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>  lib/string.c | 6 ++++++
>  1 file changed, 6 insertions(+)
>
> diff --git a/lib/string.c b/lib/string.c
> index be26623953d2..e83c6dd77ec6 100644
> --- a/lib/string.c
> +++ b/lib/string.c
> @@ -111,6 +111,9 @@ size_t strlcpy(char *dest, const char *src, size_t size)
>         if (size) {
>                 size_t len = (ret >= size) ? size - 1 : ret;
>                 __builtin_memcpy(dest, src, len);

On x86, I clearly see this __builtin_memcpy() being replaced with
__msan_memcpy().


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 09/33] kmsan: Introduce kmsan_memmove_metadata()
  2023-11-21 22:01 ` [PATCH v2 09/33] kmsan: Introduce kmsan_memmove_metadata() Ilya Leoshkevich
@ 2023-12-08 16:51   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 16:51 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:07 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> It is useful to manually copy metadata in order to describe the effects
> of memmove()-like logic in uninstrumented code or inline asm. Introduce
> kmsan_memmove_metadata() for this purpose.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
>  include/linux/kmsan-checks.h | 14 ++++++++++++++
>  mm/kmsan/hooks.c             | 11 +++++++++++
>  2 files changed, 25 insertions(+)
>
> diff --git a/include/linux/kmsan-checks.h b/include/linux/kmsan-checks.h
> index c4cae333deec..5218973f0ad0 100644
> --- a/include/linux/kmsan-checks.h
> +++ b/include/linux/kmsan-checks.h
> @@ -61,6 +61,17 @@ void kmsan_check_memory(const void *address, size_t size);
>  void kmsan_copy_to_user(void __user *to, const void *from, size_t to_copy,
>                         size_t left);
>
> +/**
> + * kmsan_memmove_metadata() - Copy kernel memory range metadata.
> + * @dst: start of the destination kernel memory range.
> + * @src: start of the source kernel memory range.
> + * @n:   size of the memory ranges.
> + *
> + * KMSAN will treat the destination range as if its contents were memmove()d
> + * from the source range.
> + */
> +void kmsan_memmove_metadata(void *dst, const void *src, size_t n);

As noted in patch 18/33, I am pretty sure we shouldn't need this function.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 23/33] s390/boot: Add the KMSAN runtime stub
  2023-11-21 22:01 ` [PATCH v2 23/33] s390/boot: Add the KMSAN runtime stub Ilya Leoshkevich
@ 2023-12-08 16:56   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-08 16:56 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> It should be possible to have inline functions in the s390 header
> files, which call kmsan_unpoison_memory(). The problem is that these
> header files might be included by the decompressor, which does not
> contain KMSAN runtime, causing linker errors.
>
> Not compiling these calls if __SANITIZE_MEMORY__ is not defined -
> either by changing kmsan-checks.h or at the call sites - may cause
> unintended side effects, since calling these functions from an
> uninstrumented code that is linked into the kernel is valid use case.
>
> One might want to explicitly distinguish between the kernel and the
> decompressor. Checking for a decompressor-specific #define is quite
> heavy-handed, and will have to be done at all call sites.
>
> A more generic approach is to provide a dummy kmsan_unpoison_memory()
> definition. This produces some runtime overhead, but only when building
> with CONFIG_KMSAN. The benefit is that it does not disturb the existing
> KMSAN build logic and call sites don't need to be changed.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 05/33] kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces
  2023-11-21 22:00 ` [PATCH v2 05/33] kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces Ilya Leoshkevich
@ 2023-12-11  9:52   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11  9:52 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Comparing pointers with TASK_SIZE does not make sense when kernel and
> userspace overlap. Skip the comparison when this is the case.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 10/33] kmsan: Expose kmsan_get_metadata()
       [not found] ` <20231121220155.1217090-11-iii@linux.ibm.com>
@ 2023-12-11 10:07   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:07 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

> +static inline void *kmsan_get_metadata(void *addr, bool is_origin)
> +{
> +       return NULL;
> +}
> +
>  #endif

We shouldn't need this part, as kmsan_get_metadata() should never be
called in non-KMSAN builds.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 27/33] s390/mm: Define KMSAN metadata for vmalloc and modules
  2023-11-21 22:01 ` [PATCH v2 27/33] s390/mm: Define KMSAN metadata for vmalloc and modules Ilya Leoshkevich
@ 2023-12-11 10:13   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:13 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:07 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> The pages for the KMSAN metadata associated with most kernel mappings
> are taken from memblock by the common code. However, vmalloc and module
> metadata needs to be defined by the architectures.
>
> Be a little bit more careful than x86: allocate exactly MODULES_LEN
> for the module shadow and origins, and then take 2/3 of vmalloc for
> the vmalloc shadow and origins. This ensures that users passing small
> vmalloc= values on the command line do not cause module metadata
> collisions.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>

(hope some s390 maintainer acks this as well)


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions
  2023-11-21 22:01 ` [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions Ilya Leoshkevich
@ 2023-12-11 10:26   ` Alexander Potapenko
  2023-12-11 10:39     ` Ilya Leoshkevich
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:26 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

> +static inline void *arch_kmsan_get_meta_or_null(void *addr, bool is_origin)
> +{
> +       if (addr >= (void *)&S390_lowcore &&
> +           addr < (void *)(&S390_lowcore + 1)) {
> +               /*
> +                * Different lowcores accessed via S390_lowcore are described
> +                * by the same struct page. Resolve the prefix manually in
> +                * order to get a distinct struct page.
> +                */
> +               addr += (void *)lowcore_ptr[raw_smp_processor_id()] -
> +                       (void *)&S390_lowcore;
> +               return kmsan_get_metadata(addr, is_origin);
> +       }
> +       return NULL;
> +}

Is there a possibility for infinite recursion here? E.g. can
`lowcore_ptr[raw_smp_processor_id()]` point somewhere in between
`(void *)&S390_lowcore` and `(void *)(&S390_lowcore + 1))`?


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 25/33] s390/cpacf: Unpoison the results of cpacf_trng()
  2023-11-21 22:01 ` [PATCH v2 25/33] s390/cpacf: Unpoison the results of cpacf_trng() Ilya Leoshkevich
@ 2023-12-11 10:36   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:36 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Prevent KMSAN from complaining about buffers filled by cpacf_trng()
> being uninitialized.
>
> Tested-by: Alexander Gordeev <agordeev@linux.ibm.com>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions
  2023-12-11 10:26   ` Alexander Potapenko
@ 2023-12-11 10:39     ` Ilya Leoshkevich
  2023-12-11 10:45       ` Alexander Potapenko
  0 siblings, 1 reply; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-12-11 10:39 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Mon, 2023-12-11 at 11:26 +0100, Alexander Potapenko wrote:
> > +static inline void *arch_kmsan_get_meta_or_null(void *addr, bool
> > is_origin)
> > +{
> > +       if (addr >= (void *)&S390_lowcore &&
> > +           addr < (void *)(&S390_lowcore + 1)) {
> > +               /*
> > +                * Different lowcores accessed via S390_lowcore are
> > described
> > +                * by the same struct page. Resolve the prefix
> > manually in
> > +                * order to get a distinct struct page.
> > +                */
> > +               addr += (void *)lowcore_ptr[raw_smp_processor_id()]
> > -
> > +                       (void *)&S390_lowcore;
> > +               return kmsan_get_metadata(addr, is_origin);
> > +       }
> > +       return NULL;
> > +}
> 
> Is there a possibility for infinite recursion here? E.g. can
> `lowcore_ptr[raw_smp_processor_id()]` point somewhere in between
> `(void *)&S390_lowcore` and `(void *)(&S390_lowcore + 1))`?

No, it's allocated with __get_free_pages() or memblock_alloc_low().
But since this question came up, I should probably add a check and
a WARN_ON_ONCE() here.

^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions
  2023-12-11 10:39     ` Ilya Leoshkevich
@ 2023-12-11 10:45       ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:45 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

> > Is there a possibility for infinite recursion here? E.g. can
> > `lowcore_ptr[raw_smp_processor_id()]` point somewhere in between
> > `(void *)&S390_lowcore` and `(void *)(&S390_lowcore + 1))`?
>
> No, it's allocated with __get_free_pages() or memblock_alloc_low().
> But since this question came up, I should probably add a check and
> a WARN_ON_ONCE() here.

Yes, please.


-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Liana Sebastian
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 30/33] s390/uaccess: Add KMSAN support to put_user() and get_user()
  2023-11-21 22:01 ` [PATCH v2 30/33] s390/uaccess: Add KMSAN support to put_user() and get_user() Ilya Leoshkevich
@ 2023-12-11 10:46   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:46 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:03 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> put_user() uses inline assembly with precise constraints, so Clang is
> in principle capable of instrumenting it automatically. Unfortunately,
> one of the constraints contains a dereferenced user pointer, and Clang
> does not currently distinguish user and kernel pointers. Therefore
> KMSAN attempts to access shadow for user pointers, which is not a right
> thing to do.
>
> An obvious fix to add __no_sanitize_memory to __put_user_fn() does not
> work, since it's __always_inline. And __always_inline cannot be removed
> due to the __put_user_bad() trick.
>
> A different obvious fix of using the "a" instead of the "+Q" constraint
> degrades the code quality, which is very important here, since it's a
> hot path.
>
> Instead, repurpose the __put_user_asm() macro to define
> __put_user_{char,short,int,long}_noinstr() functions and mark them with
> __no_sanitize_memory. For the non-KMSAN builds make them
> __always_inline in order to keep the generated code quality. Also
> define __put_user_{char,short,int,long}() functions, which call the
> aforementioned ones and which *are* instrumented, because they call
> KMSAN hooks, which may be implemented as macros.
>
> The same applies to get_user() as well.
>
> Acked-by: Heiko Carstens <hca@linux.ibm.com>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>

I think this patch makes sense, but I don't feel myself qualified
enough to stamp it. Hope Heiko's ack is enough.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 28/33] s390/string: Add KMSAN support
  2023-11-21 22:01 ` [PATCH v2 28/33] s390/string: Add KMSAN support Ilya Leoshkevich
@ 2023-12-11 10:49   ` Alexander Potapenko
  0 siblings, 0 replies; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 10:49 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:03 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Add KMSAN support for the s390 implementations of the string functions.
> Do this similar to how it's already done for KASAN, except that the
> optimized memset{16,32,64}() functions need to be disabled: it's
> important for KMSAN to know that they initialized something.
>
> The way boot code is built with regard to string functions is
> problematic, since most files think it's configured with sanitizers,
> but boot/string.c doesn't. This creates various problems with the
> memset64() definitions, depending on whether the code is built with
> sanitizers or fortify. This should probably be streamlined, but in the
> meantime resolve the issues by introducing the IN_BOOT_STRING_C macro,
> similar to the existing IN_ARCH_STRING_C macro.
>
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Reviewed-by: Alexander Potapenko <glider@google.com>


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task
  2023-11-21 22:01 ` [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task Ilya Leoshkevich
@ 2023-12-11 11:50   ` Alexander Potapenko
  2023-12-13 15:01     ` Ilya Leoshkevich
  0 siblings, 1 reply; 63+ messages in thread
From: Alexander Potapenko @ 2023-12-11 11:50 UTC (permalink / raw)
  To: Ilya Leoshkevich
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Tue, Nov 21, 2023 at 11:06 PM Ilya Leoshkevich <iii@linux.ibm.com> wrote:
>
> Like for KASAN, it's useful to temporarily disable KMSAN checks around,
> e.g., redzone accesses. Introduce kmsan_disable_current() and
> kmsan_enable_current(), which are similar to their KASAN counterparts.

Initially we used to have this disablement counter in KMSAN, but
adding it uncontrollably can result in KMSAN not functioning properly.
E.g. forgetting to call kmsan_disable_current() or underflowing the
counter will break reporting.
We'd better put this API in include/linux/kmsan.h to indicate it
should be discouraged.

> Even though it's not strictly necessary, make them reentrant, in order
> to match the KASAN behavior.

Until this becomes strictly necessary, I think we'd better
KMSAN_WARN_ON if the counter is re-entered.


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat()
  2023-12-08 16:50   ` Alexander Potapenko
@ 2023-12-13  0:53     ` Ilya Leoshkevich
  0 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-12-13  0:53 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Fri, 2023-12-08 at 17:50 +0100, Alexander Potapenko wrote:
> On Tue, Nov 21, 2023 at 11:02 PM Ilya Leoshkevich <iii@linux.ibm.com>
> wrote:
> > 
> > Currently KMSAN does not fully propagate metadata in strlcpy() and
> > strlcat(), because they are built with -ffreestanding and call
> > memcpy(). In this combination memcpy() calls are not instrumented.
> 
> Is this something specific to s390?

Nice catch - I can't reproduce this behavior anymore. Even if I go
back to the clang version that first introduced KMSAN on s390x, the
memset() instrumentation with -ffreestanding is still there. I should
have written down more detailed notes after investigating this, but
here we are. I will drop this patch as well as 10/33.

[...]


^ permalink raw reply	[flat|nested] 63+ messages in thread

* Re: [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task
  2023-12-11 11:50   ` Alexander Potapenko
@ 2023-12-13 15:01     ` Ilya Leoshkevich
  0 siblings, 0 replies; 63+ messages in thread
From: Ilya Leoshkevich @ 2023-12-13 15:01 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: Alexander Gordeev, Andrew Morton, Christoph Lameter,
	David Rientjes, Heiko Carstens, Joonsoo Kim, Marco Elver,
	Masami Hiramatsu, Pekka Enberg, Steven Rostedt, Vasily Gorbik,
	Vlastimil Babka, Christian Borntraeger, Dmitry Vyukov,
	Hyeonggon Yoo, kasan-dev, linux-kernel, linux-mm, linux-s390,
	linux-trace-kernel, Mark Rutland, Roman Gushchin, Sven Schnelle

On Mon, 2023-12-11 at 12:50 +0100, Alexander Potapenko wrote:
> On Tue, Nov 21, 2023 at 11:06 PM Ilya Leoshkevich <iii@linux.ibm.com>
> wrote:
> > 
> > Like for KASAN, it's useful to temporarily disable KMSAN checks
> > around,
> > e.g., redzone accesses. Introduce kmsan_disable_current() and
> > kmsan_enable_current(), which are similar to their KASAN
> > counterparts.
> 
> Initially we used to have this disablement counter in KMSAN, but
> adding it uncontrollably can result in KMSAN not functioning
> properly.
> E.g. forgetting to call kmsan_disable_current() or underflowing the
> counter will break reporting.
> We'd better put this API in include/linux/kmsan.h to indicate it
> should be discouraged.
> 
> > Even though it's not strictly necessary, make them reentrant, in
> > order
> > to match the KASAN behavior.
> 
> Until this becomes strictly necessary, I think we'd better
> KMSAN_WARN_ON if the counter is re-entered.

I encountered a case when we are freeing memory from an interrupt
handler:

[  149.840553] ------------[ cut here ]------------                   
[  149.840649] WARNING: CPU: 1 PID: 181 at mm/kmsan/hooks.c:447
kmsan_disable_current+0x2e/0x40                                       
[  149.840790] Modules linked in:                                     
[  149.840894] CPU: 1 PID: 181 Comm: (direxec) Tainted: G    B   W    
N 6.7.0-rc5-gd34a4b46f382 #13
[  149.841003] Hardware name: IBM 3931 A01 704 (KVM/Linux)     
[  149.841094] Krnl PSW : 0404c00180000000 000000000197dbc2
(kmsan_disable_current+0x32/0x40)
[  149.841276]            R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:0
PM:0 RI:0 EA:3
[  149.841420] Krnl GPRS: 0000000000000040 0000000096914100
0000000000001000 0000000000000001
[  149.841518]            0000036d827daee0 0000000007c97008
0000000080096500 0000000092f4f000
[  149.841617]            0000036d00000000 0000000000000000
0000000000000040 0000000000000000
[  149.841712]            0000000092f4efc0 00000001ff710f60
000000000193acba 0000037f0008f710
[  149.841893] Krnl Code: 000000000197dbb6: eb0018640352        mviy  
14436(%r1),0
[  149.841893]            000000000197dbbc: 07fe                bcr   
15,%r14
[  149.841893]           #000000000197dbbe: af000000            mc    
0,0
[  149.841893]           >000000000197dbc2: a7f4fffa            brc   
15,000000000197dbb6
[  149.841893]            000000000197dbc6: 0700                bcr   
0,%r0
[  149.841893]            000000000197dbc8: 0700                bcr   
0,%r0
[  149.841893]            000000000197dbca: 0700                bcr   
0,%r0
[  149.841893]            000000000197dbcc: 0700                bcr   
0,%r0
[  149.842438] Call Trace:                                            
15:37:25 [90/1838]
[  149.842510]  [<000000000197dbc2>] kmsan_disable_current+0x32/0x40 
[  149.842631] ([<000000000193ac14>] slab_pad_check+0x1d4/0xac0)
[  149.842738]  [<0000000001949222>] free_to_partial_list+0x1d72/0x3b80
[  149.842850]  [<0000000001947066>] __slab_free+0xd86/0x11d0 
[  149.842956]  [<00000000019111e8>] kmem_cache_free+0x15d8/0x25d0 
[  149.843062]  [<0000000000229e3a>] __tlb_remove_table+0x20a/0xa50 
[  149.843174]  [<00000000016c7f98>] tlb_remove_table_rcu+0x98/0x120 
[  149.843291]  [<000000000083e1c6>] rcu_core+0x15b6/0x54b0 
[  149.843406]  [<00000000069c3c0e>] __do_softirq+0xa1e/0x2178 
[  149.843514]  [<00000000003467b4>] irq_exit_rcu+0x2c4/0x630 
[  149.843623]  [<0000000006949f6e>] do_ext_irq+0x9e/0x120 
[  149.843736]  [<00000000069c18d4>] ext_int_handler+0xc4/0xf0 
[  149.843841]  [<000000000197e428>] kmsan_get_metadata+0x68/0x280 
[  149.843950]  [<000000000197e344>]
kmsan_get_shadow_origin_ptr+0x74/0xf0 
[  149.844071]  [<000000000197ba3a>]
__msan_metadata_ptr_for_load_8+0x2a/0x40 
[  149.844192]  [<0000000000184e4a>]
unwind_get_return_address+0xda/0x150 
[  149.844313]  [<000000000018fd12>] arch_stack_walk+0x172/0x2f0 
[  149.844417]  [<00000000008f1af0>] stack_trace_save+0x100/0x160 
[  149.844529]  [<000000000197af22>]
kmsan_internal_chain_origin+0x62/0xe0 
[  149.844647]  [<000000000197c1f0>] __msan_chain_origin+0xd0/0x160 
[  149.844763]  [<00000000068b3ba4>] memchr_inv+0x5b4/0xb20 
[  149.844877]  [<000000000193e730>] check_bytes_and_report+0xa0/0xd30 
[  149.844986]  [<000000000193b920>] check_object+0x420/0x17d0 
[  149.845092]  [<000000000194aa8a>] free_to_partial_list+0x35da/0x3b80
[  149.845202]  [<0000000001947066>] __slab_free+0xd86/0x11d0 
[  149.845308]  [<00000000019111e8>] kmem_cache_free+0x15d8/0x25d0 
[  149.845414]  [<00000000016bc2fe>] exit_mmap+0x87e/0x1200 
[  149.845524]  [<00000000002f315c>] mmput+0x13c/0x5b0 
[  149.845632]  [<0000000001b9d634>] exec_mmap+0xc34/0x1230 
[  149.845744]  [<0000000001b996c2>] begin_new_exec+0xcf2/0x2520 
[  149.845857]  [<0000000001f6a084>] load_elf_binary+0x2364/0x67d0 
[  149.845971]  [<0000000001ba5ba4>] bprm_execve+0x25b4/0x4010 
[  149.846083]  [<0000000001baa7e6>] do_execveat_common+0x2436/0x2600 
[  149.846200]  [<0000000001ba78f8>] __s390x_sys_execve+0x108/0x140 
[  149.846314]  [<000000000011b192>] do_syscall+0x4c2/0x690 
[  149.846424]  [<0000000006949d78>] __do_syscall+0x98/0xe0 
[  149.846536]  [<00000000069c1640>] system_call+0x70/0xa0 
[  149.846638] INFO: lockdep is turned off.
[  149.846846] Last Breaking-Event-Address:
[  149.846916]  [<000000000197dbb2>] kmsan_disable_current+0x22/0x40
[  149.847057] irq event stamp: 0
[  149.847128] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
[  149.847227] hardirqs last disabled at (0): [<00000000002f8f46>]
copy_process+0x21f6/0x8b20
[  149.847344] softirqs last  enabled at (0): [<00000000002f8f80>]
copy_process+0x2230/0x8b20
[  149.847461] softirqs last disabled at (0): [<0000000000000000>] 0x0
[  149.847559] ---[ end trace 0000000000000000 ]---
[  149.865485] =====================================================

Using a counter resolves this issue, but, of course, at the expense of
not reporting valid issues in the interrupt handler.

Unfortunately I don't see another easy way to solve this problem. The
possibilities that come to mind are providing uninstrumented
memchr_inv() or disablement flags for each context, but I'm not sure if
we want to go there, especially since KASAN already has this
limitation.


^ permalink raw reply	[flat|nested] 63+ messages in thread

end of thread, other threads:[~2023-12-13 15:02 UTC | newest]

Thread overview: 63+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-21 22:00 [PATCH v2 00/33] kmsan: Enable on s390 Ilya Leoshkevich
2023-11-21 22:00 ` [PATCH v2 01/33] ftrace: Unpoison ftrace_regs in ftrace_ops_list_func() Ilya Leoshkevich
2023-11-22 23:32   ` Steven Rostedt
2023-12-08 14:16   ` Alexander Potapenko
2023-12-08 14:31     ` Steven Rostedt
2023-11-21 22:00 ` [PATCH v2 02/33] kmsan: Make the tests compatible with kmsan.panic=1 Ilya Leoshkevich
2023-11-21 22:00 ` [PATCH v2 03/33] kmsan: Disable KMSAN when DEFERRED_STRUCT_PAGE_INIT is enabled Ilya Leoshkevich
2023-11-21 22:00 ` [PATCH v2 04/33] kmsan: Increase the maximum store size to 4096 Ilya Leoshkevich
2023-12-08 16:31   ` Alexander Potapenko
2023-11-21 22:00 ` [PATCH v2 05/33] kmsan: Fix is_bad_asm_addr() on arches with overlapping address spaces Ilya Leoshkevich
2023-12-11  9:52   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 08/33] kmsan: Remove an x86-specific #include from kmsan.h Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 09/33] kmsan: Introduce kmsan_memmove_metadata() Ilya Leoshkevich
2023-12-08 16:51   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 11/33] kmsan: Export panic_on_kmsan Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 12/33] kmsan: Allow disabling KMSAN checks for the current task Ilya Leoshkevich
2023-12-11 11:50   ` Alexander Potapenko
2023-12-13 15:01     ` Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 13/33] kmsan: Introduce memset_no_sanitize_memory() Ilya Leoshkevich
2023-12-08 13:48   ` Alexander Potapenko
     [not found]     ` <69e7bc8e8c8a38c429a793e991e0509cb97a53e1.camel@linux.ibm.com>
2023-12-08 15:25       ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 14/33] kmsan: Support SLAB_POISON Ilya Leoshkevich
2023-12-08 13:51   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 15/33] kmsan: Use ALIGN_DOWN() in kmsan_get_metadata() Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 16/33] mm: slub: Let KMSAN access metadata Ilya Leoshkevich
2023-11-30 15:26   ` Vlastimil Babka
2023-11-21 22:01 ` [PATCH v2 17/33] mm: kfence: Disable KMSAN when checking the canary Ilya Leoshkevich
2023-12-08 12:53   ` Alexander Potapenko
2023-12-08 13:55     ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 18/33] lib/string: Add KMSAN support to strlcpy() and strlcat() Ilya Leoshkevich
2023-12-08 16:50   ` Alexander Potapenko
2023-12-13  0:53     ` Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 19/33] lib/zlib: Unpoison DFLTCC output buffers Ilya Leoshkevich
2023-12-08 13:32   ` Alexander Potapenko
2023-12-08 14:14     ` Ilya Leoshkevich
2023-12-08 14:25       ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 20/33] kmsan: Accept ranges starting with 0 on s390 Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 21/33] s390: Turn off KMSAN for boot, vdso and purgatory Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 22/33] s390: Use a larger stack for KMSAN Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 23/33] s390/boot: Add the KMSAN runtime stub Ilya Leoshkevich
2023-12-08 16:56   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 24/33] s390/checksum: Add a KMSAN check Ilya Leoshkevich
2023-12-08 13:38   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 25/33] s390/cpacf: Unpoison the results of cpacf_trng() Ilya Leoshkevich
2023-12-11 10:36   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 26/33] s390/ftrace: Unpoison ftrace_regs in kprobe_ftrace_handler() Ilya Leoshkevich
2023-12-08 14:18   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 27/33] s390/mm: Define KMSAN metadata for vmalloc and modules Ilya Leoshkevich
2023-12-11 10:13   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 28/33] s390/string: Add KMSAN support Ilya Leoshkevich
2023-12-11 10:49   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 29/33] s390/traps: Unpoison the kernel_stack_overflow()'s pt_regs Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 30/33] s390/uaccess: Add KMSAN support to put_user() and get_user() Ilya Leoshkevich
2023-12-11 10:46   ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 31/33] s390/unwind: Disable KMSAN checks Ilya Leoshkevich
2023-11-21 22:01 ` [PATCH v2 32/33] s390: Implement the architecture-specific kmsan functions Ilya Leoshkevich
2023-12-11 10:26   ` Alexander Potapenko
2023-12-11 10:39     ` Ilya Leoshkevich
2023-12-11 10:45       ` Alexander Potapenko
2023-11-21 22:01 ` [PATCH v2 33/33] kmsan: Enable on s390 Ilya Leoshkevich
2023-11-29  9:19   ` Alexander Potapenko
2023-11-29  9:58     ` Ilya Leoshkevich
     [not found] ` <20231121220155.1217090-11-iii@linux.ibm.com>
2023-12-11 10:07   ` [PATCH v2 10/33] kmsan: Expose kmsan_get_metadata() Alexander Potapenko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).