randstruct: Reorganize Kconfigs and attribute macros

In preparation for Clang supporting randstruct, reorganize the Kconfigs,
move the attribute macros, and generalize the feature to be named
CONFIG_RANDSTRUCT for on/off, CONFIG_RANDSTRUCT_FULL for the full
randomization mode, and CONFIG_RANDSTRUCT_PERFORMANCE for the cache-line
sized mode.

Cc: linux-hardening@vger.kernel.org
Signed-off-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20220503205503.3054173-4-keescook@chromium.org
This commit is contained in:
Kees Cook 2022-05-03 13:55:00 -07:00
parent d364658970
commit 595b893e20
10 changed files with 81 additions and 66 deletions

View File

@ -99,10 +99,9 @@ unreproducible parts can be treated as sources:
Structure randomisation Structure randomisation
----------------------- -----------------------
If you enable ``CONFIG_GCC_PLUGIN_RANDSTRUCT``, you will need to If you enable ``CONFIG_RANDSTRUCT``, you will need to pre-generate
pre-generate the random seed in the random seed in ``scripts/gcc-plugins/randomize_layout_seed.h``
``scripts/gcc-plugins/randomize_layout_seed.h`` so the same value so the same value is used in rebuilds.
is used in rebuilds.
Debug info conflicts Debug info conflicts
-------------------- --------------------

View File

@ -468,7 +468,7 @@ config CC_HAVE_STACKPROTECTOR_TLS
config STACKPROTECTOR_PER_TASK config STACKPROTECTOR_PER_TASK
def_bool y def_bool y
depends on !GCC_PLUGIN_RANDSTRUCT depends on !RANDSTRUCT
depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS depends on STACKPROTECTOR && CC_HAVE_STACKPROTECTOR_TLS
config PHYS_RAM_BASE_FIXED config PHYS_RAM_BASE_FIXED

View File

@ -540,7 +540,7 @@ static inline bool pti_kernel_image_global_ok(void)
* cases where RANDSTRUCT is in use to help keep the layout a * cases where RANDSTRUCT is in use to help keep the layout a
* secret. * secret.
*/ */
if (IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT)) if (IS_ENABLED(CONFIG_RANDSTRUCT))
return false; return false;
return true; return true;

View File

@ -66,14 +66,6 @@
__builtin_unreachable(); \ __builtin_unreachable(); \
} while (0) } while (0)
#if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__)
#define __randomize_layout __attribute__((randomize_layout))
#define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
#define randomized_struct_fields_start struct {
#define randomized_struct_fields_end } __randomize_layout;
#endif
/* /*
* GCC 'asm goto' miscompiles certain code sequences: * GCC 'asm goto' miscompiles certain code sequences:
* *

View File

@ -242,15 +242,15 @@ struct ftrace_likely_data {
# define __latent_entropy # define __latent_entropy
#endif #endif
#ifndef __randomize_layout #if defined(RANDSTRUCT) && !defined(__CHECKER__)
# define __randomize_layout __designated_init __attribute__((randomize_layout))
# define __no_randomize_layout __attribute__((no_randomize_layout))
/* This anon struct can add padding, so only enable it under randstruct. */
# define randomized_struct_fields_start struct {
# define randomized_struct_fields_end } __randomize_layout;
#else
# define __randomize_layout __designated_init # define __randomize_layout __designated_init
#endif
#ifndef __no_randomize_layout
# define __no_randomize_layout # define __no_randomize_layout
#endif
#ifndef randomized_struct_fields_start
# define randomized_struct_fields_start # define randomized_struct_fields_start
# define randomized_struct_fields_end # define randomized_struct_fields_end
#endif #endif

View File

@ -32,11 +32,11 @@
#else #else
#define MODULE_VERMAGIC_MODVERSIONS "" #define MODULE_VERMAGIC_MODVERSIONS ""
#endif #endif
#ifdef RANDSTRUCT_PLUGIN #ifdef RANDSTRUCT
#include <generated/randomize_layout_hash.h> #include <generated/randomize_layout_hash.h>
#define MODULE_RANDSTRUCT_PLUGIN "RANDSTRUCT_PLUGIN_" RANDSTRUCT_HASHED_SEED #define MODULE_RANDSTRUCT "RANDSTRUCT_" RANDSTRUCT_HASHED_SEED
#else #else
#define MODULE_RANDSTRUCT_PLUGIN #define MODULE_RANDSTRUCT
#endif #endif
#define VERMAGIC_STRING \ #define VERMAGIC_STRING \
@ -44,6 +44,6 @@
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \ MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \ MODULE_VERMAGIC_MODULE_UNLOAD MODULE_VERMAGIC_MODVERSIONS \
MODULE_ARCH_VERMAGIC \ MODULE_ARCH_VERMAGIC \
MODULE_RANDSTRUCT_PLUGIN MODULE_RANDSTRUCT
#endif /* _LINUX_VERMAGIC_H */ #endif /* _LINUX_VERMAGIC_H */

