| From: Andrey Konovalov <andreyknvl@gmail.com> |
| Subject: kasan: avoid resetting aux_lock |
| Date: Tue, 9 Jan 2024 23:12:34 +0100 |
| |
| With commit 63b85ac56a64 ("kasan: stop leaking stack trace handles"), |
| KASAN zeroes out alloc meta when an object is freed. The zeroed out data |
| purposefully includes alloc and auxiliary stack traces but also |
| accidentally includes aux_lock. |
| |
| As aux_lock is only initialized for each object slot during slab creation, |
| when the freed slot is reallocated, saving auxiliary stack traces for the |
| new object leads to lockdep reports when taking the zeroed out aux_lock. |
| |
| Arguably, we could reinitialize aux_lock when the object is reallocated, |
| but a simpler solution is to avoid zeroing out aux_lock when an object |
| gets freed. |
| |
| Link: https://lkml.kernel.org/r/20240109221234.90929-1-andrey.konovalov@linux.dev |
| Fixes: 63b85ac56a64 ("kasan: stop leaking stack trace handles") |
| Signed-off-by: Andrey Konovalov <andreyknvl@gmail.com> |
| Reported-by: Paul E. McKenney <paulmck@kernel.org> |
| Closes: https://lore.kernel.org/linux-next/5cc0f83c-e1d6-45c5-be89-9b86746fe731@paulmck-laptop/ |
| Reviewed-by: Marco Elver <elver@google.com> |
| Tested-by: Paul E. McKenney <paulmck@kernel.org> |
| Cc: Alexander Potapenko <glider@google.com> |
| Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com> |
| Cc: Dmitry Vyukov <dvyukov@google.com> |
| Cc: Liam R. Howlett <Liam.Howlett@oracle.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| mm/kasan/generic.c | 10 ++++++++-- |
| 1 file changed, 8 insertions(+), 2 deletions(-) |
| |
| --- a/mm/kasan/generic.c~kasan-avoid-resetting-aux_lock |
| +++ a/mm/kasan/generic.c |
| @@ -487,6 +487,7 @@ void kasan_init_object_meta(struct kmem_ |
| __memset(alloc_meta, 0, sizeof(*alloc_meta)); |
| |
| /* |
| + * Prepare the lock for saving auxiliary stack traces. |
| * Temporarily disable KASAN bug reporting to allow instrumented |
| * raw_spin_lock_init to access aux_lock, which resides inside |
| * of a redzone. |
| @@ -510,8 +511,13 @@ static void release_alloc_meta(struct ka |
| stack_depot_put(meta->aux_stack[0]); |
| stack_depot_put(meta->aux_stack[1]); |
| |
| - /* Zero out alloc meta to mark it as invalid. */ |
| - __memset(meta, 0, sizeof(*meta)); |
| + /* |
| + * Zero out alloc meta to mark it as invalid but keep aux_lock |
| + * initialized to avoid having to reinitialize it when another object |
| + * is allocated in the same slot. |
| + */ |
| + __memset(&meta->alloc_track, 0, sizeof(meta->alloc_track)); |
| + __memset(meta->aux_stack, 0, sizeof(meta->aux_stack)); |
| } |
| |
| static void release_free_meta(const void *object, struct kasan_free_meta *meta) |
| _ |