|
|
Message-Id: <1462468869-6210-3-git-send-email-michael.leibowitz@intel.com>
Date: Thu, 5 May 2016 10:21:08 -0700
From: Michael Leibowitz <michael.leibowitz@...el.com>
To: spender@...ecurity.net,
kernel-hardening@...ts.openwall.com,
keescook@...omium.org,
re.emese@...il.com,
pageexec@...email.hu
Cc: michael.leibowitz@...el.com
Subject: [RFC 2/3] Enable the RANDSTRUCT plugin
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.
+
+ 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.
+
+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);
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
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.