mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-23 07:01:23 +00:00
scs: Add support for Clang's Shadow Call Stack (SCS)
This change adds generic support for Clang's Shadow Call Stack, which uses a shadow stack to protect return addresses from being overwritten by an attacker. Details are available here: https://clang.llvm.org/docs/ShadowCallStack.html Note that security guarantees in the kernel differ from the ones documented for user space. The kernel must store addresses of shadow stacks in memory, which means an attacker capable reading and writing arbitrary memory may be able to locate them and hijack control flow by modifying the stacks. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Reviewed-by: Kees Cook <keescook@chromium.org> Reviewed-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com> [will: Numerous cosmetic changes] Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
6a8b55ed40
commit
d08b9f0ca6
10 changed files with 191 additions and 0 deletions
65
kernel/scs.c
Normal file
65
kernel/scs.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Shadow Call Stack support.
|
||||
*
|
||||
* Copyright (C) 2019 Google LLC
|
||||
*/
|
||||
|
||||
#include <linux/kasan.h>
|
||||
#include <linux/scs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/scs.h>
|
||||
|
||||
static struct kmem_cache *scs_cache;
|
||||
|
||||
static void *scs_alloc(int node)
|
||||
{
|
||||
void *s;
|
||||
|
||||
s = kmem_cache_alloc_node(scs_cache, GFP_SCS, node);
|
||||
if (s) {
|
||||
*__scs_magic(s) = SCS_END_MAGIC;
|
||||
/*
|
||||
* Poison the allocation to catch unintentional accesses to
|
||||
* the shadow stack when KASAN is enabled.
|
||||
*/
|
||||
kasan_poison_object_data(scs_cache, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
static void scs_free(void *s)
|
||||
{
|
||||
kasan_unpoison_object_data(scs_cache, s);
|
||||
kmem_cache_free(scs_cache, s);
|
||||
}
|
||||
|
||||
void __init scs_init(void)
|
||||
{
|
||||
scs_cache = kmem_cache_create("scs_cache", SCS_SIZE, 0, 0, NULL);
|
||||
}
|
||||
|
||||
int scs_prepare(struct task_struct *tsk, int node)
|
||||
{
|
||||
void *s = scs_alloc(node);
|
||||
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
task_scs(tsk) = s;
|
||||
task_scs_offset(tsk) = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scs_release(struct task_struct *tsk)
|
||||
{
|
||||
void *s = task_scs(tsk);
|
||||
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
WARN(scs_corrupted(tsk), "corrupted shadow stack detected when freeing task\n");
|
||||
scs_free(s);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue