summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2020-02-20 20:04:30 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-02-28 16:38:55 +0100
commitda3418ad747fa035a1a88c6883dd2c7d7142ffc4 (patch)
tree47d38bd75fdd4df8205e1f265ca1e96cd9a07141 /lib
parent56ad5b4b7405ec08ef3f2b33cd59f5b3bca6577c (diff)
downloadlinux-stable-da3418ad747fa035a1a88c6883dd2c7d7142ffc4.tar.gz
linux-stable-da3418ad747fa035a1a88c6883dd2c7d7142ffc4.tar.bz2
linux-stable-da3418ad747fa035a1a88c6883dd2c7d7142ffc4.zip
lib/stackdepot.c: fix global out-of-bounds in stack_slabs
[ Upstream commit 305e519ce48e935702c32241f07d393c3c8fed3e ] 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: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/stackdepot.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/lib/stackdepot.c b/lib/stackdepot.c
index e513459a5601..3376a3291186 100644
--- a/lib/stackdepot.c
+++ b/lib/stackdepot.c
@@ -92,15 +92,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;
}