lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAG_fn=VuaiTB11bJraxQjoVxp=0ML7Zoth1CYjczgUof3Rhqmw@mail.gmail.com>
Date: Thu, 8 May 2025 10:19:06 +0200
From: Alexander Potapenko <glider@...gle.com>
To: Marco Elver <elver@...gle.com>
Cc: dvyukov@...gle.com, bvanassche@....org, kent.overstreet@...ux.dev, 
	iii@...ux.ibm.com, akpm@...ux-foundation.org, linux-kernel@...r.kernel.org, 
	kasan-dev@...glegroups.com
Subject: Re: [PATCH 2/5] kmsan: fix usage of kmsan_enter_runtime() in kmsan_vmap_pages_range_noflush()

On Wed, May 7, 2025 at 6:09 PM Marco Elver <elver@...gle.com> wrote:
>
> On Wed, 7 May 2025 at 18:00, Alexander Potapenko <glider@...gle.com> wrote:
> >
> > Only enter the runtime to call __vmap_pages_range_noflush(), so that error
> > handling does not skip kmsan_leave_runtime().
> >
> > This bug was spotted by CONFIG_WARN_CAPABILITY_ANALYSIS=y
>
> Might be worth pointing out this is not yet upstream:
> https://lore.kernel.org/all/20250304092417.2873893-1-elver@google.com/

Thanks! I'll update the description (here and in the other patch) and
post v2 later today.

> Also, for future reference, feel free to dump the diff here that added
> the annotations that helped you find the missing kmsan*runtime()
> calls. I'm sure it'd be of interest to others. At one point we may
> upstream those annotations, too, but we'll need Capability Analysis
> upstream first (which is blocked by some Clang improvements that were
> requested).

The diff is below. I added a __no_matter() macro which isn't strictly
necessary (maybe we can remove it altogether), but I thought it'll be
more descriptive.

Author: Alexander Potapenko <glider@...gle.com>
Date:   Thu Apr 3 15:44:38 2025 +0200

    DO-NOT-SUBMIT: kmsan: enable capability analysis

    Add support for the new capability analysis framework to KMSAN.
    Use the KMSAN_RUNTIME capability token to ensure correctness of
    kmsan_enter_runtime()/kmsan_leave_runtime() usage.

    Cc: Marco Elver <elver@...gle.com>
    Cc: Bart Van Assche <bvanassche@....org>
    Cc: Kent Overstreet <kent.overstreet@...ux.dev>
    Signed-off-by: Alexander Potapenko <glider@...gle.com>

diff --git a/mm/kmsan/Makefile b/mm/kmsan/Makefile
index 91cfdde642d16..94591d612384c 100644
--- a/mm/kmsan/Makefile
+++ b/mm/kmsan/Makefile
@@ -8,6 +8,7 @@ obj-y := core.o instrumentation.o init.o hooks.o
report.o shadow.o
 KMSAN_SANITIZE := n
 KCOV_INSTRUMENT := n
 UBSAN_SANITIZE := n
+CAPABILITY_ANALYSIS := y

 # Disable instrumentation of KMSAN runtime with other tools.
 CC_FLAGS_KMSAN_RUNTIME := -fno-stack-protector
diff --git a/mm/kmsan/kmsan.h b/mm/kmsan/kmsan.h
index bc3d1810f352c..441c9dd39fe2a 100644
--- a/mm/kmsan/kmsan.h
+++ b/mm/kmsan/kmsan.h
@@ -35,6 +35,9 @@
 #define KMSAN_META_SHADOW (false)
 #define KMSAN_META_ORIGIN (true)

+token_capability(KMSAN_RUNTIME);
+#define __no_matter(X)
+
 /*
  * A pair of metadata pointers to be returned by the instrumentation functions.
  */
@@ -74,7 +77,7 @@ void kmsan_print_origin(depot_stack_handle_t origin);
  */
 void kmsan_report(depot_stack_handle_t origin, void *address, int size,
                  int off_first, int off_last, const void __user *user_addr,
-                 enum kmsan_bug_reason reason);
+                 enum kmsan_bug_reason reason) __must_not_hold(KMSAN_RUNTIME);

 DECLARE_PER_CPU(struct kmsan_ctx, kmsan_percpu_ctx);

@@ -107,6 +110,7 @@ static __always_inline bool kmsan_in_runtime(void)
 }

 static __always_inline void kmsan_enter_runtime(void)
+       __acquires(KMSAN_RUNTIME) __no_capability_analysis
 {
        struct kmsan_ctx *ctx;

@@ -115,6 +119,7 @@ static __always_inline void kmsan_enter_runtime(void)
 }

 static __always_inline void kmsan_leave_runtime(void)
+       __releases(KMSAN_RUNTIME) __no_capability_analysis
 {
        struct kmsan_ctx *ctx = kmsan_get_context();

@@ -122,7 +127,8 @@ static __always_inline void kmsan_leave_runtime(void)
 }

 depot_stack_handle_t kmsan_save_stack_with_flags(gfp_t flags,
-                                                unsigned int extra_bits);
+                                                unsigned int extra_bits)
+       __must_hold(KMSAN_RUNTIME);

 /*
  * Pack and unpack the origin chain depth and UAF flag to/from the extra bits
@@ -151,19 +157,26 @@ static __always_inline unsigned int
kmsan_depth_from_eb(unsigned int extra_bits)
  * kmsan_internal_ functions are supposed to be very simple and not require the
  * kmsan_in_runtime() checks.
  */
-void kmsan_internal_memmove_metadata(void *dst, void *src, size_t n);
+void kmsan_internal_memmove_metadata(void *dst, void *src, size_t n)
+       __must_hold(KMSAN_RUNTIME);
 void kmsan_internal_poison_memory(void *address, size_t size, gfp_t flags,
-                                 unsigned int poison_flags);
-void kmsan_internal_unpoison_memory(void *address, size_t size, bool checked);
+                                 unsigned int poison_flags)
+       __must_hold(KMSAN_RUNTIME);
+void kmsan_internal_unpoison_memory(void *address, size_t size, bool checked)
+       __no_matter(KMSAN_RUNTIME);
+
 void kmsan_internal_set_shadow_origin(void *address, size_t size, int b,
-                                     u32 origin, bool checked);
-depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id);
+                                     u32 origin, bool checked)
+       __no_matter(KMSAN_RUNTIME);
+depot_stack_handle_t kmsan_internal_chain_origin(depot_stack_handle_t id)
+       __must_hold(KMSAN_RUNTIME);

 void kmsan_internal_task_create(struct task_struct *task);

 bool kmsan_metadata_is_contiguous(void *addr, size_t size);
 void kmsan_internal_check_memory(void *addr, size_t size,
-                                const void __user *user_addr, int reason);
+                                const void __user *user_addr, int reason)
+       __must_not_hold(KMSAN_RUNTIME);

 struct page *kmsan_vmalloc_to_page_or_null(void *vaddr);
 void kmsan_setup_meta(struct page *page, struct page *shadow,

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