linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/5] mm: kmsan: export kmsan_copy_page_meta()
@ 2022-10-24 21:21 Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 2/5] x86/purgatory: disable KMSAN instrumentation Alexander Potapenko
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Alexander Potapenko @ 2022-10-24 21:21 UTC (permalink / raw)
  To: glider; +Cc: linux-kernel, linux-mm, Andrew Morton

Certain modules call copy_user_highpage(), which calls
kmsan_copy_page_meta() under KMSAN, so we need to export the latter.

Cc: Andrew Morton <akpm@linux-foundation.org>
Fixes: b073d7f8aee4 ("mm: kmsan: maintain KMSAN metadata for page operations")
Link: https://github.com/google/kmsan/issues/89
Signed-off-by: Alexander Potapenko <glider@google.com>
---
 mm/kmsan/shadow.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/kmsan/shadow.c b/mm/kmsan/shadow.c
index 21e3e196ec3cf..a787c04e9583c 100644
--- a/mm/kmsan/shadow.c
+++ b/mm/kmsan/shadow.c
@@ -167,6 +167,7 @@ void kmsan_copy_page_meta(struct page *dst, struct page *src)
 	__memcpy(origin_ptr_for(dst), origin_ptr_for(src), PAGE_SIZE);
 	kmsan_leave_runtime();
 }
+EXPORT_SYMBOL(kmsan_copy_page_meta);
 
 void kmsan_alloc_page(struct page *page, unsigned int order, gfp_t flags)
 {
-- 
2.38.0.135.g90850a2211-goog



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

* [PATCH 2/5] x86/purgatory: disable KMSAN instrumentation
  2022-10-24 21:21 [PATCH 1/5] mm: kmsan: export kmsan_copy_page_meta() Alexander Potapenko
@ 2022-10-24 21:21 ` Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default Alexander Potapenko
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Alexander Potapenko @ 2022-10-24 21:21 UTC (permalink / raw)
  To: glider
  Cc: linux-kernel, linux-mm, Andrew Morton, Thomas Gleixner, Ingo Molnar, x86

The stand-alone purgatory.ro does not contain the KMSAN runtime,
therefore it can't be built with KMSAN compiler instrumentation.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: x86@kernel.org
Link: https://github.com/google/kmsan/issues/89
Signed-off-by: Alexander Potapenko <glider@google.com>
---
 arch/x86/purgatory/Makefile | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 58a200dc762d6..17f09dc263811 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -26,6 +26,7 @@ GCOV_PROFILE	:= n
 KASAN_SANITIZE	:= n
 UBSAN_SANITIZE	:= n
 KCSAN_SANITIZE	:= n
+KMSAN_SANITIZE	:= n
 KCOV_INSTRUMENT := n
 
 # These are adjustments to the compiler flags used for objects that
-- 
2.38.0.135.g90850a2211-goog



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

* [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default
  2022-10-24 21:21 [PATCH 1/5] mm: kmsan: export kmsan_copy_page_meta() Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 2/5] x86/purgatory: disable KMSAN instrumentation Alexander Potapenko
@ 2022-10-24 21:21 ` Alexander Potapenko
  2022-10-27 14:31   ` Masahiro Yamada
  2022-10-24 21:21 ` [PATCH 4/5] x86: asm: make sure __put_user_size() evaluates pointer once Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 5/5] x86: fortify: kmsan: fix KMSAN fortify builds Alexander Potapenko
  3 siblings, 1 reply; 7+ messages in thread
From: Alexander Potapenko @ 2022-10-24 21:21 UTC (permalink / raw)
  To: glider
  Cc: linux-kernel, linux-mm, Andrew Morton, Kees Cook,
	Masahiro Yamada, Nick Desaulniers, linux-kbuild

