aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-07-05 00:41:31 -0400
committerKees Cook <keescook@chromium.org>2017-07-05 00:41:31 -0400
commitd1185a8c5dd21182012e6dd531b00fd72f4d30cb (patch)
tree1c394d6e27bad00e0f3aba4e59ca19823d0486d5 /scripts
parent6f7da290413ba713f0cdd9ff1a2a9bb129ef4f6c (diff)
parent03232e0ddebdc2c9d088e6748075704885f039a5 (diff)
Merge branch 'merge/randstruct' into for-next/gcc-plugins
Diffstat (limited to 'scripts')
-rw-r--r--scripts/Makefile.gcc-plugins4
-rw-r--r--scripts/gcc-plugins/.gitignore1
-rw-r--r--scripts/gcc-plugins/Makefile8
-rw-r--r--scripts/gcc-plugins/gcc-common.h12
-rw-r--r--scripts/gcc-plugins/gen-random-seed.sh8
-rw-r--r--scripts/gcc-plugins/randomize_layout_plugin.c1028
6 files changed, 1061 insertions, 0 deletions
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 82335533620e..2e0e2eaa397f 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -29,6 +29,10 @@ ifdef CONFIG_GCC_PLUGINS
29 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose 29 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK_VERBOSE) += -fplugin-arg-structleak_plugin-verbose
30 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN 30 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_STRUCTLEAK) += -DSTRUCTLEAK_PLUGIN
31 31
32 gcc-plugin-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += randomize_layout_plugin.so
33 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT) += -DRANDSTRUCT_PLUGIN
34 gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_RANDSTRUCT_PERFORMANCE) += -fplugin-arg-randomize_layout_plugin-performance-mode
35
32 GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y)) 36 GCC_PLUGINS_CFLAGS := $(strip $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) $(gcc-plugin-cflags-y))
33 37
34 export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR 38 export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN GCC_PLUGIN_SUBDIR
diff --git a/scripts/gcc-plugins/.gitignore b/scripts/gcc-plugins/.gitignore
new file mode 100644
index 000000000000..de92ed9e3d83
--- /dev/null
+++ b/scripts/gcc-plugins/.gitignore
@@ -0,0 +1 @@
randomize_layout_seed.h
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 8b29dc17c73c..214eb2335c31 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -18,6 +18,14 @@ endif
18 18
19export HOSTLIBS 19export HOSTLIBS
20 20
21$(obj)/randomize_layout_plugin.o: $(objtree)/$(obj)/randomize_layout_seed.h
22quiet_cmd_create_randomize_layout_seed = GENSEED $@
23cmd_create_randomize_layout_seed = \
24 $(CONFIG_SHELL) $(srctree)/$(src)/gen-random-seed.sh $@ $(objtree)/include/generated/randomize_layout_hash.h
25$(objtree)/$(obj)/randomize_layout_seed.h: FORCE
26 $(call if_changed,create_randomize_layout_seed)
27targets = randomize_layout_seed.h randomize_layout_hash.h
28
21$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p))) 29$(HOSTLIBS)-y := $(foreach p,$(GCC_PLUGIN),$(if $(findstring /,$(p)),,$(p)))
22always := $($(HOSTLIBS)-y) 30always := $($(HOSTLIBS)-y)
23 31
diff --git a/scripts/gcc-plugins/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index b232ab15624c..6948898b3cdf 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -63,6 +63,13 @@
63#endif 63#endif
64 64
65#if BUILDING_GCC_VERSION >= 4006 65#if BUILDING_GCC_VERSION >= 4006
66/*
67 * The c-family headers were moved into a subdirectory in GCC version
68 * 4.7, but most plugin-building users of GCC 4.6 are using the Debian
69 * or Ubuntu package, which has an out-of-tree patch to move this to the
70 * same location as found in 4.7 and later:
71 * https://sources.debian.net/src/gcc-4.6/4.6.3-14/debian/patches/pr45078.diff/
72 */
66#include "c-family/c-common.h" 73#include "c-family/c-common.h"
67#else 74#else
68#include "c-common.h" 75#include "c-common.h"
@@ -946,4 +953,9 @@ static inline void debug_gimple_stmt(const_gimple s)
946 get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep) 953 get_inner_reference(exp, pbitsize, pbitpos, poffset, pmode, punsignedp, preversep, pvolatilep)
947#endif 954#endif
948 955
956#if BUILDING_GCC_VERSION < 7000
957#define SET_DECL_ALIGN(decl, align) DECL_ALIGN(decl) = (align)
958#define SET_DECL_MODE(decl, mode) DECL_MODE(decl) = (mode)
959#endif
960
949#endif 961#endif
diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh
new file mode 100644
index 000000000000..7514850f4815
--- /dev/null
+++ b/scripts/gcc-plugins/gen-random-seed.sh
@@ -0,0 +1,8 @@
1#!/bin/sh
2
3if [ ! -f "$1" ]; then
4 SEED=`od -A n -t x8 -N 32 /dev/urandom | tr -d ' \n'`
5 echo "const char *randstruct_seed = \"$SEED\";" > "$1"
6 HASH=`echo -n "$SEED" | sha256sum | cut -d" " -f1 | tr -d ' \n'`
7 echo "#define RANDSTRUCT_HASHED_SEED \"$HASH\"" > "$2"
8fi
diff --git a/scripts/gcc-plugins/randomize_layout_plugin.c b/scripts/gcc-plugins/randomize_layout_plugin.c
new file mode 100644
index 000000000000..cdaac8c66734
--- /dev/null
+++ b/scripts/gcc-plugins/randomize_layout_plugin.c
@@ -0,0 +1,1028 @@
1/*
2 * Copyright 2014-2016 by Open Source Security, Inc., Brad Spengler <spender@grsecurity.net>
3 * and PaX Team <pageexec@freemail.hu>
4 * Licensed under the GPL v2
5 *
6 * Note: the choice of the license means that the compilation process is
7 * NOT 'eligible' as defined by gcc's library exception to the GPL v3,
8 * but for the kernel it doesn't matter since it doesn't link against
9 * any of the gcc libraries
10 *
11 * Usage:
12 * $ # for 4.5/4.6/C based 4.7
13 * $ gcc -I`gcc -print-file-name=plugin`/include -I`gcc -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c
14 * $ # for C++ based 4.7/4.8+
15 * $ g++ -I`g++ -print-file-name=plugin`/include -I`g++ -print-file-name=plugin`/include/c-family -fPIC -shared -O2 -o randomize_layout_plugin.so randomize_layout_plugin.c
16 * $ gcc -fplugin=./randomize_layout_plugin.so test.c -O2
17 */
18
19#include "gcc-common.h"
20#include "randomize_layout_seed.h"
21
22#if BUILDING_GCC_MAJOR < 4 || (BUILDING_GCC_MAJOR == 4 && BUILDING_GCC_MINOR < 7)
23#error "The RANDSTRUCT plugin requires GCC 4.7 or newer."
24#endif
25
26#define ORIG_TYPE_NAME(node) \
27 (TYPE_NAME(TYPE_MAIN_VARIANT(node)) != NULL_TREE ? ((const unsigned char *)IDENTIFIER_POINTER(TYPE_NAME(TYPE_MAIN_VARIANT(node)))) : (const unsigned char *)"anonymous")
28
29#define INFORM(loc, msg, ...) inform(loc, "randstruct: " msg, ##__VA_ARGS__)
30#define MISMATCH(loc, how, ...) INFORM(loc, "casting between randomized structure pointer types (" how "): %qT and %qT\n", __VA_ARGS__)
31
32__visible int plugin_is_GPL_compatible;
33
34static int performance_mode;
35
36static struct plugin_info randomize_layout_plugin_info = {
37 .version = "201402201816vanilla",
38 .help = "disable\t\t\tdo not activate plugin\n"
39 "performance-mode\tenable cacheline-aware layout randomization\n"
40};
41
42struct whitelist_entry {
43 const char *pathname;
44 const char *lhs;
45 const char *rhs;
46};
47
48static const struct whitelist_entry whitelist[] = {
49 /* NIU overloads mapping with page struct */
50 { "drivers/net/ethernet/sun/niu.c", "page", "address_space" },
51 /* unix_skb_parms via UNIXCB() buffer */
52 { "net/unix/af_unix.c", "unix_skb_parms", "char" },
53 /* big_key payload.data struct splashing */
54 { "security/keys/big_key.c", "path", "void *" },
55 /* walk struct security_hook_heads as an array of struct list_head */
56 { "security/security.c", "list_head", "security_hook_heads" },
57 { }
58};
59
60/* from old Linux dcache.h */
61static inline unsigned long
62partial_name_hash(unsigned long c, unsigned long prevhash)
63{
64 return (prevhash + (c << 4) + (c >> 4)) * 11;
65}
66static inline unsigned int
67name_hash(const unsigned char *name)
68{
69 unsigned long hash = 0;
70 unsigned int len = strlen((const char *)name);
71 while (len--)
72 hash = partial_name_hash(*name++, hash);
73 return (unsigned int)hash;
74}
75
76static tree handle_randomize_layout_attr(tree *node, tree name, tree args, int flags, bool *no_add_attrs)
77{
78 tree type;
79
80 *no_add_attrs = true;
81 if (TREE_CODE(*node) == FUNCTION_DECL) {
82 error("%qE attribute does not apply to functions (%qF)", name, *node);
83 return NULL_TREE;
84 }
85
86 if (TREE_CODE(*node) == PARM_DECL) {
87 error("%qE attribute does not apply to function parameters (%qD)", name, *node);
88 return NULL_TREE;
89 }
90
91 if (TREE_CODE(*node) == VAR_DECL) {
92 error("%qE attribute does not apply to variables (%qD)", name, *node);
93 return NULL_TREE;
94 }
95
96 if (TYPE_P(*node)) {
97 type = *node;
98 } else {
99 gcc_assert(TREE_CODE(*node) == TYPE_DECL);
100 type = TREE_TYPE(*node);
101 }
102
103 if (TREE_CODE(type) != RECORD_TYPE) {
104 error("%qE attribute used on %qT applies to struct types only", name, type);
105 return NULL_TREE;
106 }
107
108 if (lookup_attribute(IDENTIFIER_POINTER(name), TYPE_ATTRIBUTES(type))) {
109 error("%qE attribute is already applied to the type %qT", name, type);
110 return NULL_TREE;