Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Thu, 5 May 2016 11:15:00 -0700
From: Kees Cook <keescook@...omium.org>
To: Michael Leibowitz <michael.leibowitz@...el.com>
Cc: Brad Spengler <spender@...ecurity.net>, 
	"kernel-hardening@...ts.openwall.com" <kernel-hardening@...ts.openwall.com>, Emese Revfy <re.emese@...il.com>, 
	PaX Team <pageexec@...email.hu>
Subject: Re: [RFC 2/3] Enable the RANDSTRUCT plugin

On Thu, May 5, 2016 at 10:21 AM, Michael Leibowitz
<michael.leibowitz@...el.com> wrote:
> These are config changes necessary to configure/enable the
> structure layout randomizing gcc plugin
>
> This feature is ported over from grsecurity.  This is largely
> unchanged from the Original code written by the PaX Team and Spender.
>
> Signed-off-by: Michael Leibowitz <michael.leibowitz@...el.com>
> ---
>  arch/Kconfig                 | 43 +++++++++++++++++++++++++++++++++++++++++++
>  include/linux/compiler-gcc.h |  5 +++++
>  include/linux/compiler.h     |  9 +++++++++
>  include/linux/vermagic.h     |  9 ++++++++-
>  kernel/module.c              | 27 +++++++++++++++++++++++++++
>  5 files changed, 92 insertions(+), 1 deletion(-)
>
> diff --git a/arch/Kconfig b/arch/Kconfig
> index 8af17ae..c3955a2 100644
> --- a/arch/Kconfig
> +++ b/arch/Kconfig
> @@ -389,6 +389,49 @@ config GCC_PLUGIN_SANCOV
>           gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
>           by Dmitry Vyukov <dvyukov@...gle.com>.
>
> +config GCC_PLUGIN_RANDSTRUCT
> +       bool "Randomize layout of sensitive kernel structures"
> +       default n
> +       depends on GCC_PLUGINS
> +       select MODVERSIONS if MODULES
> +       help
> +
> +         If you say Y here, the layouts of a number of sensitive kernel
> +         structures and all structures composed entirely of function pointers
> +         (aka "ops" structs) will be randomized at compile-time.  This can make
> +         exploitation that targets these structures more difficult by either
> +         requiring an additional information leak vulnerability, or knowing the
> +         pricise build that the target is running.
> +
> +         Enabling this feature will have a performance impact, slightly
> +         increase memory usage, and prevent the use of forensic tools like
> +         Volatility against the system (unless the kernel source tree isn't
> +         cleaned after kernel installation).
> +
> +         Additionally, enabling this feature causes modules compiled with one
> +         random seed to have gibberish names when loaded by a kernel with a
> +         different random seed.

I think this paragraph can be dropped, since the module name is
avoided in the code below.

> +
> +         The seed used for compilation is located at
> +         scripts/gcc-plugins/randomize_layout_seed.h.  It remains after a make
> +         clean to allow for external modules to be compiled with the existing
> +         seed and will be removed by a make mrproper or make distclean.
> +
> +         Note that the implementation requires gcc 4.6.4. or newer.  You may need
> +         to install the supporting headers explicitly in addition to the normal
> +         gcc package.

Does this use headers not already detected by the gcc plugin infrastructure?

