diff options
author | Alexander Potapenko <glider@google.com> | 2020-02-20 20:04:30 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-02-28 15:42:50 +0100 |
commit | 73e82ee9f04808bf2938b67ab8cbf134d97b7b31 (patch) | |
tree | ba24a46c38c77ccfab1941e93b8d2e614973f8ed /lib | |
parent | 160fbca8d5d74c1a4cec4b666f36b3e614c19f4f (diff) | |
download | linux-stable-73e82ee9f04808bf2938b67ab8cbf134d97b7b31.tar.gz linux-stable-73e82ee9f04808bf2938b67ab8cbf134d97b7b31.tar.bz2 linux-stable-73e82ee9f04808bf2938b67ab8cbf134d97b7b31.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.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/lib/stackdepot.c b/lib/stackdepot.c index f87d138e9672..759ff419fe61 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; } |