diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-21 19:32:04 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-21 19:32:04 -0700 |
commit | 2142b7f0c6bbe1f9515ce3383de9f7a32a5a025b (patch) | |
tree | e1c28d1fc2cf8a905254b6f4475a4e65dfddce82 /mm/usercopy.c | |
parent | fd2d7a4a354539dc141f702c6c277bf3380e8778 (diff) | |
parent | afcf5441b9ff22ac57244cd45ff102ebc2e32d1a (diff) | |
download | linux-2142b7f0c6bbe1f9515ce3383de9f7a32a5a025b.tar.gz |
Merge tag 'hardening-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
Pull kernel hardening updates from Kees Cook:
- Add arm64 Shadow Call Stack support for GCC 12 (Dan Li)
- Avoid memset with stack offset randomization under Clang (Marco
Elver)
- Clean up stackleak plugin to play nice with .noinstr (Kees Cook)
- Check stack depth for greater usercopy hardening coverage (Kees Cook)
* tag 'hardening-v5.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
arm64: Add gcc Shadow Call Stack support
m68k: Implement "current_stack_pointer"
xtensa: Implement "current_stack_pointer"
usercopy: Check valid lifetime via stack depth
stack: Constrain and fix stack offset randomization with Clang builds
stack: Introduce CONFIG_RANDOMIZE_KSTACK_OFFSET
gcc-plugins/stackleak: Ignore .noinstr.text and .entry.text
gcc-plugins/stackleak: Exactly match strings instead of prefixes
gcc-plugins/stackleak: Provide verbose mode
Diffstat (limited to 'mm/usercopy.c')
-rw-r--r-- | mm/usercopy.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/mm/usercopy.c b/mm/usercopy.c index d0d268135d96..5d34c40c16c2 100644 --- a/mm/usercopy.c +++ b/mm/usercopy.c @@ -29,7 +29,7 @@ * Returns: * NOT_STACK: not at all on the stack * GOOD_FRAME: fully within a valid stack frame - * GOOD_STACK: fully on the stack (when can't do frame-checking) + * GOOD_STACK: within the current stack (when can't frame-check exactly) * BAD_STACK: error condition (invalid stack position or bad stack frame) */ static noinline int check_stack_object(const void *obj, unsigned long len) @@ -55,6 +55,17 @@ static noinline int check_stack_object(const void *obj, unsigned long len) if (ret) return ret; + /* Finally, check stack depth if possible. */ +#ifdef CONFIG_ARCH_HAS_CURRENT_STACK_POINTER + if (IS_ENABLED(CONFIG_STACK_GROWSUP)) { + if ((void *)current_stack_pointer < obj + len) + return BAD_STACK; + } else { + if (obj < (void *)current_stack_pointer) + return BAD_STACK; + } +#endif + return GOOD_STACK; } @@ -280,7 +291,15 @@ void __check_object_size(const void *ptr, unsigned long n, bool to_user) */ return; default: - usercopy_abort("process stack", NULL, to_user, 0, n); + usercopy_abort("process stack", NULL, to_user, +#ifdef CONFIG_ARCH_HAS_CURRENT_STACK_POINTER + IS_ENABLED(CONFIG_STACK_GROWSUP) ? + ptr - (void *)current_stack_pointer : + (void *)current_stack_pointer - ptr, +#else + 0, +#endif + n); } /* Check for bad heap object. */ |