diff mbox series

[09/43] kmsan: introduce __no_sanitize_memory and __no_kmsan_checks

Message ID 20211214162050.660953-10-glider@google.com (mailing list archive)
State New
Headers show
Series Add KernelMemorySanitizer infrastructure | expand

Commit Message

Alexander Potapenko Dec. 14, 2021, 4:20 p.m. UTC
__no_sanitize_memory is a function attribute that instructs KMSAN to
skip a function during instrumentation. This is needed to e.g. implement
the noinstr functions.

__no_kmsan_checks is a function attribute that makes KMSAN
ignore the uninitialized values coming from the function's
inputs, and initialize the function's outputs.

Functions marked with this attribute can't be inlined into functions
not marked with it, and vice versa.

__SANITIZE_MEMORY__ is a macro that's defined iff the file is
instrumented with KMSAN. This is not the same as CONFIG_KMSAN, which is
defined for every file.

Signed-off-by: Alexander Potapenko <glider@google.com>
---
Link: https://linux-review.googlesource.com/id/I004ff0360c918d3cd8b18767ddd1381c6d3281be
---
 include/linux/compiler-clang.h | 23 +++++++++++++++++++++++
 include/linux/compiler-gcc.h   |  6 ++++++
 2 files changed, 29 insertions(+)

Comments

Mark Rutland Dec. 15, 2021, 1:27 p.m. UTC | #1
On Tue, Dec 14, 2021 at 05:20:16PM +0100, Alexander Potapenko wrote:
> __no_sanitize_memory is a function attribute that instructs KMSAN to
> skip a function during instrumentation. This is needed to e.g. implement
> the noinstr functions.
> 
> __no_kmsan_checks is a function attribute that makes KMSAN
> ignore the uninitialized values coming from the function's
> inputs, and initialize the function's outputs.
> 
> Functions marked with this attribute can't be inlined into functions
> not marked with it, and vice versa.

Just to check, I assume an unmarked __always_inline() function can be inlined
into a marked function? Otherwise this is going to be really painful to manage
for low-level helper functions.

Thanks,
Mark.