> +
> +config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
> +       bool "Use cacheline-aware structure randomization"
> +       default n
> +       depends on GCC_PLUGIN_RANDSTRUCT
> +       help
> +         If you say Y here, the RANDSTRUCT randomization will make a best effort
> +         at restricting randomization to cacheline-sized groups of elements.  It
> +         will further not randomize bitfields in structures.  This reduces the
> +         performance hit of RANDSTRUCT at the cost of weakened randomization.
> +
> +
>  config HAVE_CC_STACKPROTECTOR
>         bool
>         help
> diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
> index 22ab246..7bfa763 100644
> --- a/include/linux/compiler-gcc.h
> +++ b/include/linux/compiler-gcc.h
> @@ -201,6 +201,11 @@
>  /* Mark a function definition as prohibited from being cloned. */
>  #define __noclone      __attribute__((__noclone__))
>
> +#ifdef RANDSTRUCT_PLUGIN
> +#define __randomize_layout __attribute__((randomize_layout))
> +#define __no_randomize_layout __attribute__((no_randomize_layout))
> +#endif
> +
>  #endif /* GCC_VERSION >= 40500 */
>
>  #if GCC_VERSION >= 40600
> diff --git a/include/linux/compiler.h b/include/linux/compiler.h
> index 48f5aab..8d0776e 100644
> --- a/include/linux/compiler.h
> +++ b/include/linux/compiler.h
> @@ -416,6 +416,15 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
>  # define __attribute_const__   /* unimplemented */
>  #endif
>
> +#ifndef __randomize_layout
> +# define __randomize_layout
> +#endif
> +
> +#ifndef __no_randomize_layout
> +# define __no_randomize_layout
> +#endif
> +
> +
>  /*
>   * Tell gcc if a function is cold. The compiler will assume any path
>   * directly leading to the call is unlikely.
> diff --git a/include/linux/vermagic.h b/include/linux/vermagic.h
> index 6f8fbcf..af6c03f 100644
> --- a/include/linux/vermagic.h
> +++ b/include/linux/vermagic.h
> @@ -24,10 +24,17 @@
>  #ifndef MODULE_ARCH_VERMAGIC
>  #define MODULE_ARCH_VERMAGIC ""
>  #endif
> +#ifdef RANDSTRUCT_PLUGIN
> +#include <generated/randomize_layout_hash.h>
> +#define MODULE_RANDSTRUCT_PLUGIN "RANDSTRUCT_PLUGIN_" RANDSTRUCT_HASHED_SEED
> +#else
> +#define MODULE_RANDSTRUCT_PLUGIN
> +#endif
>
>  #define VERMAGIC_STRING                                                \
>         UTS_RELEASE " "                                                 \
>         MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT                     \
>         MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS       \
> -       MODULE_ARCH_VERMAGIC
> +       MODULE_ARCH_VERMAGIC                                            \
> +       MODULE_RANDSTRUCT_PLUGIN
>
> diff --git a/kernel/module.c b/kernel/module.c
> index 794ebe8..74cf098 100644
> --- a/kernel/module.c
> +++ b/kernel/module.c
> @@ -1296,12 +1296,31 @@ static int check_version(Elf_Shdr *sechdrs,
>                 goto bad_version;
>         }
>
> +#ifdef CONFIG_GCC_PLUGIN_RANDSTRUCT
> +       /*
> +        * avoid potentially printing jibberish on attempted load
> +        * of a module randomized with a different seed
> +        */
> +       pr_warn("no symbol version for %s\n", symname);
> +#else
> +       pr_warn("%s: no symbol version for %s\n", mod->name, symname);
> +#endif
> +
>         pr_warn("%s: no symbol version for %s\n", mod->name, symname);

I think this pr_warn needs to be removed (it looks to have moved
inside the define).

I wonder if the module filename can be propagated in some other way
besides mod->name?

>         return 0;
>
>  bad_version:
> +#ifdef CONFIG_GCC_PLUGIN_RANDSTRUCT
> +       /*
> +        * avoid potentially printing jibberish on attempted load
> +        * of a module randomized with a different seed
> +        */
> +       pr_warn("attempted module disagrees about version of symbol %s\n",
> +               symname);
> +#else
>         pr_warn("%s: disagrees about version of symbol %s\n",
>                mod->name, symname);
> +#endif
>         return 0;
>  }
>
> @@ -2835,7 +2854,15 @@ static struct module *setup_load_info(struct load_info *info, int flags)
>         mod = (void *)info->sechdrs[info->index.mod].sh_addr;
>
>         if (info->index.sym == 0) {
> +#ifdef CONFIG_GCC_PLUGIN_RANDSTRUCT
> +               /*
> +                * avoid potentially printing jibberish on attempted load
> +                * of a module randomized with a different seed
> +                */
> +               pr_warn("module has no symbols (stripped?)\n");
> +#else
>                 pr_warn("%s: module has no symbols (stripped?)\n", mod->name);
> +#endif
>                 return ERR_PTR(-ENOEXEC);
>         }
>
> --
> 1.9.1
>



-- 
Kees Cook
Chrome OS & Brillo Security

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.