Commit 59005b0c authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'gcc-plugins-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull GCC plugin updates from Kees Cook:
 "The big part is the randstruct plugin infrastructure.

  This is the first of two expected pull requests for randstruct since
  there are dependencies in other trees that would be easier to merge
  once those have landed. Notably, the IPC allocation refactoring in
  -mm, and many trivial merge conflicts across several trees when
  applying the __randomize_layout annotation.

  As a result, it seemed like I should send this now since it is
  relatively self-contained, and once the rest of the trees have landed,
  send the annotation patches. I'm expecting the final phase of
  randstruct (automatic struct selection) will land for v4.14, but if
  its other tree dependencies actually make it for v4.13, I can send
  that merge request too.

  Summary:

  - typo fix in Kconfig (Jean Delvare)

  - randstruct infrastructure"

* tag 'gcc-plugins-v4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux:
  ARM: Prepare for randomized task_struct
  randstruct: Whitelist NIU struct page overloading
  randstruct: Whitelist big_key path struct overloading
  randstruct: Whitelist UNIXCB cast
  randstruct: Whitelist struct security_hook_heads cast
  gcc-plugins: Add the randstruct plugin
  Fix English in description of GCC_PLUGIN_STRUCTLEAK
  compiler: Add __designated_init annotation
  gcc-plugins: Detail c-common.h location for GCC 4.6
parents 2cc7b4ca d1185a8c
......@@ -206,6 +206,8 @@ r200_reg_safe.h
r300_reg_safe.h
r420_reg_safe.h
r600_reg_safe.h
randomize_layout_hash.h
randomize_layout_seed.h
recordmcount
relocs
rlim_names.h
......
......@@ -425,7 +425,7 @@ config GCC_PLUGIN_STRUCTLEAK
bool "Force initialization of variables containing userspace addresses"
depends on GCC_PLUGINS
help
This plugin zero-initializes any structures that containing a
This plugin zero-initializes any structures containing a
__user attribute. This can prevent some classes of information
exposures.
......@@ -443,6 +443,45 @@ config GCC_PLUGIN_STRUCTLEAK_VERBOSE
initialized. Since not all existing initializers are detected
by the plugin, this can produce false positive warnings.
config GCC_PLUGIN_RANDSTRUCT
bool "Randomize layout of sensitive kernel structures"
depends on GCC_PLUGINS
select MODVERSIONS if MODULES
help
If you say Y here, the layouts of structures explicitly
marked by __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-plgins/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.7 or newer.
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
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
......
......@@ -87,6 +87,8 @@
#define CALGN(code...)
#endif
#define IMM12_MASK 0xfff
/*
* Enable and disable interrupts
*/
......
......@@ -797,7 +797,10 @@ ENTRY(__switch_to)
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
ldr r7, [r2, #TI_TASK]
ldr r8, =__stack_chk_guard
ldr r7, [r7, #TSK_STACK_CANARY]
.if (TSK_STACK_CANARY > IMM12_MASK)
add r7, r7, #TSK_STACK_CANARY & ~IMM12_MASK
.endif
ldr r7, [r7, #TSK_STACK_CANARY & IMM12_MASK]
#endif
#ifdef CONFIG_CPU_USE_DOMAINS
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
......
......@@ -25,11 +25,6 @@
ldr \rd, [\rn, #VMA_VM_FLAGS]
.endm
.macro tsk_mm, rd, rn
ldr \rd, [\rn, #TI_TASK]
ldr \rd, [\rd, #TSK_ACTIVE_MM]
.endm
/*
* act_mm - get current->active_mm
*/
......@@ -37,7 +32,10 @@
bic \rd, sp, #8128
bic \rd, \rd, #63
ldr \rd, [\rd, #TI_TASK]
ldr \rd, [\rd, #TSK_ACTIVE_MM]
.if (TSK_ACTIVE_MM > IMM12_MASK)
add \rd, \rd, #TSK_ACTIVE_MM & ~IMM12_MASK
.endif
ldr \rd, [\rd, #TSK_ACTIVE_MM & IMM12_MASK]
.endm
/*
......
......@@ -223,6 +223,11 @@
/* Mark a function definition as prohibited from being cloned. */
#define __noclone __attribute__((__noclone__, __optimize__("no-tracer")))
#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
......@@ -294,6 +299,14 @@
#define __no_sanitize_address __attribute__((no_sanitize_address))
#endif
#if GCC_VERSION >= 50100
/*
* Mark structures as requiring designated initializers.
* https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
*/
#define __designated_init __attribute__((designated_init))
#endif
#endif /* gcc version >= 40000 specific checks */
#if !defined(__noclone)
......
......@@ -436,10 +436,22 @@ static __always_inline void __write_once_size(volatile void *p, void *res, int s
# define __attribute_const__ /* unimplemented */
#endif
#ifndef __designated_init
# define __designated_init
#endif
#ifndef __latent_entropy
# define __latent_entropy
#endif
#ifndef __randomize_layout
# define __randomize_layout __designated_init
#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.
......
......@@ -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
......@@ -29,6 +29,10 @@ ifdef CONFIG_GCC_PLUGINS
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN
gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN
gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode
GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR
......
randomize_layout_seed.h
......@@ -18,6 +18,14 @@ endif
export HOSTLIBS
$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
quiet_cmd_create_randomize_layout_seed = GENSEED $@
cmd_create_randomize_layout_seed = \
$(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h
$(objtree)/$(obj)/randomize_layout_seed.h: FORCE
$(call if_changed,create_randomize_layout_seed)
targets = randomize_layout_seed.h randomize_layout_hash.h
$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
always := $($(HOSTLIBS)-y)
......
......@@ -63,6 +63,13 @@
#endif
#if BUILDING_GCC_VERSION >= 4006
/*
* The c-family headers were moved into a subdirectory in GCC version
* 4.7, but most plugin-building users of GCC 4.6 are using the Debian
* or Ubuntu package, which has an out-of-tree patch to move this to the
* same location as found in 4.7 and later:
* https://sources.debian.net/src/gcc-4.6/4.6.3-14/debian/patches/pr45078.diff/
*/
#include "c-family/c-common.h"
#else
#include "c-common.h"
......@@ -946,4 +953,9 @@ static inline void debug_gimple_stmt(const_gimple s)
get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
#endif
#if BUILDING_GCC_VERSION < 7000
#define SET_DECL_ALIGN(decl, align) DECL_ALIGN(decl) = (align)
#define SET_DECL_MODE(decl, mode) DECL_MODE(decl) = (mode)
#endif
#endif
#!/bin/sh
if [ ! -f "$1" ]; then
SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
echo "const char *randstruct_seed = \"$SEED\";" > "$1"
HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'`
echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"
fi
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment