| From dacb425673feda4445995463953b3aa5ccf68837 Mon Sep 17 00:00:00 2001 |
| From: Alexander Potapenko <glider@google.com> |
| Date: Thu, 20 Feb 2020 20:04:30 -0800 |
| Subject: [PATCH] lib/stackdepot.c: fix global out-of-bounds in stack_slabs |
| |
| commit 305e519ce48e935702c32241f07d393c3c8fed3e upstream. |
| |
| Walter Wu has reported a potential case in which init_stack_slab() is |
| called after stack_slabs[STACK_ALLOC_MAX_SLABS - 1] has already been |
| initialized. In that case init_stack_slab() will overwrite |
| stack_slabs[STACK_ALLOC_MAX_SLABS], which may result in a memory |
| corruption. |
| |
| Link: http://lkml.kernel.org/r/20200218102950.260263-1-glider@google.com |
| Fixes: cd11016e5f521 ("mm, kasan: stackdepot implementation. Enable stackdepot for SLAB") |
| Signed-off-by: Alexander Potapenko <glider@google.com> |
| Reported-by: Walter Wu <walter-zh.wu@mediatek.com> |
| Cc: Dmitry Vyukov <dvyukov@google.com> |
| Cc: Matthias Brugger <matthias.bgg@gmail.com> |
| Cc: Thomas Gleixner <tglx@linutronix.de> |
| Cc: Josh Poimboeuf <jpoimboe@redhat.com> |
| Cc: Kate Stewart <kstewart@linuxfoundation.org> |
| Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Cc: <stable@vger.kernel.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/lib/stackdepot.c b/lib/stackdepot.c |
| index 66cab785bea0..aae3577b0392 100644 |
| --- a/lib/stackdepot.c |
| +++ b/lib/stackdepot.c |
| @@ -83,15 +83,19 @@ static bool init_stack_slab(void **prealloc) |
| return true; |
| if (stack_slabs[depot_index] == NULL) { |
| stack_slabs[depot_index] = *prealloc; |
| + *prealloc = NULL; |
| } else { |
| - stack_slabs[depot_index + 1] = *prealloc; |
| + /* If this is the last depot slab, do not touch the next one. */ |
| + if (depot_index + 1 < STACK_ALLOC_MAX_SLABS) { |
| + stack_slabs[depot_index + 1] = *prealloc; |
| + *prealloc = NULL; |
| + } |
| /* |
| * This smp_store_release pairs with smp_load_acquire() from |
| * |next_slab_inited| above and in depot_save_stack(). |
| */ |
| smp_store_release(&next_slab_inited, 1); |
| } |
| - *prealloc = NULL; |
| return true; |
| } |
| |
| -- |
| 2.7.4 |
| |