The kernel already has a mechanism to free up code and data memory that
is only used during kernel or module initialization.
This plugin will teach the compiler to find more such code and data that
can be freed after initialization.
It has two passes. The first one tries to find all functions that
can be become __init/__exit. The second one moves string constants
(local variables and function string arguments marked by
the nocapture attribute) only referenced in __init/__exit functions
to the __initconst/__exitconst sections.
It reduces memory usage. This plugin can be useful for embedded systems.
The instrumentation pass of the latent_entropy plugin must run after
the initify plugin to increase coverage.
Signed-off-by: Emese Revfy
---
arch/Kconfig | 23 +
include/asm-generic/vmlinux.lds.h|2 +
scripts/Makefile.gcc-plugins |4 +
scripts/gcc-plugins/initify_plugin.c | 1147 ++
4 files changed, 1176 insertions(+)
create mode 100644 scripts/gcc-plugins/initify_plugin.c
diff --git a/arch/Kconfig b/arch/Kconfig
index 9f8c6ee..35b01a4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -417,6 +417,29 @@ config GCC_PLUGIN_LATENT_ENTROPY
* https://grsecurity.net/
* https://pax.grsecurity.net/
+config GCC_PLUGIN_INITIFY
+ bool "Free more kernel memory after init"
+ depends on GCC_PLUGINS
+ help
+ The kernel has a mechanism to free up code and data memory that is
+ only used during kernel or module initialization. Enabling this
+ feature will teach the compiler to find more such code and data
+ that can be freed after initialization.
+
+ This plugin is the part of grsecurity/PaX. More information at:
+ * https://grsecurity.net/
+ * https://pax.grsecurity.net/
+
+config GCC_PLUGIN_INITIFY_VERBOSE
+ bool "Verbose"
+ depends on GCC_PLUGIN_INITIFY
+ help
+ Print all initified strings and all functions which should be
+ __init/__exit.
+ Note that the candidates identified for __init/__exit markings
+ depend on the current kernel configuration and thus should be verified
+ manually before the source code is patched.
+
config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/include/asm-generic/vmlinux.lds.h
b/include/asm-generic/vmlinux.lds.h
index 6a67ab9..651980b 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -523,6 +523,7 @@
MEM_DISCARD(init.data) \
KERNEL_CTORS() \
MCOUNT_REC()\
+ *(.init.rodata.str) \
*(.init.rodata) \
FTRACE_EVENTS() \
TRACE_SYSCALLS()\
@@ -547,6 +548,7 @@
#define EXIT_DATA \
*(.exit.data) \
MEM_DISCARD(exit.data) \
+ *(.exit.rodata.str) \
MEM_DISCARD(exit.rodata)
#define EXIT_TEXT \
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 1f922df..0ce8392 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -12,6 +12,10 @@ ifdef CONFIG_GCC_PLUGINS
DISABLE_LATENT_ENTROPY_PLUGIN +=
-fplugin-arg-latent_entropy_plugin-disable
endif
+ gcc-plugin-$(CONFIG_GCC_PLUGIN_INITIFY) += initify_plugin.so
+ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY) += -DINITIFY_PLUGIN
-fplugin-arg-initify_plugin-search_init_exit_functions
+ gcc-plugin-cflags-$(CONFIG_GCC_PLUGIN_INITIFY_VERBOSE)+=
-fplugin-arg-initify_plugin-verbose
+
ifdef CONFIG_GCC_PLUGIN_SANCOV
ifeq ($(CFLAGS_KCOV),)
# It is needed because of the gcc-plugin.sh and gcc version checks.
diff --git a/scripts/gcc-plugins/initify_plugin.c
b/scripts/gcc-plugins/initify_plugin.c
new file mode 100644
index 000..d5dfce5
--- /dev/null
+++ b/scripts/gcc-plugins/initify_plugin.c
@@ -0,0 +1,1147 @@
+/*
+ * Copyright 2015-2016 by Emese Revfy
+ * Licensed under the GPL v2
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/initify
+ *
+ * This plugin has two passes. The first one tries to find all functions that
+ * can be become __init/__exit. The second one moves string constants
+ * (local variables and function string arguments marked by
+ * the nocapture attribute) only referenced in __init/__exit functions
+ * to __initconst/__exitconst sections.
+ * Based on an idea from Mathias Krause .
+ *
+ * Th