KMSAN adds a lot of instrumentation to the code, which results in
increased stack usage (up to 2048 bytes and more in some cases).
It's hard to predict how big the stack frames can be, so we disable
the warnings for KMSAN instead.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Kees Cook <keescook@chromium.org>
Cc: Masahiro Yamada <masahiroy@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: linux-kbuild@vger.kernel.org
Link: https://github.com/google/kmsan/issues/89
Signed-off-by: Alexander Potapenko <glider@google.com>
---
 lib/Kconfig.debug | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 3fc7abffc7aa2..29280072dc0e4 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -400,8 +400,9 @@ config FRAME_WARN
 	default 1536 if (!64BIT && XTENSA)
 	default 1024 if !64BIT
 	default 2048 if 64BIT
+	default 0 if KMSAN
 	help
-	  Tell gcc to warn at build time for stack frames larger than this.
+	  Tell the compiler to warn at build time for stack frames larger than this.
 	  Setting this too low will cause a lot of warnings.
 	  Setting it to 0 disables the warning.
 
-- 
2.38.0.135.g90850a2211-goog



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

* [PATCH 4/5] x86: asm: make sure __put_user_size() evaluates pointer once
  2022-10-24 21:21 [PATCH 1/5] mm: kmsan: export kmsan_copy_page_meta() Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 2/5] x86/purgatory: disable KMSAN instrumentation Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default Alexander Potapenko
@ 2022-10-24 21:21 ` Alexander Potapenko
  2022-10-24 21:21 ` [PATCH 5/5] x86: fortify: kmsan: fix KMSAN fortify builds Alexander Potapenko
  3 siblings, 0 replies; 7+ messages in thread
From: Alexander Potapenko @ 2022-10-24 21:21 UTC (permalink / raw)
  To: glider
  Cc: linux-kernel, linux-mm, Andrew Morton, Borislav Petkov,
	Ingo Molnar, Thomas Gleixner, x86, youling257

User access macros must ensure their arguments are evaluated only once
if they are used more than once in the macro body. Adding
instrument_put_user() to __put_user_size() resulted in double evaluation
of the `ptr` argument, which led to correctness issues when performing
e.g. unsafe_put_user(..., p++, ...).
To fix those issues, evaluate the `ptr` argument of __put_user_size()
at the beginning of the macro.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: x86@kernel.org
Reported-by: youling257 <youling257@gmail.com>
Signed-off-by: Alexander Potapenko <glider@google.com>
Fixes: 888f84a6da4d ("x86: asm: instrument usercopy in get_user() and put_user()")
---
 arch/x86/include/asm/uaccess.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index 8bc614cfe21b9..1cc756eafa447 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -254,24 +254,25 @@ extern void __put_user_nocheck_8(void);
 #define __put_user_size(x, ptr, size, label)				\
 do {									\
 	__typeof__(*(ptr)) __x = (x); /* eval x once */			\
-	__chk_user_ptr(ptr);						\
+	__typeof__(ptr) __ptr = (ptr); /* eval ptr once */		\
+	__chk_user_ptr(__ptr);						\
 	switch (size) {							\
 	case 1:								\
-		__put_user_goto(__x, ptr, "b", "iq", label);		\
+		__put_user_goto(__x, __ptr, "b", "iq", label);		\
 		break;							\
 	case 2:								\
-		__put_user_goto(__x, ptr, "w", "ir", label);		\
+		__put_user_goto(__x, __ptr, "w", "ir", label);		\
 		break;							\
 	case 4:								\
-		__put_user_goto(__x, ptr, "l", "ir", label);		\
+		__put_user_goto(__x, __ptr, "l", "ir", label);		\
 		break;							\
 	case 8:								\
-		__put_user_goto_u64(__x, ptr, label);			\
+		__put_user_goto_u64(__x, __ptr, label);			\
 		break;							\
 	default:							\
 		__put_user_bad();					\
 	}								\
-	instrument_put_user(__x, ptr, size);				\
+	instrument_put_user(__x, __ptr, size);				\
 } while (0)
 
 #ifdef CONFIG_CC_HAS_ASM_GOTO_OUTPUT
-- 
2.38.0.135.g90850a2211-goog



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

