All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Dmitry V. Levin" <ldv@altlinux.org>
To: Alexander Popov <alex.popov@linux.com>
Cc: kernel-hardening@lists.openwall.com,
	KeesCook <keescook@chromium.org>, Ingo Molnar <mingo@kernel.org>,
	Andy Lutomirski <luto@kernel.org>,
	Tycho Andersen <tycho@tycho.ws>,
	Laura Abbott <labbott@redhat.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Peter Zijlstra <a.p.zijlstra@chello.nl>
Subject: Re: [kernel-hardening] [PATCH RFC v6 2/6] gcc-plugins: Add STACKLEAK plugin for tracking the kernel stack
Date: Tue, 12 Dec 2017 03:09:12 +0300	[thread overview]
Message-ID: <20171212000912.GA10256@altlinux.org> (raw)
In-Reply-To: <1512516827-29797-3-git-send-email-alex.popov@linux.com>

On Wed, Dec 06, 2017 at 02:33:43AM +0300, Alexander Popov wrote:
> The STACKLEAK feature erases the kernel stack before returning from
> syscalls. That reduces the information which kernel stack leak bugs can
> reveal and blocks some uninitialized stack variable attacks. Moreover,
> STACKLEAK provides runtime checks for kernel stack overflow detection.
> 
> This commit introduces the STACKLEAK gcc plugin. It is needed for:
>  - tracking the lowest border of the kernel stack, which is important
>     for the code erasing the used part of the kernel stack at the end
>     of syscalls (comes in a separate commit);
>  - checking that alloca calls don't cause stack overflow.
> 
> So this plugin instruments the kernel code inserting:
>  - the check_alloca() call before alloca and the track_stack() call
>     after it;
>  - the track_stack() call for the functions with a stack frame size
>     greater than or equal to CONFIG_STACKLEAK_TRACK_MIN_SIZE.
> 
> The STACKLEAK feature is ported from grsecurity/PaX. More information at:
>   https://grsecurity.net/
>   https://pax.grsecurity.net/
> 
> This code is modified from Brad Spengler/PaX Team's code in the last
> public patch of grsecurity/PaX based on our understanding of the code.
> Changes or omissions from the original code are ours and don't reflect
> the original grsecurity/PaX code.
> 
> Signed-off-by: Alexander Popov <alex.popov@linux.com>
> ---
>  arch/Kconfig                           |  15 ++
>  arch/x86/kernel/dumpstack.c            |  15 ++
>  fs/exec.c                              |  25 ++
>  scripts/Makefile.gcc-plugins           |   3 +
>  scripts/gcc-plugins/stackleak_plugin.c | 470 +++++++++++++++++++++++++++++++++
>  5 files changed, 528 insertions(+)
>  create mode 100644 scripts/gcc-plugins/stackleak_plugin.c
> 
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 721fdae..ba8e67b 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -528,6 +528,8 @@ config GCC_PLUGIN_STACKLEAK
>  	bool "Erase the kernel stack before returning from syscalls"
>  	depends on GCC_PLUGINS
>  	depends on HAVE_ARCH_STACKLEAK
> +	imply VMAP_STACK
> +	imply SCHED_STACK_END_CHECK
>  	help
>  	  This option makes the kernel erase the kernel stack before it
>  	  returns from a system call. That reduces the information which
> @@ -544,6 +546,19 @@ config GCC_PLUGIN_STACKLEAK
>  	   * https://grsecurity.net/
>  	   * https://pax.grsecurity.net/
>  
> +config STACKLEAK_TRACK_MIN_SIZE
> +	int "Minimum stack frame size of functions tracked by STACKLEAK"
> +	default 100
> +	range 0 4096
> +	depends on GCC_PLUGIN_STACKLEAK
> +	help
> +	  The STACKLEAK gcc plugin instruments the kernel code for tracking
> +	  the lowest border of the kernel stack (and for some other purposes).
> +	  It inserts the track_stack() call for the functions with a stack
> +	  frame size greater than or equal to this parameter. Be careful with
> +	  this setting, don't break the poison search in erase_kstack.
> +	  If unsure, leave the default value 100.
> +

