x86/stackprotector/32: Make the canary into a regular percpu variable
On 32-bit kernels, the stackprotector canary is quite nasty -- it is stored at %gs:(20), which is nasty because 32-bit kernels use %fs for percpu storage. It's even nastier because it means that whether %gs contains userspace state or kernel state while running kernel code depends on whether stackprotector is enabled (this is CONFIG_X86_32_LAZY_GS), and this setting radically changes the way that segment selectors work. Supporting both variants is a maintenance and testing mess. Merely rearranging so that percpu and the stack canary share the same segment would be messy as the 32-bit percpu address layout isn't currently compatible with putting a variable at a fixed offset. Fortunately, GCC 8.1 added options that allow the stack canary to be accessed as %fs:__stack_chk_guard, effectively turning it into an ordinary percpu variable. This lets us get rid of all of the code to manage the stack canary GDT descriptor and the CONFIG_X86_32_LAZY_GS mess. (That name is special. We could use any symbol we want for the %fs-relative mode, but for CONFIG_SMP=n, gcc refuses to let us use any name other than __stack_chk_guard.) Forcibly disable stackprotector on older compilers that don't support the new options and turn the stack canary into a percpu variable. The "lazy GS" approach is now used for all 32-bit configurations. Also makes load_gs_index() work on 32-bit kernels. On 64-bit kernels, it loads the GS selector and updates the user GSBASE accordingly. (This is unchanged.) On 32-bit kernels, it loads the GS selector and updates GSBASE, which is now always the user base. This means that the overall effect is the same on 32-bit and 64-bit, which avoids some ifdeffery. [ bp: Massage commit message. ] Signed-off-by:Andy Lutomirski <luto@kernel.org> Signed-off-by:
Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/c0ff7dba14041c7e5d1cae5d4df052f03759bef3.1613243844.git.luto@kernel.org
Showing
- arch/x86/Kconfig 2 additions, 5 deletionsarch/x86/Kconfig
- arch/x86/Makefile 8 additions, 0 deletionsarch/x86/Makefile
- arch/x86/entry/entry_32.S 4 additions, 52 deletionsarch/x86/entry/entry_32.S
- arch/x86/include/asm/processor.h 4 additions, 11 deletionsarch/x86/include/asm/processor.h
- arch/x86/include/asm/ptrace.h 4 additions, 1 deletionarch/x86/include/asm/ptrace.h
- arch/x86/include/asm/segment.h 8 additions, 22 deletionsarch/x86/include/asm/segment.h
- arch/x86/include/asm/stackprotector.h 16 additions, 63 deletionsarch/x86/include/asm/stackprotector.h
- arch/x86/include/asm/suspend_32.h 2 additions, 4 deletionsarch/x86/include/asm/suspend_32.h
- arch/x86/kernel/asm-offsets_32.c 0 additions, 5 deletionsarch/x86/kernel/asm-offsets_32.c
- arch/x86/kernel/cpu/common.c 2 additions, 3 deletionsarch/x86/kernel/cpu/common.c
- arch/x86/kernel/doublefault_32.c 1 addition, 3 deletionsarch/x86/kernel/doublefault_32.c
- arch/x86/kernel/head_32.S 2 additions, 16 deletionsarch/x86/kernel/head_32.S
- arch/x86/kernel/setup_percpu.c 0 additions, 1 deletionarch/x86/kernel/setup_percpu.c
- arch/x86/kernel/tls.c 1 addition, 7 deletionsarch/x86/kernel/tls.c
- arch/x86/lib/insn-eval.c 0 additions, 4 deletionsarch/x86/lib/insn-eval.c
- arch/x86/platform/pvh/head.S 0 additions, 14 deletionsarch/x86/platform/pvh/head.S
- arch/x86/power/cpu.c 1 addition, 5 deletionsarch/x86/power/cpu.c
- arch/x86/xen/enlighten_pv.c 0 additions, 1 deletionarch/x86/xen/enlighten_pv.c
- scripts/gcc-x86_32-has-stack-protector.sh 5 additions, 1 deletionscripts/gcc-x86_32-has-stack-protector.sh
Loading
Please register or sign in to comment