Commit 2d6bb6ad authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull stackleak gcc plugin from Kees Cook:
 "Please pull this new GCC plugin, stackleak, for v4.20-rc1. This plugin
  was ported from grsecurity by Alexander Popov. It provides efficient
  stack content poisoning at syscall exit. This creates a defense
  against at least two classes of flaws:

   - Uninitialized stack usage. (We continue to work on improving the
     compiler to do this in other ways: e.g. unconditional zero init was
     proposed to GCC and Clang, and more plugin work has started too).

   - Stack content exposure. By greatly reducing the lifetime of valid
     stack contents, exposures via either direct read bugs or unknown
     cache side-channels become much more difficult to exploit. This
     complements the existing buddy and heap poisoning options, but
     provides the coverage for stacks.

  The x86 hooks are included in this series (which have been reviewed by
  Ingo, Dave Hansen, and Thomas Gleixner). The arm64 hooks have already
  been merged through the arm64 tree (written by Laura Abbott and
  reviewed by Mark Rutland and Will Deacon).

  With VLAs having been removed this release, there is no need for
  alloca() protection, so it has been removed from the plugin"

* tag 'stackleak-v4.20-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  arm64: Drop unneeded stackleak_check_alloca()
  stackleak: Allow runtime disabling of kernel stack erasing
  doc: self-protection: Add information about STACKLEAK feature
  fs/proc: Show STACKLEAK metrics in the /proc file system
  lkdtm: Add a test for STACKLEAK
  gcc-plugins: Add STACKLEAK plugin for tracking the kernel stack
  x86/entry: Add STACKLEAK erasing the kernel stack at the end of syscalls
parents 7c6c54b5 6fcde904
Loading
Loading
Loading
Loading
+5 −5
Original line number Original line Diff line number Diff line
@@ -302,11 +302,11 @@ sure structure holes are cleared.
Memory poisoning
Memory poisoning
----------------
----------------


When releasing memory, it is best to poison the contents (clear stack on
When releasing memory, it is best to poison the contents, to avoid reuse
syscall return, wipe heap memory on a free), to avoid reuse attacks that
attacks that rely on the old contents of memory. E.g., clear stack on a
rely on the old contents of memory. This frustrates many uninitialized
syscall return (``CONFIG_GCC_PLUGIN_STACKLEAK``), wipe heap memory on a
variable attacks, stack content exposures, heap content exposures, and
free. This frustrates many uninitialized variable attacks, stack content
use-after-free attacks.
exposures, heap content exposures, and use-after-free attacks.


Destination tracking
Destination tracking
--------------------
--------------------
+18 −0
Original line number Original line Diff line number Diff line
@@ -89,6 +89,7 @@ show up in /proc/sys/kernel:
- shmmni
- shmmni
- softlockup_all_cpu_backtrace
- softlockup_all_cpu_backtrace
- soft_watchdog
- soft_watchdog
- stack_erasing
- stop-a                      [ SPARC only ]
- stop-a                      [ SPARC only ]
- sysrq                       ==> Documentation/admin-guide/sysrq.rst
- sysrq                       ==> Documentation/admin-guide/sysrq.rst
- sysctl_writes_strict
- sysctl_writes_strict
@@ -987,6 +988,23 @@ detect a hard lockup condition.


==============================================================
==============================================================


stack_erasing

This parameter can be used to control kernel stack erasing at the end
of syscalls for kernels built with CONFIG_GCC_PLUGIN_STACKLEAK.

That erasing reduces the information which kernel stack leak bugs
can reveal and blocks some uninitialized stack variable attacks.
The tradeoff is the performance impact: on a single CPU system kernel
compilation sees a 1% slowdown, other systems and workloads may vary.

  0: kernel stack erasing is disabled, STACKLEAK_METRICS are not updated.

  1: kernel stack erasing is enabled (default), it is performed before
     returning to the userspace at the end of syscalls.

==============================================================

tainted:
tainted:


Non-zero if the kernel has been tainted. Numeric values, which can be
Non-zero if the kernel has been tainted. Numeric values, which can be
+3 −0
Original line number Original line Diff line number Diff line
@@ -146,3 +146,6 @@ Their order is preserved but their base will be offset early at boot time.
Be very careful vs. KASLR when changing anything here. The KASLR address
Be very careful vs. KASLR when changing anything here. The KASLR address
range must not overlap with anything except the KASAN shadow area, which is
range must not overlap with anything except the KASAN shadow area, which is
correct as KASAN disables KASLR.
correct as KASAN disables KASLR.

For both 4- and 5-level layouts, the STACKLEAK_POISON value in the last 2MB
hole: ffffffffffff4111
+7 −0
Original line number Original line Diff line number Diff line
@@ -429,6 +429,13 @@ config SECCOMP_FILTER


	  See Documentation/userspace-api/seccomp_filter.rst for details.
	  See Documentation/userspace-api/seccomp_filter.rst for details.


config HAVE_ARCH_STACKLEAK
	bool
	help
	  An architecture should select this if it has the code which
	  fills the used part of the kernel stack with the STACKLEAK_POISON
	  value before returning from system calls.

config HAVE_STACKPROTECTOR
config HAVE_STACKPROTECTOR
	bool
	bool
	help
	help
+0 −22
Original line number Original line Diff line number Diff line
@@ -497,25 +497,3 @@ void arch_setup_new_exec(void)
{
{
	current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0;
	current->mm->context.flags = is_compat_task() ? MMCF_AARCH32 : 0;
}
}

#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
void __used stackleak_check_alloca(unsigned long size)
{
	unsigned long stack_left;
	unsigned long current_sp = current_stack_pointer;
	struct stack_info info;

	BUG_ON(!on_accessible_stack(current, current_sp, &info));

	stack_left = current_sp - info.low;

	/*
	 * There's a good chance we're almost out of stack space if this
	 * is true. Using panic() over BUG() is more likely to give
	 * reliable debugging output.
	 */
	if (size >= stack_left)
		panic("alloca() over the kernel stack boundary\n");
}
EXPORT_SYMBOL(stackleak_check_alloca);
#endif
Loading