I don't think the warning is scaring enough.  As erase_kstack (both 64-bit
and 32-bit versions) checks for 128 consequent bytes of STACKLEAK_POISON,
it would be a bad idea to raise STACKLEAK_TRACK_MIN_SIZE to a value higher
than 120.  Perhaps there has to be a consistency check that
STACKLEAK_TRACK_MIN_SIZE does not break assumptions made in erase_kstack.

>  config HAVE_CC_STACKPROTECTOR
>  	bool
>  	help
> diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
> index f13b4c0..5a9b6cc 100644
> --- a/arch/x86/kernel/dumpstack.c
> +++ b/arch/x86/kernel/dumpstack.c
> @@ -315,3 +315,18 @@ static int __init code_bytes_setup(char *s)
>  	return 1;
>  }
>  __setup("code_bytes=", code_bytes_setup);
> +
> +#ifdef CONFIG_GCC_PLUGIN_STACKLEAK
> +void __used check_alloca(unsigned long size)
> +{
> +	unsigned long sp = (unsigned long)&sp;
> +	struct stack_info stack_info = {0};
> +	unsigned long visit_mask = 0;
> +	unsigned long stack_left;
> +
> +	BUG_ON(get_stack_info(&sp, current, &stack_info, &visit_mask));
> +	stack_left = sp - (unsigned long)stack_info.begin;
> +	BUG_ON(stack_left < 256 || size >= stack_left - 256);
> +}
> +EXPORT_SYMBOL(check_alloca);
> +#endif

I think some rationale has to be given why 256 was chosen as the minimal
size of stack space left after alloca.


-- 
ldv

  parent reply	other threads:[~2017-12-12  0:09 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-12-05 23:33 [kernel-hardening] [PATCH RFC v6 0/6] Introduce the STACKLEAK feature and a test for it Alexander Popov
2017-12-05 23:33 ` [kernel-hardening] [PATCH RFC v6 1/6] x86/entry: Add STACKLEAK erasing the kernel stack at the end of syscalls Alexander Popov
2017-12-08 11:44   ` [kernel-hardening] " Peter Zijlstra
2017-12-08 21:54     ` Alexander Popov
2017-12-11  9:26       ` Peter Zijlstra
2017-12-05 23:33 ` [kernel-hardening] [PATCH RFC v6 2/6] gcc-plugins: Add STACKLEAK plugin for tracking the kernel stack Alexander Popov
2017-12-06 18:57   ` [kernel-hardening] " Laura Abbott
2017-12-07 23:05     ` Alexander Popov
2017-12-12  0:09   ` Dmitry V. Levin [this message]
2017-12-15 15:28     ` [kernel-hardening] " Alexander Popov
2017-12-05 23:33 ` [kernel-hardening] [PATCH RFC v6 3/6] x86/entry: Erase kernel stack in syscall_trace_enter() Alexander Popov
2017-12-06 21:12   ` Dmitry V. Levin
2017-12-11 22:38     ` Alexander Popov
2017-12-05 23:33 ` [kernel-hardening] [PATCH RFC v6 4/6] lkdtm: Add a test for STACKLEAK Alexander Popov
2017-12-05 23:33 ` [kernel-hardening] [PATCH RFC v6 5/6] fs/proc: Show STACKLEAK metrics in the /proc file system Alexander Popov
2017-12-06 19:22   ` [kernel-hardening] " Laura Abbott
2017-12-06 20:40     ` Kees Cook
2017-12-06 23:06       ` Laura Abbott
2017-12-07 22:58         ` Alexander Popov
2017-12-07  7:09     ` Alexander Popov
2017-12-07 20:47       ` Tobin C. Harding
2017-12-05 23:33 ` [kernel-hardening] [PATCH RFC v6 6/6] doc: self-protection: Add information about STACKLEAK feature Alexander Popov

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=20171212000912.GA10256@altlinux.org \
    --to=ldv@altlinux.org \
    --cc=a.p.zijlstra@chello.nl \
    --cc=alex.popov@linux.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=labbott@redhat.com \
    --cc=luto@kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=mingo@kernel.org \
    --cc=tycho@tycho.ws \
    /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.