mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-21 06:50:25 +00:00
kasan: remove kasan_find_vm_area() to prevent possible deadlock
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: c056a364e9
("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>
This commit is contained in:
parent
e6d3e653b0
commit
6ee9b3d847
1 changed files with 2 additions and 43 deletions
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue