From: Kees Cook <keescook@chromium.org>
To: Jann Horn <jannh@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Elena Reshetova <elena.reshetova@intel.com>,
the arch/x86 maintainers <x86@kernel.org>,
Andy Lutomirski <luto@kernel.org>,
Peter Zijlstra <peterz@infradead.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Mark Rutland <mark.rutland@arm.com>,
Alexander Potapenko <glider@google.com>,
Alexander Popov <alex.popov@linux.com>,
Ard Biesheuvel <ard.biesheuvel@linaro.org>,
Kernel Hardening <kernel-hardening@lists.openwall.com>,
Linux ARM <linux-arm-kernel@lists.infradead.org>,
Linux-MM <linux-mm@kvack.org>,
kernel list <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v4 3/5] stack: Optionally randomize kernel stack offset each syscall
Date: Mon, 22 Jun 2020 15:04:40 -0700 [thread overview]
Message-ID: <202006221451.2E80C90FF7@keescook> (raw)
In-Reply-To: <CAG48ez1b_wMkQGj+z=dWSVctikzzw72V3SPexEPm3Aw8LrXGWQ@mail.gmail.com>
On Mon, Jun 22, 2020 at 11:42:29PM +0200, Jann Horn wrote:
> No, at least on x86-64 and x86 Linux overrides the normal ABI. From
> arch/x86/Makefile:
Ah! Thanks for the pointer.
>
> # For gcc stack alignment is specified with -mpreferred-stack-boundary,
> # clang has the option -mstack-alignment for that purpose.
> ifneq ($(call cc-option, -mpreferred-stack-boundary=4),)
> cc_stack_align4 := -mpreferred-stack-boundary=2
> cc_stack_align8 := -mpreferred-stack-boundary=3
> else ifneq ($(call cc-option, -mstack-alignment=16),)
> cc_stack_align4 := -mstack-alignment=4
> cc_stack_align8 := -mstack-alignment=8
> endif
> [...]
> ifeq ($(CONFIG_X86_32),y)
> [...]
> # Align the stack to the register width instead of using the default
> # alignment of 16 bytes. This reduces stack usage and the number of
> # alignment instructions.
> KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align4))
> [...]
> else
> [...]
> # By default gcc and clang use a stack alignment of 16 bytes for x86.
> # However the standard kernel entry on x86-64 leaves the stack on an
> # 8-byte boundary. If the compiler isn't informed about the actual
> # alignment it will generate extra alignment instructions for the
> # default alignment which keep the stack *mis*aligned.
> # Furthermore an alignment to the register width reduces stack usage
> # and the number of alignment instructions.
> KBUILD_CFLAGS += $(call cc-option,$(cc_stack_align8))
> [...]
> endif
And it seems that only x86 does this. No other architecture specifies
-mpreferred-stack-boundary...
> Normal x86-64 ABI has 16-byte stack alignment; Linux kernel x86-64 ABI
> has 8-byte stack alignment.
> Similarly, the normal Linux 32-bit x86 ABI is 16-byte aligned;
> meanwhile Linux kernel x86 ABI has 4-byte stack alignment.
>
> This is because userspace code wants the stack to be sufficiently
> aligned for fancy SSE instructions and such; the kernel, on the other
> hand, never uses those in normal code, and cares about stack usage and
> such very much.
This makes it nicer for Clang:
diff --git a/include/linux/randomize_kstack.h b/include/linux/randomize_kstack.h
index 1df0dc52cadc..f7e1f68fb50c 100644
--- a/include/linux/randomize_kstack.h
+++ b/include/linux/randomize_kstack.h
@@ -10,6 +10,14 @@ DECLARE_STATIC_KEY_MAYBE(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT,
randomize_kstack_offset);
DECLARE_PER_CPU(u32, kstack_offset);
+#ifdef CONFIG_X86_64
+#define ARCH_STACK_ALIGN_MASK ~((1 << 8) - 1)
+#elif defined(CONFIG_X86_32)
+#define ARCH_STACK_ALIGN_MASK ~((1 << 4) - 1)
+#else
+#define ARCH_STACK_ALIGN_MASK ~(0)
+#endif
+
/*
* Do not use this anywhere else in the kernel. This is used here because
* it provides an arch-agnostic way to grow the stack with correct
@@ -23,7 +31,8 @@ void *__builtin_alloca(size_t size);
if (static_branch_maybe(CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT, \
&randomize_kstack_offset)) { \
u32 offset = this_cpu_read(kstack_offset); \
- u8 *ptr = __builtin_alloca(offset & 0x3FF); \
+ u8 *ptr = __builtin_alloca(offset & 0x3FF & \
+ ARCH_STACK_ALIGN_MASK); \
asm volatile("" : "=m"(*ptr)); \
} \
} while (0)
But I don't like open-coding the x86-ony stack alignment... it should be
in Kconfig or something, I think?
--
Kees Cook
next prev parent reply other threads:[~2020-06-22 22:05 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-22 19:31 [PATCH v4 0/5] Optionally randomize kernel stack offset each syscall Kees Cook
2020-06-22 19:31 ` [PATCH v4 1/5] jump_label: Provide CONFIG-driven build state defaults Kees Cook
2020-06-22 19:31 ` [PATCH v4 2/5] init_on_alloc: Unpessimize default-on builds Kees Cook
2020-06-22 19:31 ` [PATCH v4 3/5] stack: Optionally randomize kernel stack offset each syscall Kees Cook
2020-06-22 19:40 ` Randy Dunlap
2020-06-22 21:26 ` Kees Cook
2020-06-22 20:07 ` Jann Horn
2020-06-22 21:30 ` Kees Cook
2020-06-22 21:42 ` Jann Horn
2020-06-22 22:04 ` Kees Cook [this message]
2020-06-22 22:56 ` Arvind Sankar
2020-06-22 23:07 ` Kees Cook
2020-06-23 0:05 ` Arvind Sankar
2020-06-23 0:56 ` Kees Cook
2020-06-23 13:42 ` David Laight
2020-06-23 12:38 ` Alexander Popov
2020-06-22 19:31 ` [PATCH v4 4/5] x86/entry: Enable random_kstack_offset support Kees Cook
2020-06-22 19:31 ` [PATCH v4 5/5] arm64: entry: " Kees Cook
2020-06-23 9:40 ` Mark Rutland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202006221451.2E80C90FF7@keescook \
--to=keescook@chromium.org \
--cc=alex.popov@linux.com \
--cc=ard.biesheuvel@linaro.org \
--cc=catalin.marinas@arm.com \
--cc=elena.reshetova@intel.com \
--cc=glider@google.com \
--cc=jannh@google.com \
--cc=kernel-hardening@lists.openwall.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=luto@kernel.org \
--cc=mark.rutland@arm.com \
--cc=peterz@infradead.org \
--cc=tglx@linutronix.de \
--cc=will@kernel.org \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.