View File

@ -48,7 +48,7 @@ unsigned int __read_mostly sysctl_oops_all_cpu_backtrace;
int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE; int panic_on_oops = CONFIG_PANIC_ON_OOPS_VALUE;
static unsigned long tainted_mask = static unsigned long tainted_mask =
IS_ENABLED(CONFIG_GCC_PLUGIN_RANDSTRUCT) ? (1 << TAINT_RANDSTRUCT) : 0; IS_ENABLED(CONFIG_RANDSTRUCT) ? (1 << TAINT_RANDSTRUCT) : 0;
static int pause_on_oops; static int pause_on_oops;
static int pause_on_oops_flag; static int pause_on_oops_flag;
static DEFINE_SPINLOCK(pause_on_oops_lock); static DEFINE_SPINLOCK(pause_on_oops_lock);

View File

@ -24,8 +24,8 @@ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) \
gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) \
+= -DRANDSTRUCT_PLUGIN += -DRANDSTRUCT
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) \ gcc-plugin-cflags-$(CONFIG_RANDSTRUCT_PERFORMANCE) \
+= -fplugin-arg-randomize_layout_plugin-performance-mode += -fplugin-arg-randomize_layout_plugin-performance-mode
gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so gcc-plugin-$(CONFIG_GCC_PLUGIN_STACKLEAK) += stackleak_plugin.so

View File

@ -46,44 +46,6 @@ config GCC_PLUGIN_LATENT_ENTROPY
* https://grsecurity.net/ * https://grsecurity.net/
* https://pax.grsecurity.net/ * https://pax.grsecurity.net/
config GCC_PLUGIN_RANDSTRUCT
bool "Randomize layout of sensitive kernel structures"
select MODVERSIONS if MODULES
help
If you say Y here, the layouts of structures that are entirely
function pointers (and have not been manually annotated with
__no_randomize_layout), or structures that have been explicitly
marked with __randomize_layout, will be randomized at compile-time.
This can introduce the requirement of an additional information
exposure vulnerability for exploits targeting these structure
types.
Enabling this feature will introduce some 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).
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.
This plugin was ported from grsecurity/PaX. More information at:
* https://grsecurity.net/
* https://pax.grsecurity.net/
config GCC_PLUGIN_RANDSTRUCT_PERFORMANCE
bool "Use cacheline-aware structure randomization"
depends on GCC_PLUGIN_RANDSTRUCT
depends on !COMPILE_TEST # do not reduce test coverage
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 GCC_PLUGIN_ARM_SSP_PER_TASK config GCC_PLUGIN_ARM_SSP_PER_TASK
bool bool
depends on GCC_PLUGINS && ARM depends on GCC_PLUGINS && ARM

View File

@ -266,4 +266,66 @@ config ZERO_CALL_USED_REGS
endmenu endmenu
choice
prompt "Randomize layout of sensitive kernel structures"
default RANDSTRUCT_FULL if COMPILE_TEST && GCC_PLUGINS
default RANDSTRUCT_NONE
help
If you enable this, the layouts of structures that are entirely
function pointers (and have not been manually annotated with
__no_randomize_layout), or structures that have been explicitly
marked with __randomize_layout, will be randomized at compile-time.
This can introduce the requirement of an additional information
exposure vulnerability for exploits targeting these structure
types.
Enabling this feature will introduce some 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).
The seed used for compilation is located at
scripts/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".
config RANDSTRUCT_NONE
bool "Disable structure layout randomization"
help
Build normally: no structure layout randomization.
config RANDSTRUCT_FULL
bool "Fully randomize structure layout"
depends on GCC_PLUGINS
select MODVERSIONS if MODULES
help
Fully randomize the member layout of sensitive
structures as much as possible, which may have both a
memory size and performance impact.
config RANDSTRUCT_PERFORMANCE
bool "Limit randomization of structure layout to cache-lines"
depends on GCC_PLUGINS
select MODVERSIONS if MODULES
help
Randomization of sensitive kernel structures will make a
best effort at restricting randomization to cacheline-sized
groups of members. It will further not randomize bitfields
in structures. This reduces the performance hit of RANDSTRUCT
at the cost of weakened randomization.
endchoice
config RANDSTRUCT
def_bool !RANDSTRUCT_NONE
config GCC_PLUGIN_RANDSTRUCT
def_bool GCC_PLUGINS && RANDSTRUCT
help
Use GCC plugin to randomize structure layout.
This plugin was ported from grsecurity/PaX. More
information at:
* https://grsecurity.net/
* https://pax.grsecurity.net/
endmenu endmenu