> 
> __SANITIZE_MEMORY__ is a macro that's defined iff the file is
> instrumented with KMSAN. This is not the same as CONFIG_KMSAN, which is
> defined for every file.
> 
> Signed-off-by: Alexander Potapenko <glider@google.com>
> ---
> Link: https://linux-review.googlesource.com/id/I004ff0360c918d3cd8b18767ddd1381c6d3281be
> ---
>  include/linux/compiler-clang.h | 23 +++++++++++++++++++++++
>  include/linux/compiler-gcc.h   |  6 ++++++
>  2 files changed, 29 insertions(+)
> 
> diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
> index 3c4de9b6c6e3e..5f11a6f269e28 100644
> --- a/include/linux/compiler-clang.h
> +++ b/include/linux/compiler-clang.h
> @@ -51,6 +51,29 @@
>  #define __no_sanitize_undefined
>  #endif
>  
> +#if __has_feature(memory_sanitizer)
> +#define __SANITIZE_MEMORY__
> +/*
> + * Unlike other sanitizers, KMSAN still inserts code into functions marked with
> + * no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation
> + * provides the behavior consistent with other __no_sanitize_ attributes,
> + * guaranteeing that __no_sanitize_memory functions remain uninstrumented.
> + */
> +#define __no_sanitize_memory __disable_sanitizer_instrumentation
> +
> +/*
> + * The __no_kmsan_checks attribute ensures that a function does not produce
> + * false positive reports by:
> + *  - initializing all local variables and memory stores in this function;
> + *  - skipping all shadow checks;
> + *  - passing initialized arguments to this function's callees.
> + */
> +#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory")))
> +#else
> +#define __no_sanitize_memory
> +#define __no_kmsan_checks
> +#endif
> +
>  /*
>   * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together
>   * with no_sanitize("coverage"). Prior versions of Clang support coverage
> diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
> index ccbbd31b3aae5..f6e69387aad05 100644
> --- a/include/linux/compiler-gcc.h
> +++ b/include/linux/compiler-gcc.h
> @@ -129,6 +129,12 @@
>  #define __SANITIZE_ADDRESS__
>  #endif
>  
> +/*
> + * GCC does not support KMSAN.
> + */
> +#define __no_sanitize_memory
> +#define __no_kmsan_checks
> +
>  /*
>   * Turn individual warnings and errors on and off locally, depending
>   * on version.
> -- 
> 2.34.1.173.g76aa8bc2d0-goog
>
Alexander Potapenko March 18, 2022, 2:01 p.m. UTC | #2
On Wed, Dec 15, 2021 at 2:27 PM Mark Rutland <mark.rutland@arm.com> wrote:

> On Tue, Dec 14, 2021 at 05:20:16PM +0100, Alexander Potapenko wrote:
> > __no_sanitize_memory is a function attribute that instructs KMSAN to
> > skip a function during instrumentation. This is needed to e.g. implement
> > the noinstr functions.
> >
> > __no_kmsan_checks is a function attribute that makes KMSAN
> > ignore the uninitialized values coming from the function's
> > inputs, and initialize the function's outputs.
> >
> > Functions marked with this attribute can't be inlined into functions
> > not marked with it, and vice versa.
>
> Just to check, I assume an unmarked __always_inline() function can be
> inlined
> into a marked function? Otherwise this is going to be really painful to
> manage
> for low-level helper functions.
>

Yes, as a matter of fact __always_inline prevails over the requirement of
having the same attribute.
I'll probably need to clarify this in the description.

>
> Thanks,
> Mark.
>
> >
> > __SANITIZE_MEMORY__ is a macro that's defined iff the file is
> > instrumented with KMSAN. This is not the same as CONFIG_KMSAN, which is
> > defined for every file.
> >
> > Signed-off-by: Alexander Potapenko <glider@google.com>
> > ---
> > Link:
> https://linux-review.googlesource.com/id/I004ff0360c918d3cd8b18767ddd1381c6d3281be
> > ---
> >  include/linux/compiler-clang.h | 23 +++++++++++++++++++++++
> >  include/linux/compiler-gcc.h   |  6 ++++++
> >  2 files changed, 29 insertions(+)
> >
> > diff --git a/include/linux/compiler-clang.h
> b/include/linux/compiler-clang.h
> > index 3c4de9b6c6e3e..5f11a6f269e28 100644
> > --- a/include/linux/compiler-clang.h
> > +++ b/include/linux/compiler-clang.h
> > @@ -51,6 +51,29 @@
> >  #define __no_sanitize_undefined
> >  #endif
> >
> > +#if __has_feature(memory_sanitizer)
> > +#define __SANITIZE_MEMORY__
> > +/*
> > + * Unlike other sanitizers, KMSAN still inserts code into functions
> marked with
> > + * no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation
> > + * provides the behavior consistent with other __no_sanitize_
> attributes,
> > + * guaranteeing that __no_sanitize_memory functions remain
> uninstrumented.
> > + */
> > +#define __no_sanitize_memory __disable_sanitizer_instrumentation
> > +
> > +/*
> > + * The __no_kmsan_checks attribute ensures that a function does not
> produce
> > + * false positive reports by:
> > + *  - initializing all local variables and memory stores in this
> function;
> > + *  - skipping all shadow checks;
> > + *  - passing initialized arguments to this function's callees.
> > + */
> > +#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory")))
> > +#else
> > +#define __no_sanitize_memory
> > +#define __no_kmsan_checks
> > +#endif
> > +
> >  /*
> >   * Support for __has_feature(coverage_sanitizer) was added in Clang 13
> together
> >   * with no_sanitize("coverage"). Prior versions of Clang support
> coverage
> > diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
> > index ccbbd31b3aae5..f6e69387aad05 100644
> > --- a/include/linux/compiler-gcc.h
> > +++ b/include/linux/compiler-gcc.h
> > @@ -129,6 +129,12 @@
> >  #define __SANITIZE_ADDRESS__
> >  #endif
> >
> > +/*
> > + * GCC does not support KMSAN.
> > + */
> > +#define __no_sanitize_memory
> > +#define __no_kmsan_checks
> > +
> >  /*
> >   * Turn individual warnings and errors on and off locally, depending
> >   * on version.
> > --
> > 2.34.1.173.g76aa8bc2d0-goog
> >
>
diff mbox series

Patch

diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h
index 3c4de9b6c6e3e..5f11a6f269e28 100644
--- a/include/linux/compiler-clang.h
+++ b/include/linux/compiler-clang.h
@@ -51,6 +51,29 @@ 
 #define __no_sanitize_undefined
 #endif
 
+#if __has_feature(memory_sanitizer)
+#define __SANITIZE_MEMORY__
+/*
+ * Unlike other sanitizers, KMSAN still inserts code into functions marked with
+ * no_sanitize("kernel-memory"). Using disable_sanitizer_instrumentation
+ * provides the behavior consistent with other __no_sanitize_ attributes,
+ * guaranteeing that __no_sanitize_memory functions remain uninstrumented.
+ */
+#define __no_sanitize_memory __disable_sanitizer_instrumentation
+
+/*
+ * The __no_kmsan_checks attribute ensures that a function does not produce
+ * false positive reports by:
+ *  - initializing all local variables and memory stores in this function;
+ *  - skipping all shadow checks;
+ *  - passing initialized arguments to this function's callees.
+ */
+#define __no_kmsan_checks __attribute__((no_sanitize("kernel-memory")))
+#else
+#define __no_sanitize_memory
+#define __no_kmsan_checks
+#endif
+
 /*
  * Support for __has_feature(coverage_sanitizer) was added in Clang 13 together
  * with no_sanitize("coverage"). Prior versions of Clang support coverage
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index ccbbd31b3aae5..f6e69387aad05 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -129,6 +129,12 @@ 
 #define __SANITIZE_ADDRESS__
 #endif
 
+/*
+ * GCC does not support KMSAN.
+ */
+#define __no_sanitize_memory
+#define __no_kmsan_checks
+
 /*
  * Turn individual warnings and errors on and off locally, depending
  * on version.