kasan: remove kasan_find_vm_area() to prevent possible deadlock
authorYeoreum Yun <yeoreum.yun@arm.com>
Thu, 3 Jul 2025 18:10:18 +0000 (19:10 +0100)
committerAndrew Morton <akpm@linux-foundation.org>
Thu, 10 Jul 2025 04:07:54 +0000 (21:07 -0700)
find_vm_area() couldn't be called in atomic_context.  If find_vm_area() is
called to reports vm area information, kasan can trigger deadlock like:

CPU0                                CPU1
vmalloc();
 alloc_vmap_area();
  spin_lock(&vn->busy.lock)
                                    spin_lock_bh(&some_lock);
   <interrupt occurs>
   <in softirq>
   spin_lock(&some_lock);
                                    <access invalid address>
                                    kasan_report();
                                     print_report();
                                      print_address_description();
                                       kasan_find_vm_area();
                                        find_vm_area();
                                         spin_lock(&vn->busy.lock) // deadlock!

To prevent possible deadlock while kasan reports, remove kasan_find_vm_area().

Link: https://lkml.kernel.org/r/20250703181018.580833-1-yeoreum.yun@arm.com
Fixes: c056a364e954 ("kasan: print virtual mapping info in reports")
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reported-by: Yunseong Kim <ysk@kzalloc.com>
Reviewed-by: Andrey Ryabinin <ryabinin.a.a@gmail.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Dmitriy Vyukov <dvyukov@google.com>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/kasan/report.c

index 8357e1a33699b54b3360d98f0739abffb640afef..b0877035491f806ed1f6a52885e3255b76071b53 100644 (file)
@@ -370,36 +370,6 @@ static inline bool init_task_stack_addr(const void *addr)
                        sizeof(init_thread_union.stack));
 }
 
-/*
- * This function is invoked with report_lock (a raw_spinlock) held. A
- * PREEMPT_RT kernel cannot call find_vm_area() as it will acquire a sleeping
- * rt_spinlock.
- *
- * For !RT kernel, the PROVE_RAW_LOCK_NESTING config option will print a
- * lockdep warning for this raw_spinlock -> spinlock dependency. This config
- * option is enabled by default to ensure better test coverage to expose this
- * kind of RT kernel problem. This lockdep splat, however, can be suppressed
- * by using DEFINE_WAIT_OVERRIDE_MAP() if it serves a useful purpose and the
- * invalid PREEMPT_RT case has been taken care of.
- */
-static inline struct vm_struct *kasan_find_vm_area(void *addr)
-{
-       static DEFINE_WAIT_OVERRIDE_MAP(vmalloc_map, LD_WAIT_SLEEP);
-       struct vm_struct *va;
-
-       if (IS_ENABLED(CONFIG_PREEMPT_RT))
-               return NULL;
-
-       /*
-        * Suppress lockdep warning and fetch vmalloc area of the
-        * offending address.
-        */
-       lock_map_acquire_try(&vmalloc_map);
-       va = find_vm_area(addr);
-       lock_map_release(&vmalloc_map);
-       return va;
-}
-
 static void print_address_description(void *addr, u8 tag,
                                      struct kasan_report_info *info)
 {
@@ -429,19 +399,8 @@ static void print_address_description(void *addr, u8 tag,
        }
 
        if (is_vmalloc_addr(addr)) {
-               struct vm_struct *va = kasan_find_vm_area(addr);
-
-               if (va) {
-                       pr_err("The buggy address belongs to the virtual mapping at\n"
-                              " [%px, %px) created by:\n"
-                              " %pS\n",
-                              va->addr, va->addr + va->size, va->caller);
-                       pr_err("\n");
-
-                       page = vmalloc_to_page(addr);
-               } else {
-                       pr_err("The buggy address %px belongs to a vmalloc virtual mapping\n", addr);
-               }
+               pr_err("The buggy address %px belongs to a vmalloc virtual mapping\n", addr);
+               page = vmalloc_to_page(addr);
        }
 
        if (page) {