* [PATCH 5/5] x86: fortify: kmsan: fix KMSAN fortify builds
  2022-10-24 21:21 [PATCH 1/5] mm: kmsan: export kmsan_copy_page_meta() Alexander Potapenko
                   ` (2 preceding siblings ...)
  2022-10-24 21:21 ` [PATCH 4/5] x86: asm: make sure __put_user_size() evaluates pointer once Alexander Potapenko
@ 2022-10-24 21:21 ` Alexander Potapenko
  3 siblings, 0 replies; 7+ messages in thread
From: Alexander Potapenko @ 2022-10-24 21:21 UTC (permalink / raw)
  To: glider
  Cc: linux-kernel, linux-mm, Andrew Morton, Nathan Chancellor,
	Nick Desaulniers, Kees Cook, Tamas K Lengyel

Ensure that KMSAN builds replace memset/memcpy/memmove calls with the
respective __msan_XXX functions, and that none of the macros are
redefined twice. This should allow building kernel with both
CONFIG_KMSAN and CONFIG_FORTIFY_SOURCE.

Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Nathan Chancellor <nathan@kernel.org>
Cc: Nick Desaulniers <ndesaulniers@google.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: linux-mm@kvack.org
Reported-by: Tamas K Lengyel <tamas.lengyel@zentific.com>
Link: https://github.com/google/kmsan/issues/89
Signed-off-by: Alexander Potapenko <glider@google.com>
---
 arch/x86/include/asm/string_64.h | 11 +++++++----
 include/linux/fortify-string.h   | 17 +++++++++++++++--
 include/linux/kmsan_string.h     | 21 +++++++++++++++++++++
 mm/kmsan/instrumentation.c       |  1 +
 4 files changed, 44 insertions(+), 6 deletions(-)
 create mode 100644 include/linux/kmsan_string.h

diff --git a/arch/x86/include/asm/string_64.h b/arch/x86/include/asm/string_64.h
index 3b87d889b6e16..888731ccf1f67 100644
--- a/arch/x86/include/asm/string_64.h
+++ b/arch/x86/include/asm/string_64.h
@@ -10,10 +10,13 @@
 /* Even with __builtin_ the compiler may decide to use the out of line
    function. */
 
+#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
+#include <linux/kmsan_string.h>
+#endif
+
 #define __HAVE_ARCH_MEMCPY 1
-#if defined(__SANITIZE_MEMORY__)
+#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
 #undef memcpy
-void *__msan_memcpy(void *dst, const void *src, size_t size);
 #define memcpy __msan_memcpy
 #else
 extern void *memcpy(void *to, const void *from, size_t len);
@@ -21,7 +24,7 @@ extern void *memcpy(void *to, const void *from, size_t len);
 extern void *__memcpy(void *to, const void *from, size_t len);
 
 #define __HAVE_ARCH_MEMSET
-#if defined(__SANITIZE_MEMORY__)
+#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
 extern void *__msan_memset(void *s, int c, size_t n);
 #undef memset
 #define memset __msan_memset
@@ -67,7 +70,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t n)
 }
 
 #define __HAVE_ARCH_MEMMOVE
-#if defined(__SANITIZE_MEMORY__)
+#if defined(__SANITIZE_MEMORY__) && defined(__NO_FORTIFY)
 #undef memmove
 void *__msan_memmove(void *dest, const void *src, size_t len);
 #define memmove __msan_memmove
diff --git a/include/linux/fortify-string.h b/include/linux/fortify-string.h
index 4029fe368a4f6..18a31b125f9d6 100644
--- a/include/linux/fortify-string.h
+++ b/include/linux/fortify-string.h
@@ -43,11 +43,24 @@ extern __kernel_size_t __underlying_strlen(const char *p) __RENAME(strlen);
 extern char *__underlying_strncat(char *p, const char *q, __kernel_size_t count) __RENAME(strncat);
 extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy);
 #else
-#define __underlying_memchr	__builtin_memchr
-#define __underlying_memcmp	__builtin_memcmp
+
+#if defined(__SANITIZE_MEMORY__)
+/*
+ * For KMSAN builds all memcpy/memset/memmove calls should be replaced by the
+ * corresponding __msan_XXX functions.
+ */
+#include <linux/kmsan_string.h>
+#define __underlying_memcpy	__msan_memcpy
+#define __underlying_memmove	__msan_memmove
+#define __underlying_memset	__msan_memset
+#else
 #define __underlying_memcpy	__builtin_memcpy
 #define __underlying_memmove	__builtin_memmove
 #define __underlying_memset	__builtin_memset
+#endif
+
+#define __underlying_memchr	__builtin_memchr
+#define __underlying_memcmp	__builtin_memcmp
 #define __underlying_strcat	__builtin_strcat
 #define __underlying_strcpy	__builtin_strcpy
 #define __underlying_strlen	__builtin_strlen
diff --git a/include/linux/kmsan_string.h b/include/linux/kmsan_string.h
new file mode 100644
index 0000000000000..7287da6f52eff
--- /dev/null
+++ b/include/linux/kmsan_string.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * KMSAN string functions API used in other headers.
+ *
+ * Copyright (C) 2022 Google LLC
+ * Author: Alexander Potapenko <glider@google.com>
+ *
+ */
+#ifndef _LINUX_KMSAN_STRING_H
+#define _LINUX_KMSAN_STRING_H
+
+/*
+ * KMSAN overrides the default memcpy/memset/memmove implementations in the
+ * kernel, which requires having __msan_XXX function prototypes in several other
+ * headers. Keep them in one place instead of open-coding.
+ */
+void *__msan_memcpy(void *dst, const void *src, size_t size);
+void *__msan_memset(void *s, int c, size_t n);
+void *__msan_memmove(void *dest, const void *src, size_t len);
+
+#endif /* _LINUX_KMSAN_STRING_H */
diff --git a/mm/kmsan/instrumentation.c b/mm/kmsan/instrumentation.c
index 280d154132684..271f135f97a16 100644
--- a/mm/kmsan/instrumentation.c
+++ b/mm/kmsan/instrumentation.c
@@ -14,6 +14,7 @@
 
 #include "kmsan.h"
 #include <linux/gfp.h>
+#include <linux/kmsan_string.h>
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 
-- 
2.38.0.135.g90850a2211-goog



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

* Re: [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default
  2022-10-24 21:21 ` [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default Alexander Potapenko
@ 2022-10-27 14:31   ` Masahiro Yamada
  2022-10-27 16:41     ` Alexander Potapenko
  0 siblings, 1 reply; 7+ messages in thread
From: Masahiro Yamada @ 2022-10-27 14:31 UTC (permalink / raw)
  To: Alexander Potapenko
  Cc: linux-kernel, linux-mm, Andrew Morton, Kees Cook,
	Nick Desaulniers, linux-kbuild

On Tue, Oct 25, 2022 at 6:22 AM Alexander Potapenko <glider@google.com> wrote:
>
> KMSAN adds a lot of instrumentation to the code, which results in
> increased stack usage (up to 2048 bytes and more in some cases).
> It's hard to predict how big the stack frames can be, so we disable
> the warnings for KMSAN instead.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Masahiro Yamada <masahiroy@kernel.org>
> Cc: Nick Desaulniers <ndesaulniers@google.com>
> Cc: linux-kbuild@vger.kernel.org
> Link: https://github.com/google/kmsan/issues/89
> Signed-off-by: Alexander Potapenko <glider@google.com>
> ---
>  lib/Kconfig.debug | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> index 3fc7abffc7aa2..29280072dc0e4 100644
> --- a/lib/Kconfig.debug
> +++ b/lib/Kconfig.debug
> @@ -400,8 +400,9 @@ config FRAME_WARN
>         default 1536 if (!64BIT && XTENSA)
>         default 1024 if !64BIT
>         default 2048 if 64BIT
> +       default 0 if KMSAN



This is wrong.

Kconfig picks up the first default entry which has
true 'if' condition.


Since (!64BIT || 64BIT) covers all the possible cases,
this patch is just adding dead code.







>         help
> -         Tell gcc to warn at build time for stack frames larger than this.
> +         Tell the compiler to warn at build time for stack frames larger than this.
>           Setting this too low will cause a lot of warnings.
>           Setting it to 0 disables the warning.
>
> --
> 2.38.0.135.g90850a2211-goog
>


-- 
Best Regards
Masahiro Yamada


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

* Re: [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default
  2022-10-27 14:31   ` Masahiro Yamada
@ 2022-10-27 16:41     ` Alexander Potapenko
  0 siblings, 0 replies; 7+ messages in thread
From: Alexander Potapenko @ 2022-10-27 16:41 UTC (permalink / raw)
  To: Masahiro Yamada
  Cc: linux-kernel, linux-mm, Andrew Morton, Kees Cook,
	Nick Desaulniers, linux-kbuild

On Thu, Oct 27, 2022 at 7:33 AM Masahiro Yamada <masahiroy@kernel.org> wrote:
>
> On Tue, Oct 25, 2022 at 6:22 AM Alexander Potapenko <glider@google.com> wrote:
> >
> > KMSAN adds a lot of instrumentation to the code, which results in
> > increased stack usage (up to 2048 bytes and more in some cases).
> > It's hard to predict how big the stack frames can be, so we disable
> > the warnings for KMSAN instead.
> >
> > Cc: Andrew Morton <akpm@linux-foundation.org>
> > Cc: Kees Cook <keescook@chromium.org>
> > Cc: Masahiro Yamada <masahiroy@kernel.org>
> > Cc: Nick Desaulniers <ndesaulniers@google.com>
> > Cc: linux-kbuild@vger.kernel.org
> > Link: https://github.com/google/kmsan/issues/89
> > Signed-off-by: Alexander Potapenko <glider@google.com>
> > ---
> >  lib/Kconfig.debug | 3 ++-
> >  1 file changed, 2 insertions(+), 1 deletion(-)
> >
> > diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
> > index 3fc7abffc7aa2..29280072dc0e4 100644
> > --- a/lib/Kconfig.debug
> > +++ b/lib/Kconfig.debug
> > @@ -400,8 +400,9 @@ config FRAME_WARN
> >         default 1536 if (!64BIT && XTENSA)
> >         default 1024 if !64BIT
> >         default 2048 if 64BIT
> > +       default 0 if KMSAN
>
>
>
> This is wrong.
>
> Kconfig picks up the first default entry which has
> true 'if' condition.
>
>
> Since (!64BIT || 64BIT) covers all the possible cases,
> this patch is just adding dead code.
>
Thanks for clarifying!
What we actually need is to forcefully disable CONFIG_FRAME_WARN under
KMSAN, but adding constructs like "select FRAME_WARN 0" or "select
FRAME_WARN=0" doesn't work, right?

I'll move "default 0 if KMSAN" to the beginning of FRAME_WARN declaration then.

>
>
>
>
>
> >         help
> > -         Tell gcc to warn at build time for stack frames larger than this.
> > +         Tell the compiler to warn at build time for stack frames larger than this.
> >           Setting this too low will cause a lot of warnings.
> >           Setting it to 0 disables the warning.
> >
> > --
> > 2.38.0.135.g90850a2211-goog
> >
>
>
> --
> Best Regards
> Masahiro Yamada



-- 
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] 7+ messages in thread

end of thread, other threads:[~2022-10-27 16:42 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-24 21:21 [PATCH 1/5] mm: kmsan: export kmsan_copy_page_meta() Alexander Potapenko
2022-10-24 21:21 ` [PATCH 2/5] x86/purgatory: disable KMSAN instrumentation Alexander Potapenko
2022-10-24 21:21 ` [PATCH 3/5] Kconfig.debug: disable CONFIG_FRAME_WARN for KMSAN by default Alexander Potapenko
2022-10-27 14:31   ` Masahiro Yamada
2022-10-27 16:41     ` Alexander Potapenko
2022-10-24 21:21 ` [PATCH 4/5] x86: asm: make sure __put_user_size() evaluates pointer once Alexander Potapenko
2022-10-24 21:21 ` [PATCH 5/5] x86: fortify: kmsan: fix KMSAN fortify builds 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).