On Mon, Oct 5, 2020 at 3:31 PM Andy Lutomirski <l...@kernel.org> wrote: > > 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 > sepends 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_canary, 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. > > This patch forcibly disables stackprotector on older compilers that > don't support the new options and makes the stack canary into a > percpu variable.
This doesn't consider !SMP builds, where per-cpu variable are just normal variables, and the FS segment is disabled. Unfortunately, -mstack-protector-guard-reg=ds is not accepted. The simplest fix would be to define __KERNEL_PERCPU when either SMP or STACKPROTECTOR are enabled. -- Brian Gerst