• Marco Elver's avatar
    stack: Constrain and fix stack offset randomization with Clang builds · efa90c11
    Marco Elver authored
    All supported versions of Clang perform auto-init of __builtin_alloca()
    when stack auto-init is on (CONFIG_INIT_STACK_ALL_{ZERO,PATTERN}).
    
    add_random_kstack_offset() uses __builtin_alloca() to add a stack
    offset. This means, when CONFIG_INIT_STACK_ALL_{ZERO,PATTERN} is
    enabled, add_random_kstack_offset() will auto-init that unused portion
    of the stack used to add an offset.
    
    There are several problems with this:
    
    	1. These offsets can be as large as 1023 bytes. Performing
    	   memset() on them isn't exactly cheap, and this is done on
    	   every syscall entry.
    
    	2. Architectures adding add_random_kstack_offset() to syscall
    	   entry implemented in C require them to be 'noinstr' (e.g. see
    	   x86 and s390). The potential problem here is that a call to
    	   memset may occur, which is not noinstr.
    
    A x86_64 defconfig kernel with Clang 11 and CONFIG_VMLINUX_VALIDATION shows:
    
     | vmlinux.o: warning: objtool: do_syscall_64()+0x9d: call to memset() leaves .noinstr.text section
     | vmlinux.o: warning: objtool: do_int80_syscall_32()+0xab: call to memset() leaves .noinstr.text section
     | vmlinux.o: warning: objtool: __do_fast_syscall_32()+0xe2: call to memset() leaves .noinstr.text section
     | vmlinux.o: warning: objtool: fixup_bad_iret()+0x2f: call to memset() leaves .noinstr.text section
    
    Clang 14 (unreleased) will introduce a way to skip alloca initialization
    via __builtin_alloca_uninitialized() (https://reviews.llvm.org/D115440).
    
    Constrain RANDOMIZE_KSTACK_OFFSET to only be enabled if no stack
    auto-init is enabled, the compiler is GCC, or Clang is version 14+. Use
    __builtin_alloca_uninitialized() if the compiler provides it, as is done
    by Clang 14.
    
    Link: https://lkml.kernel.org/r/YbHTKUjEejZCLyhX@elver.google.com
    Fixes: 39218ff4 ("stack: Optionally randomize kernel stack offset each syscall")
    Signed-off-by: default avatarMarco Elver <elver@google.com>
    Reviewed-by: default avatarNathan Chancellor <nathan@kernel.org>
    Acked-by: default avatarKees Cook <keescook@chromium.org>
    Signed-off-by: default avatarKees Cook <keescook@chromium.org>
    Link: https://lore.kernel.org/r/20220131090521.1947110-2-elver@google.com
    efa90c11
Kconfig 40.3 KB