[PATCH v4 0/4] Introduce the latent_entropy gcc plugin

2016-06-20 Thread Emese Revfy
I would like to introduce the latent_entropy gcc plugin. This plugin
mitigates the problem of the kernel having too little entropy during and
after boot for generating crypto keys.

This plugin mixes random values into the latent_entropy global variable
in functions marked by the __latent_entropy attribute.
The value of this global variable is added to the kernel entropy pool
to increase the entropy.

It is a CII project supported by the Linux Foundation.

The latent_entropy plugin was ported from grsecurity/PaX originally written
by the PaX Team. You can find more about the plugin here:
https://grsecurity.net/pipermail/grsecurity/2012-July/001093.html

The plugin supports all gcc version from 4.5 to 6.0.

I do some changes above the PaX version. The important one is mixing
the stack pointer into the global variable too.
You can find more about the changes here:
https://github.com/ephox-gcc-plugins/latent_entropy

This patch set is based on the "Introduce GCC plugin infrastructure"
patch set (git/mmarek/kbuild.git#kbuild HEAD: 543c37cb165049c3be).

Emese Revfy (4):
 Add support for passing gcc plugin arguments
 Add the latent_entropy gcc plugin
 Mark functions with the latent_entropy attribute
 Add the extra_latent_entropy kernel parameter


Changes from v3:
  * Fix disabling latent_entropy on some powerpc files
(Reported-by: Kees Cook )
  * Truncate the lines into <= 80 columns to follow the kernel coding style
(Suggested-by: Kees Cook )

Changes from v2:
  * Moved the passing of gcc plugin arguments into a separate patch
(Suggested-by: Kees Cook )
  * Mix the global entropy variable with the stack pointer
(latent_entropy_plugin.c)
  * Handle tail calls (latent_entropy_plugin.c)
  * Fix some indentation related warnings suggested by checkpatch.pl
(latent_entropy_plugin.c)
  * Commented some latent_entropy plugin code
(Suggested-by: Kees Cook )

Changes from v1:
  * Remove unnecessary ifdefs
(Suggested-by: Kees Cook )
  * Separate the two definitions of add_latent_entropy()
(Suggested-by: Kees Cook )
  * Removed unnecessary global variable (latent_entropy_plugin.c)
  * About the latent_entropy gcc attribute (latent_entropy_plugin.c)
  * Measure the boot time performance impact of the latent_entropy plugin
(arch/Kconfig)

---
 Documentation/kernel-parameters.txt |   5 +
 arch/Kconfig|  23 +
 arch/powerpc/kernel/Makefile|   4 +
 block/blk-softirq.c |   2 +-
 drivers/char/random.c   |   6 +-
 fs/namespace.c  |   1 +
 include/linux/compiler-gcc.h|   7 +
 include/linux/compiler.h|   4 +
 include/linux/fdtable.h |   2 +-
 include/linux/genhd.h   |   2 +-
 include/linux/init.h|   5 +-
 include/linux/random.h  |  14 +-
 init/main.c |   1 +
 kernel/fork.c   |   7 +-
 kernel/rcu/tiny.c   |   2 +-
 kernel/rcu/tree.c   |   2 +-
 kernel/sched/fair.c |   2 +-
 kernel/softirq.c|   4 +-
 kernel/time/timer.c |   2 +-
 lib/irq_poll.c  |   2 +-
 lib/random32.c  |   2 +-
 mm/page_alloc.c |  31 ++
 net/core/dev.c  |   4 +-
 scripts/Makefile.gcc-plugins|  10 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 639 
 26 files changed, 760 insertions(+), 24 deletions(-)


[PATCH v4 1/4] Add support for passing gcc plugin arguments

2016-06-20 Thread Emese Revfy

Signed-off-by: Emese Revfy 
---
 scripts/Makefile.gcc-plugins | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 5e22b60..da7f86c 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -19,7 +19,7 @@ ifdef CONFIG_GCC_PLUGINS
 endif
   endif
 
-  GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
+  GCC_PLUGINS_CFLAGS := $(strip $(addprefix 
-fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) 
$(gcc-plugin-cflags-y))
 
   export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN
 
-- 
2.8.1



[PATCH v4 2/4] Add the latent_entropy gcc plugin

2016-06-20 Thread Emese Revfy
This plugin mitigates the problem of the kernel having too little entropy
during and after boot for generating crypto keys.

It creates a local variable in every marked function. The value of
this variable is modified by randomly chosen operations (add, xor and rol)
and random values (gcc generates them at compile time and the stack pointer
at runtime).
It depends on the control flow (e.g., loops, conditions).

Before the function returns the plugin writes this local variable
into the latent_entropy global variable. The value of this global variable
is added to the kernel entropy pool in do_one_initcall() and _do_fork().

Signed-off-by: Emese Revfy 
---
 arch/Kconfig|  18 +
 arch/powerpc/kernel/Makefile|   4 +
 include/linux/random.h  |  10 +
 init/main.c |   1 +
 kernel/fork.c   |   1 +
 mm/page_alloc.c |   5 +
 scripts/Makefile.gcc-plugins|   8 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 639 
 9 files changed, 686 insertions(+), 1 deletion(-)
 create mode 100644 scripts/gcc-plugins/latent_entropy_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 05f1e95..4b7cc2f 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -393,6 +393,24 @@ config GCC_PLUGIN_SANCOV
  gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
  by Dmitry Vyukov .
 
+config GCC_PLUGIN_LATENT_ENTROPY
+   bool "Generate some entropy during boot and runtime"
+   depends on GCC_PLUGINS
+   help
+ By saying Y here the kernel will instrument some kernel code to
+ extract some entropy from both original and artificially created
+ program state.  This will help especially embedded systems where
+ there is little 'natural' source of entropy normally.  The cost
+ is some slowdown of the boot process (about 0.5%) and fork and
+ irq processing.
+
+ Note that entropy extracted this way is not cryptographically
+ secure!
+
+ This plugin was ported from grsecurity/PaX. More information at:
+  * https://grsecurity.net/
+  * https://pax.grsecurity.net/
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2da380f..01935b8 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -15,6 +15,10 @@ CFLAGS_btext.o   += -fPIC
 endif
 
 ifdef CONFIG_FUNCTION_TRACER
+CFLAGS_cputable.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_init.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_btext.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_prom.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
 # Do not trace early boot code
 CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
diff --git a/include/linux/random.h b/include/linux/random.h
index e47e533..752e7df 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -18,6 +18,16 @@ struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+
+#if defined(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) && !defined(__CHECKER__)
+static inline void add_latent_entropy(void)
+{
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+}
+#else
+static inline void add_latent_entropy(void) {}
+#endif
+
 extern void add_input_randomness(unsigned int type, unsigned int code,
 unsigned int value);
 extern void add_interrupt_randomness(int irq, int irq_flags);
diff --git a/init/main.c b/init/main.c
index 4c17fda..07e4174 100644
--- a/init/main.c
+++ b/init/main.c
@@ -781,6 +781,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
}
WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf);
 
+   add_latent_entropy();
return ret;
 }
 
diff --git a/kernel/fork.c b/kernel/fork.c
index 5c2c355..fd1b3c2 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1761,6 +1761,7 @@ long _do_fork(unsigned long clone_flags,
 
p = copy_process(clone_flags, stack_start, stack_size,
 child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
+   add_latent_entropy();
/*
 * Do this prior waking up the new thread - the thread pointer
 * might get invalid after that point, if the thread exits quickly.
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f8f3bfc..d10324e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1234,6 +1234,11 @@ static void __free_pages_ok(struct page *page, unsigned 
int order)
local_irq_restore(flags);
 }
 
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+volatile u64 latent_entropy;
+EXPORT_SYMBOL(latent_entropy);
+#endif

[PATCH v4 3/4] Mark functions with the latent_entropy attribute

2016-06-20 Thread Emese Revfy
The latent_entropy gcc attribute can be only on functions and variables.
If it is on a function then the plugin will instrument it. If the attribute
is on a variable then the plugin will initialize it with a random value.
The variable must be an integer, an integer array type or a structure
with integer fields.

These functions have been selected because they are init functions or
are called at random times or they have variable loops.

Signed-off-by: Emese Revfy 
---
 block/blk-softirq.c  | 2 +-
 drivers/char/random.c| 6 +++---
 fs/namespace.c   | 1 +
 include/linux/compiler-gcc.h | 7 +++
 include/linux/compiler.h | 4 
 include/linux/fdtable.h  | 2 +-
 include/linux/genhd.h| 2 +-
 include/linux/init.h | 5 +++--
 include/linux/random.h   | 4 ++--
 kernel/fork.c| 6 --
 kernel/rcu/tiny.c| 2 +-
 kernel/rcu/tree.c| 2 +-
 kernel/sched/fair.c  | 2 +-
 kernel/softirq.c | 4 ++--
 kernel/time/timer.c  | 2 +-
 lib/irq_poll.c   | 2 +-
 lib/random32.c   | 2 +-
 mm/page_alloc.c  | 2 +-
 net/core/dev.c   | 4 ++--
 19 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index 53b1737..489eab8 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
  * Softirq action handler - move entries to local list and loop over them
  * while passing them to the queue registered handler.
  */
-static void blk_done_softirq(struct softirq_action *h)
+static __latent_entropy void blk_done_softirq(struct softirq_action *h)
 {
struct list_head *cpu_list, local_list;
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0158d3b..6cca3ed 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -443,9 +443,9 @@ struct entropy_store {
 };
 
 static void push_to_pool(struct work_struct *work);
-static __u32 input_pool_data[INPUT_POOL_WORDS];
-static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
-static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
+static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
+static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
+static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
 
 static struct entropy_store input_pool = {
.poolinfo = &poolinfo_table[0],
diff --git a/fs/namespace.c b/fs/namespace.c
index 4fb1691..0951eca 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2778,6 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct 
user_namespace *user_ns)
return new_ns;
 }
 
+__latent_entropy
 struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace 
*ns,
struct user_namespace *user_ns, struct fs_struct *new_fs)
 {
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index e294939..0ef8329 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -188,6 +188,13 @@
 #endif /* GCC_VERSION >= 40300 */
 
 #if GCC_VERSION >= 40500
+
+#ifndef __CHECKER__
+#ifdef LATENT_ENTROPY_PLUGIN
+#define __latent_entropy __attribute__((latent_entropy))
+#endif
+#endif
+
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 793c082..c65327b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile 
void *p, void *res, int s
 # define __attribute_const__   /* unimplemented */
 #endif
 
+#ifndef __latent_entropy
+# define __latent_entropy
+#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/fdtable.h b/include/linux/fdtable.h
index 5295535..9852c7e 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *);
 void put_files_struct(struct files_struct *fs);
 void reset_files_struct(struct files_struct *);
 int unshare_files(struct files_struct **);
-struct files_struct *dup_fd(struct files_struct *, int *);
+struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
int (*)(const void *, struct file *, unsigned),
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 359a8e4..8736c1f 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, 
unsigned int mask);
 extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
 
 /* drivers/char/random.c */
-extern void add_disk_randomness(stru

[PATCH v4 4/4] Add the extra_latent_entropy kernel parameter

2016-06-20 Thread Emese Revfy
When extra_latent_entropy is passed on the kernel command line,
entropy will be extracted from up to the first 4GB of RAM while the
runtime memory allocator is being initialized.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 Documentation/kernel-parameters.txt |  5 +
 arch/Kconfig|  5 +
 mm/page_alloc.c | 26 ++
 3 files changed, 36 insertions(+)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 82b42c9..d870702 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2862,6 +2862,11 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
the specified number of seconds.  This is to be used if
your oopses keep scrolling off the screen.
 
+   extra_latent_entropy
+   Enable a very simple form of latent entropy extraction
+   from the first 4GB of memory as the bootmem allocator
+   passes the memory pages to the buddy allocator.
+
pcbit=  [HW,ISDN]
 
pcd.[PARIDE]
diff --git a/arch/Kconfig b/arch/Kconfig
index 4b7cc2f..3374d50 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -404,6 +404,11 @@ config GCC_PLUGIN_LATENT_ENTROPY
  is some slowdown of the boot process (about 0.5%) and fork and
  irq processing.
 
+ When extra_latent_entropy is passed on the kernel command line,
+ entropy will be extracted from up to the first 4GB of RAM while the
+ runtime memory allocator is being initialized. This costs even more
+ slowdown of the boot process.
+
  Note that entropy extracted this way is not cryptographically
  secure!
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ffc4f4a..0a40c12 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1234,6 +1235,15 @@ static void __free_pages_ok(struct page *page, unsigned 
int order)
local_irq_restore(flags);
 }
 
+bool __meminitdata extra_latent_entropy;
+
+static int __init setup_extra_latent_entropy(char *str)
+{
+   extra_latent_entropy = true;
+   return 0;
+}
+early_param("extra_latent_entropy", setup_extra_latent_entropy);
+
 #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
 volatile u64 latent_entropy __latent_entropy;
 EXPORT_SYMBOL(latent_entropy);
@@ -1254,6 +1264,22 @@ static void __init __free_pages_boot_core(struct page 
*page, unsigned int order)
__ClearPageReserved(p);
set_page_count(p, 0);
 
+   if (extra_latent_entropy && !PageHighMem(page) &&
+   page_to_pfn(page) < 0x10) {
+   u64 hash = 0;
+   size_t index, end = PAGE_SIZE * nr_pages / sizeof(hash);
+   const u64 *data = lowmem_page_address(page);
+
+   for (index = 0; index < end; index++)
+   hash ^= hash + data[index];
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+   latent_entropy ^= hash;
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+#else
+   add_device_randomness((const void *)&hash, sizeof(hash));
+#endif
+   }
+
page_zone(page)->managed_pages += nr_pages;
set_page_refcounted(page);
__free_pages(page, order);
-- 
2.8.1



[PATCH v3 2/7] Split up struct warn_args

2016-07-27 Thread Emese Revfy
Disable the initify plugin on the 6th parameter
of __warn() because the va_list type can't be NULL
on the tile arch.

Signed-off-by: Emese Revfy 
---
 include/asm-generic/bug.h |  7 +--
 kernel/panic.c| 32 
 lib/bug.c |  2 +-
 3 files changed, 26 insertions(+), 15 deletions(-)

diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 13a9241..f6ae0d7 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -81,9 +81,12 @@ extern __nocapture(1) void warn_slowpath_null(const char 
*file, const int line);
do { printk(arg); __WARN_TAINT(taint); } while (0)
 #endif
 
-__nocapture(1, 6)
+/* used internally by panic.c */
+struct warn_args;
+
+__nocapture(1, 0)
 void __warn(const char *file, int line, void *caller, unsigned taint,
-   struct pt_regs *regs, const char *fmt, va_list args);
+   struct pt_regs *regs, struct warn_args *args);
 
 #ifndef WARN_ON
 #define WARN_ON(condition) ({  \
diff --git a/kernel/panic.c b/kernel/panic.c
index 993ad20..ca8cea1 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -475,8 +475,13 @@ void oops_exit(void)
kmsg_dump(KMSG_DUMP_OOPS);
 }
 
+struct warn_args {
+   const char *fmt;
+   va_list args;
+};
+
 void __warn(const char *file, int line, void *caller, unsigned taint,
-   struct pt_regs *regs, const char *fmt, va_list args)
+   struct pt_regs *regs, struct warn_args *args)
 {
disable_trace_on_warning();
 
@@ -490,8 +495,8 @@ void __warn(const char *file, int line, void *caller, 
unsigned taint,
pr_warn("WARNING: CPU: %d PID: %d at %pS\n",
raw_smp_processor_id(), current->pid, caller);
 
-   if (fmt)
-   vprintk(fmt, args);
+   if (args)
+   vprintk(args->fmt, args->args);
 
if (panic_on_warn) {
/*
@@ -520,28 +525,31 @@ void __warn(const char *file, int line, void *caller, 
unsigned taint,
 #ifdef WANT_WARN_ON_SLOWPATH
 void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
 {
-   va_list args;
+   struct warn_args args;
 
-   va_start(args, fmt);
-   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, fmt, 
args);
-   va_end(args);
+   args.fmt = fmt;
+   va_start(args.args, fmt);
+   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL,
+  &args);
+   va_end(args.args);
 }
 EXPORT_SYMBOL(warn_slowpath_fmt);
 
 void warn_slowpath_fmt_taint(const char *file, int line,
 unsigned taint, const char *fmt, ...)
 {
-   va_list args;
+   struct warn_args args;
 
-   va_start(args, fmt);
-   __warn(file, line, __builtin_return_address(0), taint, NULL, fmt, args);
-   va_end(args);
+   args.fmt = fmt;
+   va_start(args.args, fmt);
+   __warn(file, line, __builtin_return_address(0), taint, NULL, &args);
+   va_end(args.args);
 }
 EXPORT_SYMBOL(warn_slowpath_fmt_taint);
 
 void warn_slowpath_null(const char *file, int line)
 {
-   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL, 
NULL);
+   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL);
 }
 EXPORT_SYMBOL(warn_slowpath_null);
 #endif
diff --git a/lib/bug.c b/lib/bug.c
index c8bdebb..bc3656e 100644
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -168,7 +168,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct 
pt_regs *regs)
if (warning) {
/* this is a WARN_ON rather than BUG/BUG_ON */
__warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
-  NULL, NULL);
+  NULL);
return BUG_TRAP_TYPE_WARN;
}
 
-- 
2.8.1



[PATCH v3 6/7] Mark a few functions with the printf attribute

2016-07-27 Thread Emese Revfy
Fixed format strings warnings exposed by the printf attribute.

Signed-off-by: Emese Revfy 
---
 drivers/acpi/acpica/dbhistry.c |  2 +-
 drivers/acpi/acpica/dbinput.c  | 10 ++---
 drivers/acpi/acpica/dbstats.c  | 88 +++---
 drivers/acpi/acpica/utdebug.c  |  2 +-
 drivers/scsi/esas2r/esas2r_init.c  |  2 +-
 drivers/scsi/esas2r/esas2r_ioctl.c |  2 +-
 drivers/scsi/esas2r/esas2r_main.c  |  4 +-
 7 files changed, 55 insertions(+), 55 deletions(-)

diff --git a/drivers/acpi/acpica/dbhistry.c b/drivers/acpi/acpica/dbhistry.c
index 46bd65d..ec9da48 100644
--- a/drivers/acpi/acpica/dbhistry.c
+++ b/drivers/acpi/acpica/dbhistry.c
@@ -155,7 +155,7 @@ void acpi_db_display_history(void)
 
for (i = 0; i < acpi_gbl_num_history; i++) {
if (acpi_gbl_history_buffer[history_index].command) {
-   acpi_os_printf("%3ld %s\n",
+   acpi_os_printf("%3u %s\n",
   acpi_gbl_history_buffer[history_index].
   cmd_num,
   acpi_gbl_history_buffer[history_index].
diff --git a/drivers/acpi/acpica/dbinput.c b/drivers/acpi/acpica/dbinput.c
index 7cd5d2e..a837ce6 100644
--- a/drivers/acpi/acpica/dbinput.c
+++ b/drivers/acpi/acpica/dbinput.c
@@ -606,7 +606,7 @@ static u32 acpi_db_get_line(char *input_buffer)
(acpi_gbl_db_parsed_buf, sizeof(acpi_gbl_db_parsed_buf),
 input_buffer)) {
acpi_os_printf
-   ("Buffer overflow while parsing input line (max %u 
characters)\n",
+   ("Buffer overflow while parsing input line (max %lu 
characters)\n",
 sizeof(acpi_gbl_db_parsed_buf));
return (0);
}
@@ -862,24 +862,24 @@ acpi_db_command_dispatch(char *input_buffer,
 
if (param_count == 0) {
acpi_os_printf
-   ("Current debug level for file output is:
%8.8lX\n",
+   ("Current debug level for file output is:
%8.8X\n",
 acpi_gbl_db_debug_level);
acpi_os_printf
-   ("Current debug level for console output is: 
%8.8lX\n",
+   ("Current debug level for console output is: 
%8.8X\n",
 acpi_gbl_db_console_debug_level);
} else if (param_count == 2) {
temp = acpi_gbl_db_console_debug_level;
acpi_gbl_db_console_debug_level =
strtoul(acpi_gbl_db_args[1], NULL, 16);
acpi_os_printf
-   ("Debug Level for console output was %8.8lX, now 
%8.8lX\n",
+   ("Debug Level for console output was %8.8X, now 
%8.8X\n",
 temp, acpi_gbl_db_console_debug_level);
} else {
temp = acpi_gbl_db_debug_level;
acpi_gbl_db_debug_level =
strtoul(acpi_gbl_db_args[1], NULL, 16);
acpi_os_printf
-   ("Debug Level for file output was %8.8lX, now 
%8.8lX\n",
+   ("Debug Level for file output was %8.8X, now 
%8.8X\n",
 temp, acpi_gbl_db_debug_level);
}
break;
diff --git a/drivers/acpi/acpica/dbstats.c b/drivers/acpi/acpica/dbstats.c
index a414e1f..de70230 100644
--- a/drivers/acpi/acpica/dbstats.c
+++ b/drivers/acpi/acpica/dbstats.c
@@ -377,17 +377,17 @@ acpi_status acpi_db_display_statistics(char *type_arg)
   "ACPI_TYPE", "NODES", "OBJECTS");
 
for (i = 0; i < ACPI_TYPE_NS_NODE_MAX; i++) {
-   acpi_os_printf("%16.16s % 10ld% 10ld\n",
+   acpi_os_printf("%16.16s % 10d% 10d\n",
   acpi_ut_get_type_name(i),
   acpi_gbl_node_type_count[i],
   acpi_gbl_obj_type_count[i]);
}
 
-   acpi_os_printf("%16.16s % 10ld% 10ld\n", "Misc/Unknown",
+   acpi_os_printf("%16.16s % 10d% 10d\n", "Misc/Unknown",
   acpi_gbl_node_type_count_misc,
   acpi_gbl_obj_type_count_misc);
 
-   acpi_os_printf("%16.16s % 10ld% 10ld\n", "TOTALS:",
+   acpi_os_printf("%16.16s % 10d% 10d\n", "TOTALS:",
   acpi_gbl_num_nodes, acpi_gbl_num_objects);
break;
 
@@ -415,16 +415,16 @@

Re: [PATCH v7 1/6] Shared library support

2016-05-02 Thread Emese Revfy
On Mon, 2 May 2016 14:03:00 +0900
Masahiro Yamada  wrote:

> In the first place,
> I am wondering if we need to revive this documentation.
> What this commit is only interested in *.so generation,
> not host program support.

I agree that we don't need this documentation. I'll remove it.
  
> > @@ -124,5 +158,39 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
> >  $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
> > $(call if_changed_dep,host-cxxobjs)
> >
> > +# Compile .c file, create position independent .o file
> > +# host-cshobjs -> .o
> > +quiet_cmd_host-cshobjs = HOSTCC  -fPIC $@
> > +  cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
> > +$(host-cshobjs): $(obj)/%.o: $(src)/%.c FORCE
> > +   $(call if_changed_dep,host-cshobjs)
> > +
> > +# Compile .c file, create position independent .o file
> 
> 
> Please explain why c++ compiler should be used to compile .c files.
> 
> This is not clear, so worth commenting.

Where do you think that the C++ compiler is used above? I think HOSTCC can only 
be C compiler.

-- 
Emese


Re: [kernel-hardening] Re: [PATCH v7 2/6] GCC plugin infrastructure

2016-05-02 Thread Emese Revfy
On Mon, 2 May 2016 14:07:35 +0900
Masahiro Yamada  wrote:

Hi,

> > diff --git a/arch/x86/entry/vdso/Makefile b/arch/x86/entry/vdso/Makefile
> > index 253b72e..f912316 100644
> > --- a/arch/x86/entry/vdso/Makefile
> > +++ b/arch/x86/entry/vdso/Makefile
> > @@ -75,7 +75,7 @@ CFL := $(PROFILING) -mcmodel=small -fPIC -O2 
> > -fasynchronous-unwind-tables -m64 \
> > -fno-omit-frame-pointer -foptimize-sibling-calls \
> > -DDISABLE_BRANCH_PROFILING -DBUILD_VDSO
> >
> > -$(vobjs): KBUILD_CFLAGS += $(CFL)
> > +$(vobjs): KBUILD_CFLAGS := $(filter-out 
> > $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS)) $(CFL)
> >
> >  #
> >  # vDSO code runs in userspace and -pg doesn't help with profiling anyway.
> > @@ -145,6 +145,7 @@ KBUILD_CFLAGS_32 := $(filter-out -m64,$(KBUILD_CFLAGS))
> >  KBUILD_CFLAGS_32 := $(filter-out -mcmodel=kernel,$(KBUILD_CFLAGS_32))
> >  KBUILD_CFLAGS_32 := $(filter-out -fno-pic,$(KBUILD_CFLAGS_32))
> >  KBUILD_CFLAGS_32 := $(filter-out -mfentry,$(KBUILD_CFLAGS_32))
> > +KBUILD_CFLAGS_32 := $(filter-out $(GCC_PLUGINS_CFLAGS),$(KBUILD_CFLAGS_32))
> >  KBUILD_CFLAGS_32 += -m32 -msoft-float -mregparm=0 -fpic
> >  KBUILD_CFLAGS_32 += $(call cc-option, -fno-stack-protector)
> >  KBUILD_CFLAGS_32 += $(call cc-option, -foptimize-sibling-calls)
> 
> 
> Looks like gcc-plugins should be omitted only for this directory.
> Please tell me why.
> I am not familiar with x86 architecture, so this is not clear to me.

The vdso is userland code so in general kernel instrumentation/analysis doesn't 
apply to it.

-- 
Emese


Re: [PATCH v7 5/6] Documentation for the GCC plugin infrastructure

2016-05-02 Thread Emese Revfy
On Mon, 2 May 2016 14:10:21 +0900
Masahiro Yamada  wrote:

Hi,

> 2016-04-23 3:26 GMT+09:00 Emese Revfy :
> > This is the GCC infrastructure documentation about its operation, how to add
> > and use a new plugin with an example.
> >
> > Signed-off-by: Emese Revfy 
> 
> 
> Perhaps, this documentation should be included in 2/6 ?

Ok, I will move it there.

-- 
Emese


Re: [PATCH v7 1/6] Shared library support

2016-05-05 Thread Emese Revfy
On Wed, 4 May 2016 13:09:05 +0900
Masahiro Yamada  wrote:

> Hi Emese,
> 
> 
> 2016-05-04 6:29 GMT+09:00 Emese Revfy :
> > On Tue, 3 May 2016 11:00:56 +0900
> > Masahiro Yamada  wrote:
> >
> > Hi,
> >
> >> # Compile .c file, create position independent .o file
> >> # host-cxxshobjs -> .o
> >> quiet_cmd_host-cxxshobjs = HOSTCXX -fPIC $@
> >>   cmd_host-cxxshobjs = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
> >>$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
> >>$(call if_changed_dep,host-cxxshobjs)
> >>
> >>
> >>
> >>
> >> We generally use HOSTCC to compile *.c files,
> >> and HOSTCXX to compile *.cc files.
> >>
> >>
> >> But, here, you mention to use HOSTCXX to compile .c files
> >> such as cyc_complexity_plugin.c, sancov_plugin.c, etc.
> >>
> >> This is not straight-forward.  It is worthwhile to comment the reason.
> >
> > I wrote a comment about it here:
> > https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next/commit/74f6343a7f13c071e00c417332051e25f15009ea
> >
> 
> 
> 
> +# Note that plugin capable gcc versions can be either C or C++ based
> +# therefore plugin source files have to be compilable in both C and C++ mode.
> +# This is why a C++ compiler is invoked on a .c file.
> 
> Thanks.
> 
> Please let me confirm if I understood correctly.
> 
> 
> We generally have to do something with the name-space conflict
> (with 'extern "C"') in the mixture of C/C++.
> 
> Depending on the GCC version,
> GCC-plugin-related libraries could be built for C or C++.
> 
> So, we need to check the GCC version and choose correct one
> from C or C++.

The plugin source files have to be compilable by both versions
because gcc versions 4.5 and 4.6 are compiled by a C compiler,
gcc-4.7 can be compiled by a C or a C++ compiler,
and versions 4.8+ can only be compiled by a C++ compiler.

-- 
Emese


Re: [PATCH v7 1/6] Shared library support

2016-05-05 Thread Emese Revfy
On Tue, 3 May 2016 23:25:27 +0200
Emese Revfy  wrote:

> > Do you need to change both the top Makefile and Makefile.clean
> > for belt-and-braces cleaning?
> 
> It doesn't delete the *.so files without the hunk from the top Makefile. 
> The mrproper and distclean targets remove them with this patch:
> https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next/commit/f23b7eb247ccc9f1007e53313af343980dd52591
> But I think this isn't the best solution much like doing it from the top 
> Makefile.

Do you think this patch will be good enough? In this case I can resend the 
patch set.

-- 
Emese


Re: [PATCH v7 1/6] Shared library support

2016-05-03 Thread Emese Revfy
On Mon, 2 May 2016 14:03:00 +0900
Masahiro Yamada  wrote:

Hi,

> > diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
> > index 55c96cb..e4e88ab 100644
> > --- a/scripts/Makefile.clean
> > +++ b/scripts/Makefile.clean
> > @@ -38,7 +38,8 @@ subdir-ymn:= $(addprefix $(obj)/,$(subdir-ymn))
> >  __clean-files  := $(extra-y) $(extra-m) $(extra-)   \
> >$(always) $(targets) $(clean-files)   \
> >$(host-progs) \
> > -  $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
> > +  $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
> > +  $(hostlibs-y) $(hostlibs-m) $(hostlibs-)
> 
> $(hostcxxlibs-y)$(hostcxxlibs-m) is missing here.
> 
> 
> BTW, are you planning to support hostlibs without .so extention in the future?
> 
> 
> You are changing the top Makefile to clean with "*.so" pattern rule.
> 
> Do you need to change both the top Makefile and Makefile.clean
> for belt-and-braces cleaning?

It doesn't delete the *.so files without the hunk from the top Makefile. 
The mrproper and distclean targets remove them with this patch:
https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next/commit/f23b7eb247ccc9f1007e53313af343980dd52591
But I think this isn't the best solution much like doing it from the top 
Makefile.

-- 
Emese


Re: [PATCH v7 1/6] Shared library support

2016-05-03 Thread Emese Revfy
On Tue, 3 May 2016 11:00:56 +0900
Masahiro Yamada  wrote:

Hi,

> # Compile .c file, create position independent .o file
> # host-cxxshobjs -> .o
> quiet_cmd_host-cxxshobjs = HOSTCXX -fPIC $@
>   cmd_host-cxxshobjs = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
>$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
>$(call if_changed_dep,host-cxxshobjs)
> 
> 
> 
> 
> We generally use HOSTCC to compile *.c files,
> and HOSTCXX to compile *.cc files.
> 
> 
> But, here, you mention to use HOSTCXX to compile .c files
> such as cyc_complexity_plugin.c, sancov_plugin.c, etc.
> 
> This is not straight-forward.  It is worthwhile to comment the reason.

I wrote a comment about it here:
https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next/commit/74f6343a7f13c071e00c417332051e25f15009ea

-- 
Emese


[PATCH v9 0/4] Introduce GCC plugin infrastructure

2016-05-23 Thread Emese Revfy
This patch set introduce the GCC plugin infrastructure with examples for testing
and documentation.

GCC plugins are loadable modules that provide extra features to the compiler.
They are useful for runtime instrumentation and static analysis.

The infrastructure supports all gcc versions from 4.5 to 6.0, building
out-of-tree modules and building in a separate directory. Cross-compilation
is supported too but currently only the x86, arm, arm64 and uml architectures 
enable plugins.

This infrastructure was ported from grsecurity/PaX. Based on work created by 
the PaX Team.
It is a CII project supported by the Linux Foundation.

Emese Revfy (4):
 Shared library support
 GCC plugin infrastructure
 Add Cyclomatic complexity plugin
 Add sancov plugin


Changes from v8:
 * Use warnings instead of errors because of allmodconfig/allyesconfig builds
   with old gcc versions
(Suggested-by: Michal Marek )
 * Order HAVE_GCC_PLUGINS alphabetically
 * Moved exported variables from the top level Makefile to 
scripts/Makefile.gcc-plugins

Changes from v7:
 * Moved the "The GCC plugin infrastructure supports the arm and arm64 
architectures too"
   and the "Documentations of the GCC plugin infrastructre" patches
   into the "GCC plugin infrastructure" patch
(Suggested-by: Masahiro Yamada )
 * Add gcc-plugin.sh to MAINTAINERS
(Suggested-by: Masahiro Yamada )
 * Makefile.host: Remove *shobjs from multi-depend
(Suggested-by: Masahiro Yamada )
 * Have distclean and mrproper targets clean the *.so files
(Suggested-by: Masahiro Yamada )
 * Simplied gcc-plugin-y to add plugins to HOSTLIBS
(Suggested-by: Masahiro Yamada )
 * Simplified Makefile.host
(Suggested-by: Masahiro Yamada )
 * Clean *.c.[012]*.*
(Suggested-by: Michal Marek )
 * Documentation: gcc plugins have to compilable as C and C++
 * Enable GCC plugins for UML

Changes from v6:
 * Disable the sancov plugin whenever KCOV_INSTRUMENT is disabled
(Reported-by: Huang Ying )
 * Disable KCOV/sancov plugin because this is not a regular kernel code
(Reported-by: Huang Ying )
 * Removed unnecessary gcc plugin cflags
(Signed-off-by: Masahiro Yamada )
 * Removed unnecessary gcc plugin aflags

Changes from v5:
 * Set important properties on the external fndecl (Add sancov plugin)
 * Revert documentation change too (Shared library support)
(Suggested-by: Kees Cook )
 * The GCC plugin infrastructure now supports the arm and arm64 architectures 
too
(Signed-off-by: David Brown )
 * Simplify the computation of PLUGINCC (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify the invocation of gcc-plugin.sh (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Make use of multi-depend (Shared library support)
(Suggested-by: Masahiro Yamada )
 * Remove unnecessary exports (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify Makefile by using addprefix (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Moved the gcc plugins from tools/ to scripts/ (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Removed plugins from KBUILD_CFLAGS_32 (GCC plugin infrastructure)
 * Remove gcc-plugin target everywhere
(Suggested-by and partly Written-by: Masahiro Yamada 
)
 * There is no leaf gcc attribute in gcc-4.5 (Add sancov plugin)
 * Added support to the sancov plugin with kcov (Add sancov plugin)

Changes from v4:
 * Moved shared library support from the GCC plugin infrastructure patch into
   a different patch
 * Update gcc-*.h from PaX
   * Fixed gcc-common.h for gcc 6
   * Added pass cloning support to the gcc pass generators
 * Disable all plugins in vdso because it is userland code
 * Add sancov gcc plugin: another use case for gcc plugin support in the kernel
   is when there is a feature in the latest gcc version and we would like to use
   it with older gcc versions as well (e.g., distros).

Changes from v3:
 * Fix some indentation related warnings
   (Suggested by checkpatch.pl)
 * Add maintainer entries
 * Don't run gcc_plugin.sh when the GCC_PLUGINS option is disabled or 
unsupported
   (Reported-by: Fengguang Wu )

Changes from v2:
 * Fixed incorrectly encoded characters
 * Generate the GIMPLE, IPA, SIMPLE_IPA and RTL pass structures
   (Suggested-by: Rasmus Villemoes )
 * Write plugin related warning messages to stderr instead of stdout
   (Suggested-by: Kees Cook )
 * Mention the installation of the gcc plugin headers (Documentation)

Changes from v1:
 * Move the gcc-plugins make target into a separate Makefile because there may
   be a lot of plugins (Suggested-by: Rasmus Villemoes)
 * Simplify the dependencies of the plugin related config option
   (Suggested-by: Kees Cook )
 * Removed the unnecessary example plugin

---
 .gitignore |   1 +
 Documentation/dontdiff |   1 +
 Documentation/gcc-plugins.txt 

[PATCH v9 1/4] Shared library support

2016-05-23 Thread Emese Revfy
Infrastructure for building independent shared library targets.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 scripts/Makefile.build |  2 +-
 scripts/Makefile.clean |  4 +++-
 scripts/Makefile.host  | 55 +-
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0d1ca5b..11602e5 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -60,7 +60,7 @@ endif
 endif
 
 # Do not include host rules unless needed
-ifneq ($(hostprogs-y)$(hostprogs-m),)
+ifneq 
($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),)
 include scripts/Makefile.host
 endif
 
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 55c96cb..50616ea 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -38,7 +38,9 @@ subdir-ymn:= $(addprefix $(obj)/,$(subdir-ymn))
 __clean-files  := $(extra-y) $(extra-m) $(extra-)   \
   $(always) $(targets) $(clean-files)   \
   $(host-progs) \
-  $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
+  $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
+  $(hostlibs-y) $(hostlibs-m) $(hostlibs-) \
+  $(hostcxxlibs-y) $(hostcxxlibs-m)
 
 __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 133edfa..45b5b1a 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -20,7 +20,15 @@
 # Will compile qconf as a C++ program, and menu as a C program.
 # They are linked as C++ code to the executable qconf
 
+# hostcc-option
+# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586)
+
+hostcc-option = $(call try-run,\
+   $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(1) -c -x c /dev/null -o 
"$$TMP",$(1),$(2))
+
 __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
+host-cshlib := $(sort $(hostlibs-y) $(hostlibs-m))
+host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m))
 
 # C code
 # Executables compiled from a single .c file
@@ -42,6 +50,10 @@ host-cxxmulti:= $(foreach m,$(__hostprogs),$(if 
$($(m)-cxxobjs),$(m)))
 # C++ Object (.o) files compiled from .cc files
 host-cxxobjs   := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
 
+# Object (.o) files used by the shared libaries
+host-cshobjs   := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs
+host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs
+
 # output directory for programs/.o files
 # hostprogs-y := tools/build may have been specified.
 # Retrieve also directory of .o files from prog-objs or prog-cxxobjs notation
@@ -56,6 +68,10 @@ host-cmulti  := $(addprefix $(obj)/,$(host-cmulti))
 host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
 host-cxxmulti  := $(addprefix $(obj)/,$(host-cxxmulti))
 host-cxxobjs   := $(addprefix $(obj)/,$(host-cxxobjs))
+host-cshlib:= $(addprefix $(obj)/,$(host-cshlib))
+host-cxxshlib  := $(addprefix $(obj)/,$(host-cxxshlib))
+host-cshobjs   := $(addprefix $(obj)/,$(host-cshobjs))
+host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs))
 host-objdirs:= $(addprefix $(obj)/,$(host-objdirs))
 
 obj-dirs += $(host-objdirs)
@@ -124,5 +140,42 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
 $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
 
+# Compile .c file, create position independent .o file
+# host-cshobjs -> .o
+quiet_cmd_host-cshobjs = HOSTCC  -fPIC $@
+  cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
+$(host-cshobjs): $(obj)/%.o: $(src)/%.c FORCE
+   $(call if_changed_dep,host-cshobjs)
+
+# Compile .c file, create position independent .o file
+# Note that plugin capable gcc versions can be either C or C++ based
+# therefore plugin source files have to be compilable in both C and C++ mode.
+# This is why a C++ compiler is invoked on a .c file.
+# host-cxxshobjs -> .o
+quiet_cmd_host-cxxshobjs   = HOSTCXX -fPIC $@
+  cmd_host-cxxshobjs   = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
+$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
+   $(call if_changed_dep,host-cxxshobjs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cshlib)
+quiet_cmd_host-cshlib  = HOSTLLD -shared $@
+  cmd_host-cshlib  = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cshlib): FORCE
+   $(call if_changed,host-cshlib)
+$(call multi_depend, $(host-cshlib), .so, -objs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cxxshlib)
+quiet_cmd_host-cxxshlib= HOSTLLD -shared $@
+  cmd_host-cxxshlib= $(HOSTCX

[PATCH v9 2/4] GCC plugin infrastructure

2016-05-23 Thread Emese Revfy
This patch allows to build the whole kernel with GCC plugins. It was ported from
grsecurity/PaX. The infrastructure supports building out-of-tree modules and
building in a separate directory. Cross-compilation is supported too.
Currently the x86, arm, arm64 and uml architectures enable plugins.

The directory of the gcc plugins is scripts/gcc-plugins. You can use a file or 
a directory
there. The plugins compile with these options:
 * -fno-rtti: gcc is compiled with this option so the plugins must use it too
 * -fno-exceptions: this is inherited from gcc too
 * -fasynchronous-unwind-tables: this is inherited from gcc too
 * -ggdb: it is useful for debugging a plugin (better backtrace on internal
errors)
 * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h)
 * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version
variable, plugin-version.h)

The infrastructure introduces a new Makefile target called gcc-plugins. It
supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script
chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++).
This script also checks the availability of the included headers in
scripts/gcc-plugins/gcc-common.h.

The gcc-common.h header contains frequently included headers for GCC plugins
and it has a compatibility layer for the supported gcc versions.

The gcc-generate-*-pass.h headers automatically generate the registration
structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes.

Note that 'make clean' keeps the *.so files (only the distclean or mrproper
targets clean all) because they are needed for out-of-tree modules.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 .gitignore |   1 +
 Documentation/dontdiff |   1 +
 Documentation/gcc-plugins.txt  |  87 +++
 MAINTAINERS|   9 +
 Makefile   |  14 +-
 arch/Kconfig   |  15 +
 arch/arm/Kconfig   |   1 +
 arch/arm64/Kconfig |   1 +
 arch/um/Kconfig.common |   1 +
 arch/x86/Kconfig   |   1 +
 arch/x86/entry/vdso/Makefile   |   3 +-
 scripts/Makefile   |   2 +-
 scripts/Makefile.gcc-plugins   |  23 +
 scripts/gcc-plugin.sh  |  51 ++
 scripts/gcc-plugins/Makefile   |  20 +
 scripts/gcc-plugins/gcc-common.h   | 830 +
 scripts/gcc-plugins/gcc-generate-gimple-pass.h | 175 +
 scripts/gcc-plugins/gcc-generate-ipa-pass.h| 289 +++
 scripts/gcc-plugins/gcc-generate-rtl-pass.h| 175 +
 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 175 +
 scripts/link-vmlinux.sh|   2 +-
 scripts/package/builddeb   |   1 +
 22 files changed, 1872 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/gcc-plugins.txt
 create mode 100644 scripts/Makefile.gcc-plugins
 create mode 100755 scripts/gcc-plugin.sh
 create mode 100644 scripts/gcc-plugins/Makefile
 create mode 100644 scripts/gcc-plugins/gcc-common.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-gimple-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-ipa-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-rtl-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h

diff --git a/.gitignore b/.gitignore
index 0c320bf..2be25f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ modules.builtin
 Module.symvers
 *.dwo
 *.su
+*.c.[012]*.*
 
 #
 # Top-level generic files
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 8ea834f..5385cba 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -3,6 +3,7 @@
 *.bc
 *.bin
 *.bz2
+*.c.[012]*.*
 *.cis
 *.cpio
 *.csp
diff --git a/Documentation/gcc-plugins.txt b/Documentation/gcc-plugins.txt
new file mode 100644
index 000..891c694
--- /dev/null
+++ b/Documentation/gcc-plugins.txt
@@ -0,0 +1,87 @@
+GCC plugin infrastructure
+=
+
+
+1. Introduction
+===
+
+GCC plugins are loadable modules that provide extra features to the
+compiler [1]. They are useful for runtime instrumentation and static analysis.
+We can analyse, change and add further code during compilation via
+callbacks [2], GIMPLE [3], IPA [4] and RTL passes [5].
+
+The GCC plugin infrastructure of the kernel supports all gcc versions from
+4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a
+separate directory.
+Plugin source files have to be compilable by both a C and a C++ compiler as 
well
+because gcc versions 4.5 and 4.6 are compiled by a C compiler,
+gcc-4.7 can be compiled by 

[PATCH v9 3/4] Add Cyclomatic complexity GCC plugin

2016-05-23 Thread Emese Revfy
Add a very simple plugin to demonstrate the GCC plugin infrastructure. This GCC
plugin computes the cyclomatic complexity of each function.

The complexity M of a function's control flow graph is defined as:
M = E - N + 2P
where
E = the number of edges
N = the number of nodes
P = the number of connected components (exit nodes).

Signed-off-by: Emese Revfy 
---
 arch/Kconfig| 12 +
 scripts/Makefile.gcc-plugins|  1 +
 scripts/gcc-plugins/Makefile|  1 +
 scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +
 4 files changed, 87 insertions(+)
 create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 2821cfe..74f0d63 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -372,6 +372,18 @@ menuconfig GCC_PLUGINS
 
  See Documentation/gcc-plugins.txt for details.
 
+config GCC_PLUGIN_CYC_COMPLEXITY
+   bool "Compute the cyclomatic complexity of a function"
+   depends on GCC_PLUGINS
+   help
+ The complexity M of a function's control flow graph is defined as:
+  M = E - N + 2P
+ where
+
+ E = the number of edges
+ N = the number of nodes
+ P = the number of connected components (exit nodes).
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index bcc373d..b4a189c 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,6 +2,7 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
   export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index a4c9341..c60ba4b 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -17,4 +17,5 @@ export GCCPLUGINS_DIR HOSTLIBS
 $(HOSTLIBS)-y := $(GCC_PLUGIN)
 always := $($(HOSTLIBS)-y)
 
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
 clean-files += *.so
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c 
b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 000..34df974
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy 
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ *  E = the number of edges of the graph
+ *  N = the number of nodes of the graph
+ *  P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+   .version= "20160225",
+   .help   = "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+   int complexity;
+   expanded_location xloc;
+
+   /* M = E - N + 2P */
+   complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+   xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+   fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+   xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+   return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct 
plugin_gcc_version *version)
+{
+   const char * const plugin_name = plugin_info->base_name;
+   struct register_pass_info cyc_complexity_pass_info;
+
+   cyc_complexity_pass_info.pass   = 
make_cyc_complexity_pass();
+   cyc_complexity_pass_info.reference_pass_name= "ssa";
+   cyc_complexity_pass_info.ref_pass_instance_number   = 1;
+   cyc_complexity_pass_info.pos_op = 
PASS_POS_INSERT_AFTER;
+
+   if (!plugin_default_version_check(version, &gcc_version)) {
+   error(G_("incompatible gcc/plugin versions"));
+   return 1;
+   }
+
+   register_callback(plugin_name, PLUGIN_INFO, NULL,
+   &cyc_complexity_plugin_info);
+   register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+   &cyc_complexity_pass_info);
+
+   return 0;
+}
-- 
2.8.1



[PATCH v9 4/4] Add sancov plugin

2016-05-23 Thread Emese Revfy
The sancov gcc plugin inserts a __sanitizer_cov_trace_pc() call
at the start of basic blocks.

This plugin is a helper plugin for the kcov feature. It supports
all gcc versions with plugin support (from gcc-4.5 on).
It is based on the gcc commit "Add fuzzing coverage support" by Dmitry Vyukov
(https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296).

Signed-off-by: Emese Revfy 
---
 Makefile|  10 +--
 arch/Kconfig|   9 +++
 arch/x86/purgatory/Makefile |   2 +
 lib/Kconfig.debug   |   2 +
 scripts/Makefile.gcc-plugins|  21 +-
 scripts/gcc-plugins/Makefile|   6 ++
 scripts/gcc-plugins/sancov_plugin.c | 144 
 7 files changed, 184 insertions(+), 10 deletions(-)
 create mode 100644 scripts/gcc-plugins/sancov_plugin.c

diff --git a/Makefile b/Makefile
index ebe6c3c..b4f8f0a 100644
--- a/Makefile
+++ b/Makefile
@@ -369,7 +369,7 @@ LDFLAGS_MODULE  =
 CFLAGS_KERNEL  =
 AFLAGS_KERNEL  =
 CFLAGS_GCOV= -fprofile-arcs -ftest-coverage -fno-tree-loop-im 
-Wno-maybe-uninitialized
-CFLAGS_KCOV= -fsanitize-coverage=trace-pc
+CFLAGS_KCOV:= $(call cc-option,-fsanitize-coverage=trace-pc,)
 
 
 # Use USERINCLUDE when you must reference the UAPI directories only.
@@ -691,14 +691,6 @@ endif
 endif
 KBUILD_CFLAGS += $(stackp-flag)
 
-ifdef CONFIG_KCOV
-  ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
-$(warning Cannot use CONFIG_KCOV: \
- -fsanitize-coverage=trace-pc is not supported by compiler)
-CFLAGS_KCOV =
-  endif
-endif
-
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
 KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)
diff --git a/arch/Kconfig b/arch/Kconfig
index 74f0d63..5feadad 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -384,6 +384,15 @@ config GCC_PLUGIN_CYC_COMPLEXITY
  N = the number of nodes
  P = the number of connected components (exit nodes).
 
+config GCC_PLUGIN_SANCOV
+   bool
+   depends on GCC_PLUGINS
+   help
+ This plugin inserts a __sanitizer_cov_trace_pc() call at the start of
+ basic blocks. It supports all gcc versions with plugin support (from
+ gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
+ by Dmitry Vyukov .
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 12734a9..ac58c16 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -8,6 +8,8 @@ PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z 
nodefaultlib
 targets += purgatory.ro
 
+KCOV_INSTRUMENT := n
+
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
 # sure how to relocate those. Like kexec-tools, use custom flags.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 09cdb1f..7c7980d 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -712,6 +712,8 @@ config KCOV
bool "Code coverage for fuzzing"
depends on ARCH_HAS_KCOV
select DEBUG_FS
+   select GCC_PLUGINS
+   select GCC_PLUGIN_SANCOV
help
  KCOV exposes kernel code coverage information in a form suitable
  for coverage-guided fuzzing (randomized testing).
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index b4a189c..ed37e9b 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,10 +2,26 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
+
   gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
+
+  ifdef CONFIG_GCC_PLUGIN_SANCOV
+ifeq ($(CFLAGS_KCOV),)
+  # It is needed because of the gcc-plugin.sh and gcc version checks.
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)   += sancov_plugin.so
+
+  ifneq ($(PLUGINCC),)
+CFLAGS_KCOV := $(SANCOV_PLUGIN)
+  else
+$(warning warning: cannot use CONFIG_KCOV: 
-fsanitize-coverage=trace-pc is not supported by compiler)
+  endif
+endif
+  endif
+
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
-  export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN
+  export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN
 
   ifeq ($(PLUGINCC),)
 ifneq ($(GCC_PLUGINS_CFLAGS),)
@@ -16,6 +32,9 @@ ifdef CONFIG_GCC_PLUGINS
 $(warning warning: your gcc version does not support plugins, you 
should upgrade it to gcc 4.

[PATCH v1 0/3] Introduce the latent_entropy gcc plugin

2016-05-23 Thread Emese Revfy
I would like to introduce the latent_entropy gcc plugin. This plugin mitigates
the problem of the kernel having too little entropy during and after boot
for generating crypto keys.

This plugin mixes random values into the latent_entropy global variable
in functions marked by the __latent_entropy attribute.
The value of this global variable is added to the kernel entropy pool
to increase the entropy.

It is a CII project supported by the Linux Foundation.

The latent_entropy plugin was ported from grsecurity/PaX originally written by
the PaX Team. You can find more about the plugin here:
https://grsecurity.net/pipermail/grsecurity/2012-July/001093.html

The plugin supports all gcc version from 4.5 to 6.0.

I do some changes above the PaX version. The important one is mixing
the stack pointer into the global variable too.
You can find more about the changes here:
https://github.com/ephox-gcc-plugins/latent_entropy

This patch set is based on the "Introduce GCC plugin infrastructure" patch set 
(v9).

Emese Revfy (3):
 Add the latent_entropy gcc plugin
 Mark functions with the latent_entropy attribute
 Add the extra_latent_entropy kernel parameter

---
 Documentation/kernel-parameters.txt |   5 +
 arch/Kconfig|  22 ++
 arch/powerpc/kernel/Makefile|   8 +-
 block/blk-softirq.c |   2 +-
 drivers/char/random.c   |   6 +-
 fs/namespace.c  |   2 +-
 include/linux/compiler-gcc.h|   5 +
 include/linux/compiler.h|   4 +
 include/linux/fdtable.h |   2 +-
 include/linux/genhd.h   |   2 +-
 include/linux/init.h|  10 +-
 include/linux/random.h  |  12 +-
 init/main.c |   1 +
 kernel/fork.c   |   5 +-
 kernel/rcu/tiny.c   |   2 +-
 kernel/rcu/tree.c   |   2 +-
 kernel/sched/fair.c |   2 +-
 kernel/softirq.c|   4 +-
 kernel/time/timer.c |   2 +-
 lib/irq_poll.c  |   2 +-
 lib/random32.c  |   2 +-
 mm/page_alloc.c |  28 ++
 net/core/dev.c  |   4 +-
 scripts/Makefile.gcc-plugins|  10 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 446 
 26 files changed, 562 insertions(+), 29 deletions(-)


[PATCH v1 1/3] Add the latent_entropy gcc plugin

2016-05-23 Thread Emese Revfy
This plugin mitigates the problem of the kernel having too little entropy during
and after boot for generating crypto keys.

It creates a local variable in every marked function. The value of this 
variable is
modified by randomly chosen operations (add, xor and rol) and
random values (gcc generates them at compile time and the stack pointer at 
runtime).
It depends on the control flow (e.g., loops, conditions).

Before the function returns the plugin writes this local variable
into the latent_entropy global variable. The value of this global variable is
added to the kernel entropy pool in do_one_initcall() and _do_fork().

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 arch/Kconfig|  17 ++
 arch/powerpc/kernel/Makefile|   8 +-
 include/linux/random.h  |   8 +
 init/main.c |   1 +
 kernel/fork.c   |   1 +
 mm/page_alloc.c |   5 +
 scripts/Makefile.gcc-plugins|  10 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 446 
 9 files changed, 491 insertions(+), 6 deletions(-)
 create mode 100644 scripts/gcc-plugins/latent_entropy_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 5feadad..74489df 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -393,6 +393,23 @@ config GCC_PLUGIN_SANCOV
  gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
  by Dmitry Vyukov .
 
+config GCC_PLUGIN_LATENT_ENTROPY
+   bool "latent entropy"
+   depends on GCC_PLUGINS
+   help
+ By saying Y here the kernel will instrument some kernel code to
+ extract some entropy from both original and artificially created
+ program state.  This will help especially embedded systems where
+ there is little 'natural' source of entropy normally.  The cost
+ is some slowdown of the boot process and fork and irq processing.
+
+ Note that entropy extracted this way is not known to be 
cryptographically
+ secure!
+
+ This plugin was ported from grsecurity/PaX. More information at:
+  * https://grsecurity.net/
+  * https://pax.grsecurity.net/
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2da380f..6c7e448 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,10 +16,10 @@ endif
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace early boot code
-CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
 # do not trace tracer code
 CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
 # timers used by tracing
diff --git a/include/linux/random.h b/include/linux/random.h
index e47e533..379f4bc 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -18,6 +18,14 @@ struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+
+static inline void add_latent_entropy(void)
+{
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+#endif
+}
+
 extern void add_input_randomness(unsigned int type, unsigned int code,
 unsigned int value);
 extern void add_interrupt_randomness(int irq, int irq_flags);
diff --git a/init/main.c b/init/main.c
index 4c17fda..07e4174 100644
--- a/init/main.c
+++ b/init/main.c
@@ -781,6 +781,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
}
WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf);
 
+   add_latent_entropy();
return ret;
 }
 
diff --git a/kernel/fork.c b/kernel/fork.c
index cdf520f..d07d5a6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1766,6 +1766,7 @@ long _do_fork(unsigned long clone_flags,
 
p = copy_process(clone_flags, stack_start, stack_size,
 child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
+   add_latent_entropy();
/*
 * Do this prior waking up the new thread - the thread pointer
 * might get invalid after that point, if the thread exits quickly.
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index f8f3bfc..d

[PATCH v1 2/3] Mark functions with the latent_entropy attribute

2016-05-23 Thread Emese Revfy
These functions have been selected because they are init functions or
are called at random times or they have variable loops.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 block/blk-softirq.c  |  2 +-
 drivers/char/random.c|  6 +++---
 fs/namespace.c   |  2 +-
 include/linux/compiler-gcc.h |  5 +
 include/linux/compiler.h |  4 
 include/linux/fdtable.h  |  2 +-
 include/linux/genhd.h|  2 +-
 include/linux/init.h | 10 --
 include/linux/random.h   |  4 ++--
 kernel/fork.c|  4 ++--
 kernel/rcu/tiny.c|  2 +-
 kernel/rcu/tree.c|  2 +-
 kernel/sched/fair.c  |  2 +-
 kernel/softirq.c |  4 ++--
 kernel/time/timer.c  |  2 +-
 lib/irq_poll.c   |  2 +-
 lib/random32.c   |  2 +-
 mm/page_alloc.c  |  2 +-
 net/core/dev.c   |  4 ++--
 19 files changed, 39 insertions(+), 24 deletions(-)

diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index 53b1737..489eab8 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
  * Softirq action handler - move entries to local list and loop over them
  * while passing them to the queue registered handler.
  */
-static void blk_done_softirq(struct softirq_action *h)
+static __latent_entropy void blk_done_softirq(struct softirq_action *h)
 {
struct list_head *cpu_list, local_list;
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0158d3b..6cca3ed 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -443,9 +443,9 @@ struct entropy_store {
 };
 
 static void push_to_pool(struct work_struct *work);
-static __u32 input_pool_data[INPUT_POOL_WORDS];
-static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
-static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
+static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
+static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
+static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
 
 static struct entropy_store input_pool = {
.poolinfo = &poolinfo_table[0],
diff --git a/fs/namespace.c b/fs/namespace.c
index 4fb1691..eed930c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2778,7 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct 
user_namespace *user_ns)
return new_ns;
 }
 
-struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace 
*ns,
+__latent_entropy struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct 
mnt_namespace *ns,
struct user_namespace *user_ns, struct fs_struct *new_fs)
 {
struct mnt_namespace *new_ns;
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index e294939..8d85907 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -188,6 +188,11 @@
 #endif /* GCC_VERSION >= 40300 */
 
 #if GCC_VERSION >= 40500
+
+#ifdef LATENT_ENTROPY_PLUGIN
+#define __latent_entropy __attribute__((latent_entropy))
+#endif
+
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 793c082..c65327b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile 
void *p, void *res, int s
 # define __attribute_const__   /* unimplemented */
 #endif
 
+#ifndef __latent_entropy
+# define __latent_entropy
+#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/fdtable.h b/include/linux/fdtable.h
index 5295535..9852c7e 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *);
 void put_files_struct(struct files_struct *fs);
 void reset_files_struct(struct files_struct *);
 int unshare_files(struct files_struct **);
-struct files_struct *dup_fd(struct files_struct *, int *);
+struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
int (*)(const void *, struct file *, unsigned),
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 359a8e4..8736c1f 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, 
unsigned int mask);
 extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask);
 
 /* drivers/char/random.c */
-extern void add_disk_randomness(struct gendisk *disk);
+extern void add_disk_randomness(struct gendisk *disk) __latent_entropy;
 extern void rand_initialize_disk(struct gendisk *disk);
 
 sta

[PATCH v1 3/3] Add the extra_latent_entropy kernel parameter

2016-05-23 Thread Emese Revfy
When extra_latent_entropy is passed on the kernel command line,
entropy will be extracted from up to the first 4GB of RAM while the
runtime memory allocator is being initialized.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 Documentation/kernel-parameters.txt |  5 +
 arch/Kconfig|  5 +
 mm/page_alloc.c | 23 +++
 3 files changed, 33 insertions(+)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 5349363..6c2496e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2862,6 +2862,11 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
the specified number of seconds.  This is to be used if
your oopses keep scrolling off the screen.
 
+   extra_latent_entropy
+   Enable a very simple form of latent entropy extraction
+   from the first 4GB of memory as the bootmem allocator
+   passes the memory pages to the buddy allocator.
+
pcbit=  [HW,ISDN]
 
pcd.[PARIDE]
diff --git a/arch/Kconfig b/arch/Kconfig
index 74489df..327d1e4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -403,6 +403,11 @@ config GCC_PLUGIN_LATENT_ENTROPY
  there is little 'natural' source of entropy normally.  The cost
  is some slowdown of the boot process and fork and irq processing.
 
+ When extra_latent_entropy is passed on the kernel command line,
+ entropy will be extracted from up to the first 4GB of RAM while the
+ runtime memory allocator is being initialized.  This costs even more
+ slowdown of the boot process.
+
  Note that entropy extracted this way is not known to be 
cryptographically
  secure!
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ffc4f4a..c79407b 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1235,6 +1236,15 @@ static void __free_pages_ok(struct page *page, unsigned 
int order)
 }
 
 #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+bool __meminitdata extra_latent_entropy;
+
+static int __init setup_extra_latent_entropy(char *str)
+{
+   extra_latent_entropy = true;
+   return 0;
+}
+early_param("extra_latent_entropy", setup_extra_latent_entropy);
+
 volatile u64 latent_entropy __latent_entropy;
 EXPORT_SYMBOL(latent_entropy);
 #endif
@@ -1254,6 +1264,19 @@ static void __init __free_pages_boot_core(struct page 
*page, unsigned int order)
__ClearPageReserved(p);
set_page_count(p, 0);
 
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+   if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) < 
0x10) {
+   u64 hash = 0;
+   size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
+   const u64 *data = lowmem_page_address(page);
+
+   for (index = 0; index < end; index++)
+   hash ^= hash + data[index];
+   latent_entropy ^= hash;
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+   }
+#endif
+
page_zone(page)->managed_pages += nr_pages;
set_page_refcounted(page);
__free_pages(page, order);
-- 
2.8.1



Re: [PATCH v1 3/3] Add the extra_latent_entropy kernel parameter

2016-05-24 Thread Emese Revfy
On Tue, 24 May 2016 10:09:16 -0700
Kees Cook  wrote:

> On Mon, May 23, 2016 at 3:17 PM, Emese Revfy  wrote:
> > @@ -1235,6 +1236,15 @@ static void __free_pages_ok(struct page *page, 
> > unsigned int order)
> >  }
> >
> >  #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
> > +bool __meminitdata extra_latent_entropy;
> > +
> > +static int __init setup_extra_latent_entropy(char *str)
> > +{
> > +   extra_latent_entropy = true;
> > +   return 0;
> > +}
> > +early_param("extra_latent_entropy", setup_extra_latent_entropy);
> > +
> >  volatile u64 latent_entropy __latent_entropy;
> >  EXPORT_SYMBOL(latent_entropy);
> >  #endif
> > @@ -1254,6 +1264,19 @@ static void __init __free_pages_boot_core(struct 
> > page *page, unsigned int order)
> > __ClearPageReserved(p);
> > set_page_count(p, 0);
> >
> > +#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
> > +   if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) 
> > < 0x10) {
> > +   u64 hash = 0;
> > +   size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
> > +   const u64 *data = lowmem_page_address(page);
> > +
> > +   for (index = 0; index < end; index++)
> > +   hash ^= hash + data[index];
> > +   latent_entropy ^= hash;
> > +   add_device_randomness((const void *)&latent_entropy, 
> > sizeof(latent_entropy));
> > +   }
> > +#endif
> > +
> 
> We try to minimize #ifdefs in the .c code, so in this case, I think I
> would define "extra_latent_entropy" during an #else above so this "if"
> can be culled by the compiler automatically:
> 
> #else
> # define extra_latent_entropy false
> #endif
> 
> Others may have better suggestions to avoid the second #ifdef, but
> this seems the cleanest way to me to tie this to the earlier #ifdef.

Hi,

I think the best way would be if I removed all #ifdefs because
this is useful without the latent_entropy plugin.
I don't know wether the default value of extra_latent_entropy
should be true or false. I'll do some performance measurements.

-- 
Emese


Re: [PATCH v1 2/3] Mark functions with the latent_entropy attribute

2016-05-24 Thread Emese Revfy
On Tue, 24 May 2016 10:16:09 -0700
Kees Cook  wrote:

> On Mon, May 23, 2016 at 3:16 PM, Emese Revfy  wrote:
> > +#ifdef CONFIG_MEMORY_HOTPLUG
> > +#define add_meminit_latent_entropy
> > +#else
> > +#define add_meminit_latent_entropy __latent_entropy
> > +#endif
> > +
> >  /* These are for everybody (although not all archs will actually
> > discard it in modules) */
> > -#define __init __section(.init.text) __cold notrace
> > +#define __init __section(.init.text) __cold notrace 
> > __latent_entropy
> >  #define __initdata __section(.init.data)
> >  #define __initconst__constsection(.init.rodata)
> >  #define __exitdata __section(.exit.data)
> > @@ -92,7 +98,7 @@
> >  #define __exit  __section(.exit.text) __exitused __cold notrace
> >
> >  /* Used for MEMORY_HOTPLUG */
> > -#define __meminit__section(.meminit.text) __cold notrace
> > +#define __meminit__section(.meminit.text) __cold notrace 
> > add_meminit_latent_entropy
> >  #define __meminitdata__section(.meminit.data)
> >  #define __meminitconst   __constsection(.meminit.rodata)
> >  #define __memexit__section(.memexit.text) __exitused __cold notrace
> 
> I was confused by these defines. :) Maybe "add_meminit_latent_entropy"
> should be named "__memory_hotplug_only_latent_entropy" or something
> like that?

I think the plugin doesn't cause a significant slowdown when 
CONFIG_MEMORY_HOTPLUG is enabled so I would rather always add the 
__latent_entropy attribute to __meminit.

-- 
Emese


Re: [PATCH v1 1/3] Add the latent_entropy gcc plugin

2016-05-24 Thread Emese Revfy
On Tue, 24 May 2016 10:32:15 -0700
Kees Cook  wrote:

> Also, does this matter that it's non-atomic? It seems like the u64
> below is being written to by multiple threads and even read by
> multiple threads. Am I misunderstanding something?

The non-atomic accesses are intentional because
they can extract more latent entropy from these data races.
 
> > [...]
> > new file mode 100644
> > index 000..7295c39
> > --- /dev/null
> > +++ b/scripts/gcc-plugins/latent_entropy_plugin.c
> 
> I feel like most of the functions in this plugin could use some more
> comments about what each one does.

I think the important parts are commented (most parts just use the gcc API).
Where would you like more comments?

-- 
Emese


Re: [kernel-hardening] [PATCH v8 2/4] GCC plugin infrastructure

2016-05-18 Thread Emese Revfy
> I've done some basic sanity testing on powerpc with the cyclomatic 
> complexity plugin (with LE native + cross-compilers) and it seems to 
> work with the patch below.
> 
> Signed-off-by: Andrew Donnellan 
> 
> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
> index a18a0dc..0cfed5b 100644
> --- a/arch/powerpc/Kconfig
> +++ b/arch/powerpc/Kconfig
> @@ -97,6 +97,7 @@ config PPC
>  select HAVE_DYNAMIC_FTRACE_WITH_REGS if MPROFILE_KERNEL
>  select HAVE_FUNCTION_TRACER
>  select HAVE_FUNCTION_GRAPH_TRACER
> +   select HAVE_GCC_PLUGINS
>  select SYSCTL_EXCEPTION_TRACE
>  select ARCH_WANT_OPTIONAL_GPIOLIB
>  select VIRT_TO_BUS if !PPC64

Hi,

Did you test the plugins with all gcc versions (4.5-6)?

-- 
Emese


Re: [kernel-hardening] [PATCH v8 3/4] Add Cyclomatic complexity GCC plugin

2016-05-18 Thread Emese Revfy
On Wed, 18 May 2016 18:25:00 +1000
Andrew Donnellan  wrote:

> On 13/05/16 09:58, Emese Revfy wrote:
> > Add a very simple plugin to demonstrate the GCC plugin infrastructure. This 
> > GCC
> > plugin computes the cyclomatic complexity of each function.
> 
> ...
> 
> > +config GCC_PLUGIN_CYC_COMPLEXITY
> > +   bool "Compute the cyclomatic complexity of a function"
> > +   depends on GCC_PLUGINS
> > +   help
> > + The complexity M of a function's control flow graph is defined as:
> > +  M = E - N + 2P
> > + where
> > +
> > + E = the number of edges
> > + N = the number of nodes
> > + P = the number of connected components (exit nodes).
> > +
> 
> If this plugin is intended primarily as a demonstration it's probably 
> worth mentioning this in the Kconfig description.

Hi,

Before sancov this plugin demonstrated the gcc plugin infrastructure but 
otherwise this is a fully working plugin not a test plugin. Also it doesn't 
demonstrate all aspects of writing gcc plugins.

-- 
Emese


Re: [PATCH v8 2/4] GCC plugin infrastructure

2016-05-18 Thread Emese Revfy
On Tue, 17 May 2016 16:28:05 +0200
Michal Marek  wrote:

> Dne 13.5.2016 v 01:57 Emese Revfy napsal(a):
> > --- /dev/null
> > +++ b/scripts/Makefile.gcc-plugins
> > @@ -0,0 +1,21 @@
> > +ifdef CONFIG_GCC_PLUGINS
> > +  __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
> > +  PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
> > "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
> > +
> > +  GCC_PLUGINS_CFLAGS := $(addprefix 
> > -fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y))
> > +
> > +  ifeq ($(PLUGINCC),)
> > +ifneq ($(GCC_PLUGINS_CFLAGS),)
> > +  ifeq ($(call cc-ifversion, -ge, 0405, y), y)
> > +PLUGINCC := $(shell $(CO, NFIG_SHELL) -x 
> > $(srctree)/scripts/gcc-plugin.sh "$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
> > +$(error error, your gcc installation does not support plugins, 
> > perhaps the necessary headers are missing?)
> > +  else
> > +$(error error, your gcc version does not support plugins, you 
> > should upgrade it to gcc 4.5 at least)
> > +  endif
> > +endif
> > +  endif
> > +
> > +  KBUILD_CFLAGS += $(GCC_PLUGINS_CFLAGS)
> > +  GCC_PLUGIN := $(gcc-plugin-y)
> > +
> > +endif
> 
> Hi Emese,
> 
> sorry for the late feedback. A problem I ran into now is that if you
> have a compiler that is either too old or built with plugin support
> disabled, scripts/Makefile.gcc-plugins errors out immediately. This is
> going to be an issue with allmodconfig/allyesconfig test builds. A
> solution would either be to make the respective options depend on
> !COMPILE_TEST, or turn the errors into warnings and do nothing if the
> compiler lacks plugin support. We are handling CONFIG_CC_STACKPROTECTOR
> on x86 this way already.

Hi,

I'll change the errors to warnings in the next patch set.

-- 
Emese


Re: [PATCH v7 2/6] GCC plugin infrastructure

2016-05-12 Thread Emese Revfy
On Wed, 11 May 2016 13:24:30 +0200
Michal Marek  wrote:

> On 2016-04-22 20:22, Emese Revfy wrote:
> > diff --git a/Documentation/dontdiff b/Documentation/dontdiff
> > index 8ea834f..5385cba 100644
> > --- a/Documentation/dontdiff
> > +++ b/Documentation/dontdiff
> > @@ -3,6 +3,7 @@
> >  *.bc
> >  *.bin
> >  *.bz2
> > +*.c.[012]*.*
> >  *.cis
> >  *.cpio
> >  *.csp
> 
> Hi Emese,
> 
> Where are these files generated? It should be added to .gitignore and
> the clean or mrproper rule if it's needed.

Hi,

Yes, they are generated by gcc options -fdump-* (if someone gives them in 
EXTRA_CFLAGS). 
I'll add these files to .gitignore and the clean rules.

-- 
Emese


[PATCH v8 0/4] Introduce GCC plugin infrastructure

2016-05-12 Thread Emese Revfy
This patch set introduce the GCC plugin infrastructure with examples for testing
and documentation.

GCC plugins are loadable modules that provide extra features to the compiler.
They are useful for runtime instrumentation and static analysis.

The infrastructure supports all gcc versions from 4.5 to 6.0, building
out-of-tree modules and building in a separate directory. Cross-compilation
is supported too but currently only the x86, arm, arm64 and uml architectures 
enable plugins.

This infrastructure was ported from grsecurity/PaX. It is a CII project
supported by the Linux Foundation.

Emese Revfy (4):
 Shared library support
 GCC plugin infrastructure
 Add Cyclomatic complexity plugin
 Add sancov plugin


Changes from v7:
 * Moved the "The GCC plugin infrastructure supports the arm and arm64 
architectures too"
   and the "Documentations of the GCC plugin infrastructre" patches
   into the "GCC plugin infrastructure" patch
(Suggested-by: Masahiro Yamada )
 * Add gcc-plugin.sh to MAINTAINERS
(Suggested-by: Masahiro Yamada )
 * Makefile.host: Remove *shobjs from multi-depend
(Suggested-by: Masahiro Yamada )
 * Have distclean and mrproper targets clean the *.so files
(Suggested-by: Masahiro Yamada )
 * Simplied gcc-plugin-y to add plugins to HOSTLIBS
(Suggested-by: Masahiro Yamada )
 * Simplified Makefile.host
(Suggested-by: Masahiro Yamada )
 * Clean *.c.[012]*.*
(Suggested-by: Michal Marek )
 * Documentation: gcc plugins have to compilable as C and C++
 * Enable GCC plugins for UML

Changes from v6:
 * Disable the sancov plugin whenever KCOV_INSTRUMENT is disabled
(Reported-by: Huang Ying )
 * Disable KCOV/sancov plugin because this is not a regular kernel code
(Reported-by: Huang Ying )
 * Removed unnecessary gcc plugin cflags
(Signed-off-by: Masahiro Yamada )
 * Removed unnecessary gcc plugin aflags

Changes from v5:
 * Set important properties on the external fndecl (Add sancov plugin)
 * Revert documentation change too (Shared library support)
(Suggested-by: Kees Cook )
 * The GCC plugin infrastructure now supports the arm and arm64 architectures 
too
(Signed-off-by: David Brown )
 * Simplify the computation of PLUGINCC (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify the invocation of gcc-plugin.sh (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Make use of multi-depend (Shared library support)
(Suggested-by: Masahiro Yamada )
 * Remove unnecessary exports (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify Makefile by using addprefix (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Moved the gcc plugins from tools/ to scripts/ (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Removed plugins from KBUILD_CFLAGS_32 (GCC plugin infrastructure)
 * Remove gcc-plugin target everywhere
(Suggested-by and partly Written-by: Masahiro Yamada 
)
 * There is no leaf gcc attribute in gcc-4.5 (Add sancov plugin)
 * Added support to the sancov plugin with kcov (Add sancov plugin)

Changes from v4:
 * Moved shared library support from the GCC plugin infrastructure patch into
   a different patch
 * Update gcc-*.h from PaX
   * Fixed gcc-common.h for gcc 6
   * Added pass cloning support to the gcc pass generators
 * Disable all plugins in vdso because it is userland code
 * Add sancov gcc plugin: another use case for gcc plugin support in the kernel
   is when there is a feature in the latest gcc version and we would like to use
   it with older gcc versions as well (e.g., distros).

Changes from v3:
 * Fix some indentation related warnings
   (Suggested by checkpatch.pl)
 * Add maintainer entries
 * Don't run gcc_plugin.sh when the GCC_PLUGINS option is disabled or 
unsupported
   (Reported-by: Fengguang Wu )

Changes from v2:
 * Fixed incorrectly encoded characters
 * Generate the GIMPLE, IPA, SIMPLE_IPA and RTL pass structures
   (Suggested-by: Rasmus Villemoes )
 * Write plugin related warning messages to stderr instead of stdout
   (Suggested-by: Kees Cook )
 * Mention the installation of the gcc plugin headers (Documentation)

Changes from v1:
 * Move the gcc-plugins make target into a separate Makefile because there may
   be a lot of plugins (Suggested-by: Rasmus Villemoes)
 * Simplify the dependencies of the plugin related config option
   (Suggested-by: Kees Cook )
 * Removed the unnecessary example plugin

---
 .gitignore |   1 +
 Documentation/dontdiff |   1 +
 Documentation/gcc-plugins.txt  |  87 +++
 MAINTAINERS|   9 +
 Makefile   |  24 +-
 arch/Kconfig   |  36 +
 arch/arm/Kconfig   |   1 +
 arch/arm64/Kconfig 

[PATCH v8 1/4] Shared library support

2016-05-12 Thread Emese Revfy
Infrastructure for building independent shared library targets.

Signed-off-by: Emese Revfy 
---
 scripts/Makefile.build |  2 +-
 scripts/Makefile.clean |  4 +++-
 scripts/Makefile.host  | 55 +-
 3 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0d1ca5b..11602e5 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -60,7 +60,7 @@ endif
 endif
 
 # Do not include host rules unless needed
-ifneq ($(hostprogs-y)$(hostprogs-m),)
+ifneq 
($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),)
 include scripts/Makefile.host
 endif
 
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 55c96cb..50616ea 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -38,7 +38,9 @@ subdir-ymn:= $(addprefix $(obj)/,$(subdir-ymn))
 __clean-files  := $(extra-y) $(extra-m) $(extra-)   \
   $(always) $(targets) $(clean-files)   \
   $(host-progs) \
-  $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
+  $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
+  $(hostlibs-y) $(hostlibs-m) $(hostlibs-) \
+  $(hostcxxlibs-y) $(hostcxxlibs-m)
 
 __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 133edfa..45b5b1a 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -20,7 +20,15 @@
 # Will compile qconf as a C++ program, and menu as a C program.
 # They are linked as C++ code to the executable qconf
 
+# hostcc-option
+# Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586)
+
+hostcc-option = $(call try-run,\
+   $(HOSTCC) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(1) -c -x c /dev/null -o 
"$$TMP",$(1),$(2))
+
 __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
+host-cshlib := $(sort $(hostlibs-y) $(hostlibs-m))
+host-cxxshlib := $(sort $(hostcxxlibs-y) $(hostcxxlibs-m))
 
 # C code
 # Executables compiled from a single .c file
@@ -42,6 +50,10 @@ host-cxxmulti:= $(foreach m,$(__hostprogs),$(if 
$($(m)-cxxobjs),$(m)))
 # C++ Object (.o) files compiled from .cc files
 host-cxxobjs   := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
 
+# Object (.o) files used by the shared libaries
+host-cshobjs   := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs
+host-cxxshobjs := $(sort $(foreach m,$(host-cxxshlib),$($(m:.so=-objs
+
 # output directory for programs/.o files
 # hostprogs-y := tools/build may have been specified.
 # Retrieve also directory of .o files from prog-objs or prog-cxxobjs notation
@@ -56,6 +68,10 @@ host-cmulti  := $(addprefix $(obj)/,$(host-cmulti))
 host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
 host-cxxmulti  := $(addprefix $(obj)/,$(host-cxxmulti))
 host-cxxobjs   := $(addprefix $(obj)/,$(host-cxxobjs))
+host-cshlib:= $(addprefix $(obj)/,$(host-cshlib))
+host-cxxshlib  := $(addprefix $(obj)/,$(host-cxxshlib))
+host-cshobjs   := $(addprefix $(obj)/,$(host-cshobjs))
+host-cxxshobjs := $(addprefix $(obj)/,$(host-cxxshobjs))
 host-objdirs:= $(addprefix $(obj)/,$(host-objdirs))
 
 obj-dirs += $(host-objdirs)
@@ -124,5 +140,42 @@ quiet_cmd_host-cxxobjs = HOSTCXX $@
 $(host-cxxobjs): $(obj)/%.o: $(src)/%.cc FORCE
$(call if_changed_dep,host-cxxobjs)
 
+# Compile .c file, create position independent .o file
+# host-cshobjs -> .o
+quiet_cmd_host-cshobjs = HOSTCC  -fPIC $@
+  cmd_host-cshobjs = $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
+$(host-cshobjs): $(obj)/%.o: $(src)/%.c FORCE
+   $(call if_changed_dep,host-cshobjs)
+
+# Compile .c file, create position independent .o file
+# Note that plugin capable gcc versions can be either C or C++ based
+# therefore plugin source files have to be compilable in both C and C++ mode.
+# This is why a C++ compiler is invoked on a .c file.
+# host-cxxshobjs -> .o
+quiet_cmd_host-cxxshobjs   = HOSTCXX -fPIC $@
+  cmd_host-cxxshobjs   = $(HOSTCXX) $(hostcxx_flags) -fPIC -c -o $@ $<
+$(host-cxxshobjs): $(obj)/%.o: $(src)/%.c FORCE
+   $(call if_changed_dep,host-cxxshobjs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cshlib)
+quiet_cmd_host-cshlib  = HOSTLLD -shared $@
+  cmd_host-cshlib  = $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
+ $(addprefix $(obj)/,$($(@F:.so=-objs))) \
+ $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
+$(host-cshlib): FORCE
+   $(call if_changed,host-cshlib)
+$(call multi_depend, $(host-cshlib), .so, -objs)
+
+# Link a shared library, based on position independent .o files
+# *.o -> .so shared library (host-cxxshlib)
+quiet_cmd_host-cxxshlib= HOSTLLD -shared $@
+  cmd_host-cxxshlib= $(HOSTCXX) $(HOSTLDFLAGS) -shared -o $@ \
+  

[PATCH v8 2/4] GCC plugin infrastructure

2016-05-12 Thread Emese Revfy
This patch allows to build the whole kernel with GCC plugins. It was ported from
grsecurity/PaX. The infrastructure supports building out-of-tree modules and
building in a separate directory. Cross-compilation is supported too.
Currently the x86, arm, arm64 and uml architectures enable plugins.

The directory of the gcc plugins is scripts/gcc-plugins. You can use a file or 
a directory
there. The plugins compile with these options:
 * -fno-rtti: gcc is compiled with this option so the plugins must use it too
 * -fno-exceptions: this is inherited from gcc too
 * -fasynchronous-unwind-tables: this is inherited from gcc too
 * -ggdb: it is useful for debugging a plugin (better backtrace on internal
errors)
 * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h)
 * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version
variable, plugin-version.h)

The infrastructure introduces a new Makefile target called gcc-plugins. It
supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script
chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++).
This script also checks the availability of the included headers in
scripts/gcc-plugins/gcc-common.h.

The gcc-common.h header contains frequently included headers for GCC plugins
and it has a compatibility layer for the supported gcc versions.

The gcc-generate-*-pass.h headers automatically generate the registration
structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes.

Note that 'make clean' keeps the *.so files (only the distclean or mrproper
targets clean all) because they are needed for out-of-tree modules.

The arm and arm64 architectures were tested by David Brown 
.

Signed-off-by: Emese Revfy 
---
 .gitignore |   1 +
 Documentation/dontdiff |   1 +
 Documentation/gcc-plugins.txt  |  87 +++
 MAINTAINERS|   9 +
 Makefile   |  16 +-
 arch/Kconfig   |  15 +
 arch/arm/Kconfig   |   1 +
 arch/arm64/Kconfig |   1 +
 arch/um/Kconfig.common |   1 +
 arch/x86/Kconfig   |   1 +
 arch/x86/entry/vdso/Makefile   |   3 +-
 scripts/Makefile   |   2 +-
 scripts/Makefile.gcc-plugins   |  21 +
 scripts/gcc-plugin.sh  |  51 ++
 scripts/gcc-plugins/Makefile   |  20 +
 scripts/gcc-plugins/gcc-common.h   | 830 +
 scripts/gcc-plugins/gcc-generate-gimple-pass.h | 175 +
 scripts/gcc-plugins/gcc-generate-ipa-pass.h| 289 +++
 scripts/gcc-plugins/gcc-generate-rtl-pass.h| 175 +
 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 175 +
 scripts/link-vmlinux.sh|   2 +-
 scripts/package/builddeb   |   1 +
 22 files changed, 1872 insertions(+), 5 deletions(-)
 create mode 100644 Documentation/gcc-plugins.txt
 create mode 100644 scripts/Makefile.gcc-plugins
 create mode 100755 scripts/gcc-plugin.sh
 create mode 100644 scripts/gcc-plugins/Makefile
 create mode 100644 scripts/gcc-plugins/gcc-common.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-gimple-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-ipa-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-rtl-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h

diff --git a/.gitignore b/.gitignore
index 0c320bf..2be25f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@ modules.builtin
 Module.symvers
 *.dwo
 *.su
+*.c.[012]*.*
 
 #
 # Top-level generic files
diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 8ea834f..5385cba 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -3,6 +3,7 @@
 *.bc
 *.bin
 *.bz2
+*.c.[012]*.*
 *.cis
 *.cpio
 *.csp
diff --git a/Documentation/gcc-plugins.txt b/Documentation/gcc-plugins.txt
new file mode 100644
index 000..891c694
--- /dev/null
+++ b/Documentation/gcc-plugins.txt
@@ -0,0 +1,87 @@
+GCC plugin infrastructure
+=
+
+
+1. Introduction
+===
+
+GCC plugins are loadable modules that provide extra features to the
+compiler [1]. They are useful for runtime instrumentation and static analysis.
+We can analyse, change and add further code during compilation via
+callbacks [2], GIMPLE [3], IPA [4] and RTL passes [5].
+
+The GCC plugin infrastructure of the kernel supports all gcc versions from
+4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a
+separate directory.
+Plugin source files have to be compilable by both a C and a C++ compiler as 
well
+because gcc versions 4.5 and 4.6 are compiled by a C compiler,
+gcc-

[PATCH v8 3/4] Add Cyclomatic complexity GCC plugin

2016-05-12 Thread Emese Revfy
Add a very simple plugin to demonstrate the GCC plugin infrastructure. This GCC
plugin computes the cyclomatic complexity of each function.

The complexity M of a function's control flow graph is defined as:
M = E - N + 2P
where
E = the number of edges
N = the number of nodes
P = the number of connected components (exit nodes).

Signed-off-by: Emese Revfy 
---
 arch/Kconfig| 12 +
 scripts/Makefile.gcc-plugins|  1 +
 scripts/gcc-plugins/Makefile|  1 +
 scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +
 4 files changed, 87 insertions(+)
 create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 2821cfe..74f0d63 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -372,6 +372,18 @@ menuconfig GCC_PLUGINS
 
  See Documentation/gcc-plugins.txt for details.
 
+config GCC_PLUGIN_CYC_COMPLEXITY
+   bool "Compute the cyclomatic complexity of a function"
+   depends on GCC_PLUGINS
+   help
+ The complexity M of a function's control flow graph is defined as:
+  M = E - N + 2P
+ where
+
+ E = the number of edges
+ N = the number of nodes
+ P = the number of connected components (exit nodes).
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 78d81fc..bf0eaf1 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,6 +2,7 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
   ifeq ($(PLUGINCC),)
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index a4c9341..c60ba4b 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -17,4 +17,5 @@ export GCCPLUGINS_DIR HOSTLIBS
 $(HOSTLIBS)-y := $(GCC_PLUGIN)
 always := $($(HOSTLIBS)-y)
 
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
 clean-files += *.so
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c 
b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 000..34df974
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy 
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ *  E = the number of edges of the graph
+ *  N = the number of nodes of the graph
+ *  P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+   .version= "20160225",
+   .help   = "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+   int complexity;
+   expanded_location xloc;
+
+   /* M = E - N + 2P */
+   complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+   xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+   fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+   xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+   return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct 
plugin_gcc_version *version)
+{
+   const char * const plugin_name = plugin_info->base_name;
+   struct register_pass_info cyc_complexity_pass_info;
+
+   cyc_complexity_pass_info.pass   = 
make_cyc_complexity_pass();
+   cyc_complexity_pass_info.reference_pass_name= "ssa";
+   cyc_complexity_pass_info.ref_pass_instance_number   = 1;
+   cyc_complexity_pass_info.pos_op = 
PASS_POS_INSERT_AFTER;
+
+   if (!plugin_default_version_check(version, &gcc_version)) {
+   error(G_("incompatible gcc/plugin versions"));
+   return 1;
+   }
+
+   register_callback(plugin_name, PLUGIN_INFO, NULL,
+   &cyc_complexity_plugin_info);
+   register_callback(plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
+   &cyc_complexity_pass_info);
+
+   return 0;
+}
-- 
2.8.1



[PATCH v8 4/4] Add sancov plugin

2016-05-12 Thread Emese Revfy
The sancov gcc plugin inserts a __sanitizer_cov_trace_pc() call
at the start of basic blocks.

This plugin is a helper plugin for the kcov feature. It supports
all gcc versions with plugin support (from gcc-4.5 on).
It is based on the gcc commit "Add fuzzing coverage support" by Dmitry Vyukov
(https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296).

Signed-off-by: Emese Revfy 
---
 Makefile|  12 +--
 arch/Kconfig|   9 +++
 arch/x86/purgatory/Makefile |   2 +
 lib/Kconfig.debug   |   2 +
 scripts/Makefile.gcc-plugins|  19 +
 scripts/gcc-plugins/Makefile|   6 ++
 scripts/gcc-plugins/sancov_plugin.c | 144 
 7 files changed, 184 insertions(+), 10 deletions(-)
 create mode 100644 scripts/gcc-plugins/sancov_plugin.c

diff --git a/Makefile b/Makefile
index 972d845..2eed43f 100644
--- a/Makefile
+++ b/Makefile
@@ -369,7 +369,7 @@ LDFLAGS_MODULE  =
 CFLAGS_KERNEL  =
 AFLAGS_KERNEL  =
 CFLAGS_GCOV= -fprofile-arcs -ftest-coverage -fno-tree-loop-im 
-Wno-maybe-uninitialized
-CFLAGS_KCOV= -fsanitize-coverage=trace-pc
+CFLAGS_KCOV:= $(call cc-option,-fsanitize-coverage=trace-pc,)
 
 
 # Use USERINCLUDE when you must reference the UAPI directories only.
@@ -422,7 +422,7 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE 
KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
 export KBUILD_ARFLAGS
 
-export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN
+export PLUGINCC GCC_PLUGINS_CFLAGS SANCOV_PLUGIN GCC_PLUGIN
 
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
@@ -693,14 +693,6 @@ endif
 endif
 KBUILD_CFLAGS += $(stackp-flag)
 
-ifdef CONFIG_KCOV
-  ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
-$(warning Cannot use CONFIG_KCOV: \
- -fsanitize-coverage=trace-pc is not supported by compiler)
-CFLAGS_KCOV =
-  endif
-endif
-
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
 KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)
diff --git a/arch/Kconfig b/arch/Kconfig
index 74f0d63..5feadad 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -384,6 +384,15 @@ config GCC_PLUGIN_CYC_COMPLEXITY
  N = the number of nodes
  P = the number of connected components (exit nodes).
 
+config GCC_PLUGIN_SANCOV
+   bool
+   depends on GCC_PLUGINS
+   help
+ This plugin inserts a __sanitizer_cov_trace_pc() call at the start of
+ basic blocks. It supports all gcc versions with plugin support (from
+ gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
+ by Dmitry Vyukov .
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 12734a9..ac58c16 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -8,6 +8,8 @@ PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z 
nodefaultlib
 targets += purgatory.ro
 
+KCOV_INSTRUMENT := n
+
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
 # sure how to relocate those. Like kexec-tools, use custom flags.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 5d57177..a377fd7 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -712,6 +712,8 @@ config KCOV
bool "Code coverage for fuzzing"
depends on ARCH_HAS_KCOV
select DEBUG_FS
+   select GCC_PLUGINS
+   select GCC_PLUGIN_SANCOV
help
  KCOV exposes kernel code coverage information in a form suitable
  for coverage-guided fuzzing (randomized testing).
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index bf0eaf1..372c73a 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,7 +2,23 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
+
   gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
+
+  ifdef CONFIG_GCC_PLUGIN_SANCOV
+ifeq ($(CFLAGS_KCOV),)
+  # It is needed because of the gcc-plugin.sh and gcc version checks.
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)   += sancov_plugin.so
+
+  ifneq ($(PLUGINCC),)
+CFLAGS_KCOV := $(SANCOV_PLUGIN)
+  else
+$(error Cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not 
supported by compiler)
+  endif
+endif
+  endif
+
   GCC_PLUGINS_CFLAGS := $

[PATCH v7 0/6] Introduce GCC plugin infrastructure

2016-04-22 Thread Emese Revfy
This patch set introduce the GCC plugin infrastructure with examples for testing
and documentation.

GCC plugins are loadable modules that provide extra features to the compiler.
They are useful for runtime instrumentation and static analysis.

The infrastructure supports all gcc versions from 4.5 to 6.0, building
out-of-tree modules and building in a separate directory. Cross-compilation
is supported too but currently only the x86, arm and arm64 architectures 
enables plugins.

This infrastructure was ported from grsecurity/PaX. It is a CII project
supported by the Linux Foundation.

Emese Revfy (6):
 Shared library support
 GCC plugin infrastructure
 The GCC plugin infrastructure supports the arm and arm64 architectures too
 Add Cyclomatic complexity plugin
 Documentations of the GCC plugin infrastructre
 Add sancov plugin


Changes from v6:
 * Disable the sancov plugin whenever KCOV_INSTRUMENT is disabled
(Reported-by: Huang Ying )
 * Disable KCOV/sancov plugin because this is not a regular kernel code
(Reported-by: Huang Ying )
 * Removed unnecessary gcc plugin cflags
(Signed-off-by: Masahiro Yamada )
 * Removed unnecessary gcc plugin aflags

Changes from v5:
 * Set important properties on the external fndecl (Add sancov plugin)
 * Revert documentation change too (Shared library support)
(Suggested-by: Kees Cook )
 * The GCC plugin infrastructure now supports the arm and arm64 architectures 
too
(Signed-off-by: David Brown )
 * Simplify the computation of PLUGINCC (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify the invocation of gcc-plugin.sh (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Make use of multi-depend (Shared library support)
(Suggested-by: Masahiro Yamada )
 * Remove unnecessary exports (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify Makefile by using addprefix (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Moved the gcc plugins from tools/ to scripts/ (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Removed plugins from KBUILD_CFLAGS_32 (GCC plugin infrastructure)
 * Remove gcc-plugin target everywhere
(Suggested-by and partly Written-by: Masahiro Yamada 
)
 * There is no leaf gcc attribute in gcc-4.5 (Add sancov plugin)
 * Added support to the sancov plugin with kcov (Add sancov plugin)

Changes from v4:
 * Moved shared library support from the GCC plugin infrastructure patch into
   a different patch
 * Update gcc-*.h from PaX
   * Fixed gcc-common.h for gcc 6
   * Added pass cloning support to the gcc pass generators
 * Disable all plugins in vdso because it is userland code
 * Add sancov gcc plugin: another use case for gcc plugin support in the kernel
   is when there is a feature in the latest gcc version and we would like to use
   it with older gcc versions as well (e.g., distros).

Changes from v3:
 * Fix some indentation related warnings
   (Suggested by checkpatch.pl)
 * Add maintainer entries
 * Don't run gcc_plugin.sh when the GCC_PLUGINS option is disabled or 
unsupported
   (Reported-by: Fengguang Wu )

Changes from v2:
 * Fixed incorrectly encoded characters
 * Generate the GIMPLE, IPA, SIMPLE_IPA and RTL pass structures
   (Suggested-by: Rasmus Villemoes )
 * Write plugin related warning messages to stderr instead of stdout
   (Suggested-by: Kees Cook )
 * Mention the installation of the gcc plugin headers (Documentation)

Changes from v1:
 * Move the gcc-plugins make target into a separate Makefile because there may
   be a lot of plugins (Suggested-by: Rasmus Villemoes)
 * Simplify the dependencies of the plugin related config option
   (Suggested-by: Kees Cook )
 * Removed the unnecessary example plugin

---
 Documentation/dontdiff |   1 +
 Documentation/gcc-plugins.txt  |  83 +++
 Documentation/kbuild/makefiles.txt |  39 +-
 Documentation/kernel-parameters.txt|   5 +
 MAINTAINERS|   8 +
 Makefile   |  25 +-
 arch/Kconfig   |  36 +
 arch/arm/Kconfig   |   1 +
 arch/arm64/Kconfig |   1 +
 arch/x86/Kconfig   |   1 +
 arch/x86/entry/vdso/Makefile   |   3 +-
 arch/x86/purgatory/Makefile|   2 +
 lib/Kconfig.debug  |   2 +
 scripts/Makefile   |   2 +-
 scripts/Makefile.build |   2 +-
 scripts/Makefile.clean |   3 +-
 scripts/Makefile.gcc-plugins   |  40 +
 scripts/Makefile.host  |  70 +-
 scripts/gcc-plugin.sh  |  51 ++
 scripts/gcc-plugins/Makefile   |  24 +
 scripts/gcc-pl

[PATCH v7 1/6] Shared library support

2016-04-22 Thread Emese Revfy
Infrastructure for building independent shared library targets.
This effectively also reverts commit 62e2210798ed38928ab24841e8b4878a
(Masahiro Yamada, kbuild: drop shared library support from Makefile.host).

Signed-off-by: Emese Revfy 
---
 Documentation/kbuild/makefiles.txt | 39 -
 scripts/Makefile.build |  2 +-
 scripts/Makefile.clean |  3 +-
 scripts/Makefile.host  | 70 +-
 4 files changed, 103 insertions(+), 11 deletions(-)

diff --git a/Documentation/kbuild/makefiles.txt 
b/Documentation/kbuild/makefiles.txt
index 13f888a..250729b 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -23,10 +23,11 @@ This document describes the Linux kernel Makefiles.
=== 4 Host Program support
   --- 4.1 Simple Host Program
   --- 4.2 Composite Host Programs
-  --- 4.3 Using C++ for host programs
-  --- 4.4 Controlling compiler options for host programs
-  --- 4.5 When host programs are actually built
-  --- 4.6 Using hostprogs-$(CONFIG_FOO)
+  --- 4.3 Defining shared libraries
+  --- 4.4 Using C++ for host programs
+  --- 4.5 Controlling compiler options for host programs
+  --- 4.6 When host programs are actually built
+  --- 4.7 Using hostprogs-$(CONFIG_FOO)
 
=== 5 Kbuild clean infrastructure
 
@@ -643,7 +644,29 @@ Both possibilities are described in the following.
Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax -y is not permitted for host-programs.
 
 4.3 Using C++ for host programs
+--- 4.3 Defining shared libraries
+
+   Objects with extension .so are considered shared libraries, and
+   will be compiled as position independent objects.
+   Kbuild provides support for shared libraries, but the usage
+   shall be restricted.
+   In the following example the libkconfig.so shared library is used
+   to link the executable conf.
+
+   Example:
+   #scripts/kconfig/Makefile
+   hostprogs-y := conf
+   conf-objs   := conf.o libkconfig.so
+   libkconfig-objs := expr.o type.o
+
+   Shared libraries always require a corresponding -objs line, and
+   in the example above the shared library libkconfig is composed by
+   the two objects expr.o and type.o.
+   expr.o and type.o will be built as position independent code and
+   linked as a shared library libkconfig.so. C++ is not supported for
+   shared libraries.
+
+--- 4.4 Using C++ for host programs
 
kbuild offers support for host programs written in C++. This was
introduced solely to support kconfig, and is not recommended
@@ -666,7 +689,7 @@ Both possibilities are described in the following.
qconf-cxxobjs := qconf.o
qconf-objs:= check.o
 
 4.4 Controlling compiler options for host programs
+--- 4.5 Controlling compiler options for host programs
 
When compiling host programs, it is possible to set specific flags.
The programs will always be compiled utilising $(HOSTCC) passed
@@ -694,7 +717,7 @@ Both possibilities are described in the following.
When linking qconf, it will be passed the extra option
"-L$(QTDIR)/lib".
 
 4.5 When host programs are actually built
+--- 4.6 When host programs are actually built
 
Kbuild will only build host-programs when they are referenced
as a prerequisite.
@@ -725,7 +748,7 @@ Both possibilities are described in the following.
This will tell kbuild to build lxdialog even if not referenced in
any rule.
 
 4.6 Using hostprogs-$(CONFIG_FOO)
+--- 4.7 Using hostprogs-$(CONFIG_FOO)
 
A typical pattern in a Kbuild file looks like this:
 
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index 0d1ca5b..11602e5 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -60,7 +60,7 @@ endif
 endif
 
 # Do not include host rules unless needed
-ifneq ($(hostprogs-y)$(hostprogs-m),)
+ifneq 
($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),)
 include scripts/Makefile.host
 endif
 
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 55c96cb..e4e88ab 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -38,7 +38,8 @@ subdir-ymn:= $(addprefix $(obj)/,$(subdir-ymn))
 __clean-files  := $(extra-y) $(extra-m) $(extra-)   \
   $(always) $(targets) $(clean-files)   \
   $(host-progs) \
-  $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
+  $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
+  $(hostlibs-y) $(hostlibs-m) $(hostlibs-)
 
 __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
diff --git a/scripts/Makef

[PATCH v7 2/6] GCC plugin infrastructure

2016-04-22 Thread Emese Revfy
This patch allows to build the whole kernel with GCC plugins. It was ported from
grsecurity/PaX. The infrastructure supports building out-of-tree modules and
building in a separate directory. Cross-compilation is supported too but
currently only the x86 architecture enables plugins.

The directory of the gcc plugins is tools/gcc. You can use a file or a directory
there. The plugins compile with these options:
 * -fno-rtti: gcc is compiled with this option so the plugins must use it too
 * -fno-exceptions: this is inherited from gcc too
 * -fasynchronous-unwind-tables: this is inherited from gcc too
 * -ggdb: it is useful for debugging a plugin (better backtrace on internal
errors)
 * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h)
 * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version
variable, plugin-version.h)

The infrastructure introduces a new Makefile target called gcc-plugins. It
supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script
chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++).
This script also checks the availability of the included headers in
tools/gcc/gcc-common.h.

The gcc-common.h header contains frequently included headers for GCC plugins
and it has a compatibility layer for the supported gcc versions.

The gcc-generate-*-pass.h headers automatically generate the registration
structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes.

Note that 'make clean' keeps the *.so files (only the distclean or mrproper
targets clean all) because they are needed for out-of-tree modules.

Signed-off-by: Emese Revfy 
---
 Documentation/dontdiff |   1 +
 MAINTAINERS|   8 +
 Makefile   |  17 +-
 arch/Kconfig   |  13 +
 arch/x86/Kconfig   |   1 +
 arch/x86/entry/vdso/Makefile   |   3 +-
 scripts/Makefile   |   2 +-
 scripts/Makefile.gcc-plugins   |  20 +
 scripts/gcc-plugin.sh  |  51 ++
 scripts/gcc-plugins/Makefile   |  15 +
 scripts/gcc-plugins/gcc-common.h   | 830 +
 scripts/gcc-plugins/gcc-generate-gimple-pass.h | 175 +
 scripts/gcc-plugins/gcc-generate-ipa-pass.h| 289 +++
 scripts/gcc-plugins/gcc-generate-rtl-pass.h| 175 +
 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 175 +
 scripts/link-vmlinux.sh|   2 +-
 scripts/package/builddeb   |   1 +
 17 files changed, 1772 insertions(+), 6 deletions(-)
 create mode 100644 scripts/Makefile.gcc-plugins
 create mode 100755 scripts/gcc-plugin.sh
 create mode 100644 scripts/gcc-plugins/Makefile
 create mode 100644 scripts/gcc-plugins/gcc-common.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-gimple-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-ipa-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-rtl-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h

diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 8ea834f..5385cba 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -3,6 +3,7 @@
 *.bc
 *.bin
 *.bz2
+*.c.[012]*.*
 *.cis
 *.cpio
 *.csp
diff --git a/MAINTAINERS b/MAINTAINERS
index e12a27c..de91d6c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4777,6 +4777,14 @@ L:   linux-s...@vger.kernel.org
 S: Odd Fixes (e.g., new signatures)
 F: drivers/scsi/fdomain.*
 
+GCC PLUGINS
+M: Kees Cook 
+R: Emese Revfy 
+L: kernel-harden...@lists.openwall.com
+S: Maintained
+F: scripts/gcc-plugins/
+F: Documentation/gcc-plugins.txt
+
 GCOV BASED KERNEL PROFILING
 M: Peter Oberparleiter 
 S: Maintained
diff --git a/Makefile b/Makefile
index c3937c5..22f0e1b 100644
--- a/Makefile
+++ b/Makefile
@@ -418,6 +418,8 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE 
KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
 export KBUILD_ARFLAGS
 
+export PLUGINCC GCC_PLUGINS_CFLAGS
+
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
 # even be read-only.
@@ -548,7 +550,7 @@ ifeq ($(KBUILD_EXTMOD),)
 # in parallel
 PHONY += scripts
 scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \
-asm-generic
+asm-generic gcc-plugins
$(Q)$(MAKE) $(build)=$(@)
 
 # Objects we will link into vmlinux / subdirs we need to visit
@@ -623,6 +625,15 @@ endif
 # Tell gcc to never replace conditional load with a non-conditional one
 KBUILD_CFLAGS  += $(call cc-option,--param=allow-store-data-races=0)
 
+PHONY += gcc-plugins
+gcc-plugins: scripts_basic
+ifdef CONFIG_GCC_PLUGINS
+   $(Q)$(MAKE) $(build)=s

[PATCH v7 3/6] The GCC plugin infrastructure supports the arm and arm64 architectures too

2016-04-22 Thread Emese Revfy
The GCC plugin infrastructure supports the arm and arm64 architectures too

Signed-off-by: David Brown 
---
 arch/arm/Kconfig   | 1 +
 arch/arm64/Kconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0846026..8f57eb6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -55,6 +55,7 @@ config ARM
select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
+   select HAVE_GCC_PLUGINS
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || 
CPU_V7))
select HAVE_IDE if PCI || ISA || PCMCIA
select HAVE_IRQ_TIME_ACCOUNTING
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index c8762f4..33f30f6 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -76,6 +76,7 @@ config ARM64
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
+   select HAVE_GCC_PLUGINS
select HAVE_GENERIC_DMA_COHERENT
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IRQ_TIME_ACCOUNTING
-- 
2.4.1



[PATCH v7 4/6] Add Cyclomatic complexity GCC plugin

2016-04-22 Thread Emese Revfy
Add a very simple plugin to demonstrate the GCC plugin infrastructure. This GCC
plugin computes the cyclomatic complexity of each function.

The complexity M of a function's control flow graph is defined as:
M = E - N + 2P
where
E = the number of edges
N = the number of nodes
P = the number of connected components (exit nodes).

Signed-off-by: Emese Revfy 
---
 arch/Kconfig| 12 +
 scripts/Makefile.gcc-plugins|  2 +
 scripts/gcc-plugins/Makefile|  4 ++
 scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +
 4 files changed, 91 insertions(+)
 create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 7c12571..ddf29b4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -366,6 +366,18 @@ menuconfig GCC_PLUGINS
  GCC plugins are loadable modules that provide extra features to the
  compiler. They are useful for runtime instrumentation and static 
analysis.
 
+config GCC_PLUGIN_CYC_COMPLEXITY
+   bool "Compute the cyclomatic complexity of a function"
+   depends on GCC_PLUGINS
+   help
+ The complexity M of a function's control flow graph is defined as:
+  M = E - N + 2P
+ where
+
+ E = the number of edges
+ N = the number of nodes
+ P = the number of connected components (exit nodes).
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index e6d66e2..282d63a 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,6 +2,8 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
+
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
   ifeq ($(PLUGINCC),)
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index b2d64af..31c72bf 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -12,4 +12,8 @@ endif
 
 export GCCPLUGINS_DIR HOSTLIBS
 
+$(HOSTLIBS)-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) := cyc_complexity_plugin.so
+
 always := $($(HOSTLIBS)-y)
+
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c 
b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 000..34df974
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy 
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ *  E = the number of edges of the graph
+ *  N = the number of nodes of the graph
+ *  P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+   .version= "20160225",
+   .help   = "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+   int complexity;
+   expanded_location xloc;
+
+   /* M = E - N + 2P */
+   complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+   xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+   fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+   xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+   return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct 
plugin_gcc_version *version)
+{
+   const char * const plugin_name = plugin_info->base_name;
+   struct register_pass_info cyc_complexity_pass_info;
+
+   cyc_complexity_pass_info.pass   = 
make_cyc_complexity_pass();
+   cyc_complexity_pass_info.reference_pass_name= "ssa";
+   cyc_complexity_pass_info.ref_pass_instance_number   = 1;
+   cyc_complexity_pass_info.pos_op = 
PASS_POS_INSERT_AFTER;
+
+   if (!plugin_default_version_check(version, &gcc_version)) {
+   error(G_("incompatible gcc/plugin versions"));
+   return 1;
+   }
+
+   register_callback(plugin_name, PLUGIN_INFO, NULL,
+

[PATCH v7 5/6] Documentation for the GCC plugin infrastructure

2016-04-22 Thread Emese Revfy
This is the GCC infrastructure documentation about its operation, how to add
and use a new plugin with an example.

Signed-off-by: Emese Revfy 
---
 Documentation/gcc-plugins.txt | 83 +++
 arch/Kconfig  |  2 ++
 2 files changed, 85 insertions(+)
 create mode 100644 Documentation/gcc-plugins.txt

diff --git a/Documentation/gcc-plugins.txt b/Documentation/gcc-plugins.txt
new file mode 100644
index 000..9fa9bd2
--- /dev/null
+++ b/Documentation/gcc-plugins.txt
@@ -0,0 +1,83 @@
+GCC plugin infrastructure
+=
+
+
+1. Introduction
+===
+
+GCC plugins are loadable modules that provide extra features to the
+compiler [1]. They are useful for runtime instrumentation and static analysis.
+We can analyse, change and add further code during compilation via
+callbacks [2], GIMPLE [3], IPA [4] and RTL passes [5].
+
+The GCC plugin infrastructure of the kernel supports all gcc versions from
+4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a
+separate directory.
+
+Currently the GCC plugin infrastructure supports only the x86, arm and arm64
+architectures.
+
+This infrastructure was ported from grsecurity [6] and PaX [7].
+
+--
+[1] https://gcc.gnu.org/onlinedocs/gccint/Plugins.html
+[2] https://gcc.gnu.org/onlinedocs/gccint/Plugin-API.html#Plugin-API
+[3] https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html
+[4] https://gcc.gnu.org/onlinedocs/gccint/IPA.html
+[5] https://gcc.gnu.org/onlinedocs/gccint/RTL.html
+[6] https://grsecurity.net/
+[7] https://pax.grsecurity.net/
+
+
+2. Files
+
+
+$(src)/scripts/gcc-plugins
+   This is the directory of the GCC plugins.
+
+$(src)/scripts/gcc-plugins/gcc-common.h
+   This is a compatibility header for GCC plugins.
+   It should be always included instead of individual gcc headers.
+
+$(src)/scripts/gcc-plugin.sh
+   This script checks the availability of the included headers in
+   gcc-common.h and chooses the proper host compiler to build the plugins
+   (gcc-4.7 can be built by either gcc or g++).
+
+$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h
+$(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h
+$(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
+$(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h
+   These headers automatically generate the registration structures for
+   GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions
+   from 4.5 to 6.0.
+   They should be preferred to creating the structures by hand.
+
+
+3. Usage
+
+
+You must install the gcc plugin headers for your gcc version,
+e.g., on Ubuntu for gcc-4.9:
+
+   apt-get install gcc-4.9-plugin-dev
+
+Enable a GCC plugin based feature in the kernel config:
+
+   CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y
+
+To compile only the plugin(s):
+
+   make gcc-plugins
+
+or just run the kernel make and compile the whole kernel with
+the cyclomatic complexity GCC plugin.
+
+
+4. How to add a new GCC plugin
+==
+
+The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a 
directory
+here. It must be added to $(src)/scripts/gcc-plugins/Makefile,
+$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig.
+See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin.
diff --git a/arch/Kconfig b/arch/Kconfig
index ddf29b4..e783429 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -366,6 +366,8 @@ menuconfig GCC_PLUGINS
  GCC plugins are loadable modules that provide extra features to the
  compiler. They are useful for runtime instrumentation and static 
analysis.
 
+ See Documentation/gcc-plugins.txt for details.
+
 config GCC_PLUGIN_CYC_COMPLEXITY
bool "Compute the cyclomatic complexity of a function"
depends on GCC_PLUGINS
-- 
2.4.1



[PATCH v7 6/6] Add sancov plugin

2016-04-22 Thread Emese Revfy
The sancov gcc plugin inserts a __sanitizer_cov_trace_pc() call
at the start of basic blocks.

This plugin is a helper plugin for the kcov feature. It supports
all gcc versions with plugin support (from gcc-4.5 on).
It is based on the gcc commit "Add fuzzing coverage support" by Dmitry Vyukov
(https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296).

Signed-off-by: Emese Revfy 
---
 Makefile|  10 +--
 arch/Kconfig|   9 +++
 arch/x86/purgatory/Makefile |   2 +
 lib/Kconfig.debug   |   2 +
 scripts/Makefile.gcc-plugins|  18 +
 scripts/gcc-plugins/Makefile|   5 ++
 scripts/gcc-plugins/sancov_plugin.c | 144 
 7 files changed, 181 insertions(+), 9 deletions(-)
 create mode 100644 scripts/gcc-plugins/sancov_plugin.c

diff --git a/Makefile b/Makefile
index 22f0e1b..f09f2bf 100644
--- a/Makefile
+++ b/Makefile
@@ -365,7 +365,7 @@ LDFLAGS_MODULE  =
 CFLAGS_KERNEL  =
 AFLAGS_KERNEL  =
 CFLAGS_GCOV= -fprofile-arcs -ftest-coverage
-CFLAGS_KCOV= -fsanitize-coverage=trace-pc
+CFLAGS_KCOV:= $(call cc-option,-fsanitize-coverage=trace-pc,)
 
 
 # Use USERINCLUDE when you must reference the UAPI directories only.
@@ -685,14 +685,6 @@ endif
 endif
 KBUILD_CFLAGS += $(stackp-flag)
 
-ifdef CONFIG_KCOV
-  ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
-$(warning Cannot use CONFIG_KCOV: \
- -fsanitize-coverage=trace-pc is not supported by compiler)
-CFLAGS_KCOV =
-  endif
-endif
-
 ifeq ($(cc-name),clang)
 KBUILD_CPPFLAGS += $(call cc-option,-Qunused-arguments,)
 KBUILD_CPPFLAGS += $(call cc-option,-Wno-unknown-warning-option,)
diff --git a/arch/Kconfig b/arch/Kconfig
index e783429..5d856c8 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -380,6 +380,15 @@ config GCC_PLUGIN_CYC_COMPLEXITY
  N = the number of nodes
  P = the number of connected components (exit nodes).
 
+config GCC_PLUGIN_SANCOV
+   bool
+   depends on GCC_PLUGINS
+   help
+ This plugin inserts a __sanitizer_cov_trace_pc() call at the start of
+ basic blocks. It supports all gcc versions with plugin support (from
+ gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
+ by Dmitry Vyukov .
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
index 12734a9..ac58c16 100644
--- a/arch/x86/purgatory/Makefile
+++ b/arch/x86/purgatory/Makefile
@@ -8,6 +8,8 @@ PURGATORY_OBJS = $(addprefix $(obj)/,$(purgatory-y))
 LDFLAGS_purgatory.ro := -e purgatory_start -r --no-undefined -nostdlib -z 
nodefaultlib
 targets += purgatory.ro
 
+KCOV_INSTRUMENT := n
+
 # Default KBUILD_CFLAGS can have -pg option set when FTRACE is enabled. That
 # in turn leaves some undefined symbols like __fentry__ in purgatory and not
 # sure how to relocate those. Like kexec-tools, use custom flags.
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 4fff4b0..616f7ed 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -708,6 +708,8 @@ config KCOV
bool "Code coverage for fuzzing"
depends on ARCH_HAS_KCOV
select DEBUG_FS
+   select GCC_PLUGINS
+   select GCC_PLUGIN_SANCOV
help
  KCOV exposes kernel code coverage information in a form suitable
  for coverage-guided fuzzing (randomized testing).
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 282d63a..33ab13e 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,8 +2,23 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  SANCOV_PLUGIN := -fplugin=$(objtree)/scripts/gcc-plugins/sancov_plugin.so
+
   gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
 
+  ifdef CONFIG_GCC_PLUGIN_SANCOV
+ifeq ($(CFLAGS_KCOV),)
+  # It is needed because of the gcc-plugin.sh and gcc version checks.
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)   += sancov_plugin.so
+
+  ifneq ($(PLUGINCC),)
+CFLAGS_KCOV := $(SANCOV_PLUGIN)
+  else
+$(error Cannot use CONFIG_KCOV: -fsanitize-coverage=trace-pc is not 
supported by compiler)
+  endif
+endif
+  endif
+
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
   ifeq ($(PLUGINCC),)
@@ -15,6 +30,9 @@ ifdef CONFIG_GCC_PLUGINS
 $(error error, your gcc version does not support plugins, you should 
upgrade it to gcc 4.5 at least)
   endif
 endif
+  else
+# SANCOV_PLUGIN can be only in CFLAGS_KCOV because avoid duplication.
+GCC_PLUGINS_CFLAGS := $(filter-out $(SANCOV_PLUGIN), $(GCC_PLUGINS_CFLAGS))
   endif

Re: [kernel-hardening] [PATCH v5 2/5] GCC plugin infrastructure

2016-03-09 Thread Emese Revfy
On Wed, 9 Mar 2016 02:01:15 -0700
David Brown  wrote:

> Feel free to fold these into your patch, or, if you prefer, I can send
> out separate patches for them.

Thanks, I'll take it.

-- 
Emese


Re: [kernel-hardening] [PATCH v5 2/5] GCC plugin infrastructure

2016-03-09 Thread Emese Revfy
On Wed, 9 Mar 2016 12:50:26 -0800
Kees Cook  wrote:

> > Feel free to fold these into your patch, or, if you prefer, I can send
> > out separate patches for them.
> 
> Ah-ha, great! Thanks for testing!
> 
> Emese, if you're not interested in carrying this, I can add it to my tree.

I think it is easier if it is in my patch set.

-- 
Emese


[PATCH v6 0/6] Introduce GCC plugin infrastructure

2016-04-07 Thread Emese Revfy
This patch set introduce the GCC plugin infrastructure with examples for testing
and documentation.

GCC plugins are loadable modules that provide extra features to the compiler.
They are useful for runtime instrumentation and static analysis.

The infrastructure supports all gcc versions from 4.5 to 6.0, building
out-of-tree modules and building in a separate directory. Cross-compilation
is supported too but currently only the x86, arm and arm64 architectures 
enables plugins.

This infrastructure was ported from grsecurity/PaX. It is a CII project
supported by the Linux Foundation.

Emese Revfy (6):
 Shared library support
 GCC plugin infrastructure
 The GCC plugin infrastructure supports the arm and arm64 architectures too
 Add Cyclomatic complexity plugin
 Documentations of the GCC plugin infrastructre
 Add sancov plugin


Changes from v5:
 * Set important properties on the external fndecl (Add sancov plugin)
 * Revert documentation change too (Shared library support)
(Suggested-by: Kees Cook )
 * The GCC plugin infrastructure now supports the arm and arm64 architectures 
too
(Signed-off-by: David Brown )
 * Simplify the computation of PLUGINCC (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify the invocation of gcc-plugin.sh (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Make use of multi-depend (Shared library support)
(Suggested-by: Masahiro Yamada )
 * Remove unnecessary exports (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Simplify Makefile by using addprefix (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Moved the gcc plugins from tools/ to scripts/ (GCC plugin infrastructure)
(Suggested-by: Masahiro Yamada )
 * Removed plugins from KBUILD_CFLAGS_32 (GCC plugin infrastructure)
 * Remove gcc-plugin target everywhere
(Suggested-by and partly Written-by: Masahiro Yamada 
)
 * There is no leaf gcc attribute in gcc-4.5 (Add sancov plugin)
 * Added support to the sancov plugin with kcov (Add sancov plugin)

Changes from v4:
 * Moved shared library support from the GCC plugin infrastructure patch into
   a different patch
 * Update gcc-*.h from PaX
   * Fixed gcc-common.h for gcc 6
   * Added pass cloning support to the gcc pass generators
 * Disable all plugins in vdso because it is userland code
 * Add sancov gcc plugin: another use case for gcc plugin support in the kernel
   is when there is a feature in the latest gcc version and we would like to use
   it with older gcc versions as well (e.g., distros).

Changes from v3:
 * Fix some indentation related warnings
   (Suggested by checkpatch.pl)
 * Add maintainer entries
 * Don't run gcc_plugin.sh when the GCC_PLUGINS option is disabled or 
unsupported
   (Reported-by: Fengguang Wu )

Changes from v2:
 * Fixed incorrectly encoded characters
 * Generate the GIMPLE, IPA, SIMPLE_IPA and RTL pass structures
   (Suggested-by: Rasmus Villemoes )
 * Write plugin related warning messages to stderr instead of stdout
   (Suggested-by: Kees Cook )
 * Mention the installation of the gcc plugin headers (Documentation)

Changes from v1:
 * Move the gcc-plugins make target into a separate Makefile because there may
   be a lot of plugins (Suggested-by: Rasmus Villemoes)
 * Simplify the dependencies of the plugin related config option
   (Suggested-by: Kees Cook )
 * Removed the unnecessary example plugin

---
 Documentation/dontdiff |   1 +
 Documentation/gcc-plugins.txt  |  83 +++
 Documentation/kbuild/makefiles.txt |  39 +-
 MAINTAINERS|   8 +
 Makefile   |  42 +-
 arch/Kconfig   |  36 +
 arch/arm/Kconfig   |   1 +
 arch/arm64/Kconfig |   1 +
 arch/x86/Kconfig   |   1 +
 arch/x86/entry/vdso/Makefile   |   3 +-
 init/Makefile  |   3 +
 lib/Kconfig.debug  |   2 +
 scripts/Makefile   |   2 +-
 scripts/Makefile.build |   2 +-
 scripts/Makefile.clean |   3 +-
 scripts/Makefile.gcc-plugins   |  29 +
 scripts/Makefile.host  |  70 +-
 scripts/gcc-plugin.sh  |  51 ++
 scripts/gcc-plugins/Makefile   |  21 +
 scripts/gcc-plugins/cyc_complexity_plugin.c|  73 ++
 scripts/gcc-plugins/gcc-common.h   | 830 +
 scripts/gcc-plugins/gcc-generate-gimple-pass.h | 175 +
 scripts/gcc-plugins/gcc-generate-ipa-pass.h| 289 +++
 scripts/gcc-plugins/gcc-generate-rtl-pass.h| 175 +
 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 175 +
 scripts/gcc-pl

[PATCH v6 1/6] Shared library support

2016-04-07 Thread Emese Revfy
Infrastructure for building independent shared library targets.
This effectively also reverts commit 62e2210798ed38928ab24841e8b4878a
(Masahiro Yamada, kbuild: drop shared library support from Makefile.host).

Signed-off-by: Emese Revfy 
---
 Documentation/kbuild/makefiles.txt | 39 -
 scripts/Makefile.build |  2 +-
 scripts/Makefile.clean |  3 +-
 scripts/Makefile.host  | 70 +-
 4 files changed, 103 insertions(+), 11 deletions(-)

diff --git a/Documentation/kbuild/makefiles.txt 
b/Documentation/kbuild/makefiles.txt
index 13f888a..250729b 100644
--- a/Documentation/kbuild/makefiles.txt
+++ b/Documentation/kbuild/makefiles.txt
@@ -23,10 +23,11 @@ This document describes the Linux kernel Makefiles.
=== 4 Host Program support
   --- 4.1 Simple Host Program
   --- 4.2 Composite Host Programs
-  --- 4.3 Using C++ for host programs
-  --- 4.4 Controlling compiler options for host programs
-  --- 4.5 When host programs are actually built
-  --- 4.6 Using hostprogs-$(CONFIG_FOO)
+  --- 4.3 Defining shared libraries
+  --- 4.4 Using C++ for host programs
+  --- 4.5 Controlling compiler options for host programs
+  --- 4.6 When host programs are actually built
+  --- 4.7 Using hostprogs-$(CONFIG_FOO)
 
=== 5 Kbuild clean infrastructure
 
@@ -643,7 +644,29 @@ Both possibilities are described in the following.
Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax -y is not permitted for host-programs.
 
 4.3 Using C++ for host programs
+--- 4.3 Defining shared libraries
+
+   Objects with extension .so are considered shared libraries, and
+   will be compiled as position independent objects.
+   Kbuild provides support for shared libraries, but the usage
+   shall be restricted.
+   In the following example the libkconfig.so shared library is used
+   to link the executable conf.
+
+   Example:
+   #scripts/kconfig/Makefile
+   hostprogs-y := conf
+   conf-objs   := conf.o libkconfig.so
+   libkconfig-objs := expr.o type.o
+
+   Shared libraries always require a corresponding -objs line, and
+   in the example above the shared library libkconfig is composed by
+   the two objects expr.o and type.o.
+   expr.o and type.o will be built as position independent code and
+   linked as a shared library libkconfig.so. C++ is not supported for
+   shared libraries.
+
+--- 4.4 Using C++ for host programs
 
kbuild offers support for host programs written in C++. This was
introduced solely to support kconfig, and is not recommended
@@ -666,7 +689,7 @@ Both possibilities are described in the following.
qconf-cxxobjs := qconf.o
qconf-objs:= check.o
 
 4.4 Controlling compiler options for host programs
+--- 4.5 Controlling compiler options for host programs
 
When compiling host programs, it is possible to set specific flags.
The programs will always be compiled utilising $(HOSTCC) passed
@@ -694,7 +717,7 @@ Both possibilities are described in the following.
When linking qconf, it will be passed the extra option
"-L$(QTDIR)/lib".
 
 4.5 When host programs are actually built
+--- 4.6 When host programs are actually built
 
Kbuild will only build host-programs when they are referenced
as a prerequisite.
@@ -725,7 +748,7 @@ Both possibilities are described in the following.
This will tell kbuild to build lxdialog even if not referenced in
any rule.
 
 4.6 Using hostprogs-$(CONFIG_FOO)
+--- 4.7 Using hostprogs-$(CONFIG_FOO)
 
A typical pattern in a Kbuild file looks like this:
 
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index e1bc190..b2ce235 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -60,7 +60,7 @@ endif
 endif
 
 # Do not include host rules unless needed
-ifneq ($(hostprogs-y)$(hostprogs-m),)
+ifneq 
($(hostprogs-y)$(hostprogs-m)$(hostlibs-y)$(hostlibs-m)$(hostcxxlibs-y)$(hostcxxlibs-m),)
 include scripts/Makefile.host
 endif
 
diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
index 55c96cb..e4e88ab 100644
--- a/scripts/Makefile.clean
+++ b/scripts/Makefile.clean
@@ -38,7 +38,8 @@ subdir-ymn:= $(addprefix $(obj)/,$(subdir-ymn))
 __clean-files  := $(extra-y) $(extra-m) $(extra-)   \
   $(always) $(targets) $(clean-files)   \
   $(host-progs) \
-  $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
+  $(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
+  $(hostlibs-y) $(hostlibs-m) $(hostlibs-)
 
 __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
diff --git a/scripts/Makef

[PATCH v6 2/6] GCC plugin infrastructure

2016-04-07 Thread Emese Revfy
This patch allows to build the whole kernel with GCC plugins. It was ported from
grsecurity/PaX. The infrastructure supports building out-of-tree modules and
building in a separate directory. Cross-compilation is supported too but
currently only the x86 architecture enables plugins.

The directory of the gcc plugins is tools/gcc. You can use a file or a directory
there. The plugins compile with these options:
 * -fno-rtti: gcc is compiled with this option so the plugins must use it too
 * -fno-exceptions: this is inherited from gcc too
 * -fasynchronous-unwind-tables: this is inherited from gcc too
 * -ggdb: it is useful for debugging a plugin (better backtrace on internal
errors)
 * -Wno-narrowing: to suppress warnings from gcc headers (ipa-utils.h)
 * -Wno-unused-variable: to suppress warnings from gcc headers (gcc_version
variable, plugin-version.h)

The infrastructure introduces a new Makefile target called gcc-plugins. It
supports all gcc versions from 4.5 to 6.0. The scripts/gcc-plugin.sh script
chooses the proper host compiler (gcc-4.7 can be built by either gcc or g++).
This script also checks the availability of the included headers in
tools/gcc/gcc-common.h.

The gcc-common.h header contains frequently included headers for GCC plugins
and it has a compatibility layer for the supported gcc versions.

The gcc-generate-*-pass.h headers automatically generate the registration
structures for GIMPLE, SIMPLE_IPA, IPA and RTL passes.

Note that 'make clean' keeps the *.so files (only the distclean or mrproper
targets clean all) because they are needed for out-of-tree modules.

Signed-off-by: Emese Revfy 
---
 Documentation/dontdiff |   1 +
 MAINTAINERS|   8 +
 Makefile   |  34 +-
 arch/Kconfig   |  13 +
 arch/x86/Kconfig   |   1 +
 arch/x86/entry/vdso/Makefile   |   3 +-
 init/Makefile  |   3 +
 scripts/Makefile   |   2 +-
 scripts/Makefile.gcc-plugins   |  18 +
 scripts/gcc-plugin.sh  |  51 ++
 scripts/gcc-plugins/Makefile   |  15 +
 scripts/gcc-plugins/gcc-common.h   | 830 +
 scripts/gcc-plugins/gcc-generate-gimple-pass.h | 175 +
 scripts/gcc-plugins/gcc-generate-ipa-pass.h| 289 +++
 scripts/gcc-plugins/gcc-generate-rtl-pass.h| 175 +
 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h | 175 +
 scripts/link-vmlinux.sh|   2 +-
 scripts/package/builddeb   |   1 +
 18 files changed, 1790 insertions(+), 6 deletions(-)
 create mode 100644 scripts/Makefile.gcc-plugins
 create mode 100644 scripts/gcc-plugin.sh
 create mode 100644 scripts/gcc-plugins/Makefile
 create mode 100644 scripts/gcc-plugins/gcc-common.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-gimple-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-ipa-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-rtl-pass.h
 create mode 100644 scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h

diff --git a/Documentation/dontdiff b/Documentation/dontdiff
index 8ea834f..5385cba 100644
--- a/Documentation/dontdiff
+++ b/Documentation/dontdiff
@@ -3,6 +3,7 @@
 *.bc
 *.bin
 *.bz2
+*.c.[012]*.*
 *.cis
 *.cpio
 *.csp
diff --git a/MAINTAINERS b/MAINTAINERS
index 0919fed..4463502 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4763,6 +4763,14 @@ L:   linux-s...@vger.kernel.org
 S: Odd Fixes (e.g., new signatures)
 F: drivers/scsi/fdomain.*
 
+GCC PLUGINS
+M: Kees Cook 
+R: Emese Revfy 
+L: kernel-harden...@lists.openwall.com
+S: Maintained
+F: scripts/gcc-plugins/
+F: Documentation/gcc-plugins.txt
+
 GCOV BASED KERNEL PROFILING
 M: Peter Oberparleiter 
 S: Maintained
diff --git a/Makefile b/Makefile
index 173437d..3af7b9e 100644
--- a/Makefile
+++ b/Makefile
@@ -418,6 +418,8 @@ export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE 
KBUILD_LDFLAGS_MODULE
 export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
 export KBUILD_ARFLAGS
 
+export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGINS_AFLAGS
+
 # When compiling out-of-tree modules, put MODVERDIR in the module
 # tree rather than in the kernel tree. The kernel tree might
 # even be read-only.
@@ -548,7 +550,7 @@ ifeq ($(KBUILD_EXTMOD),)
 # in parallel
 PHONY += scripts
 scripts: scripts_basic include/config/auto.conf include/config/tristate.conf \
-asm-generic
+asm-generic gcc-plugins
$(Q)$(MAKE) $(build)=$(@)
 
 # Objects we will link into vmlinux / subdirs we need to visit
@@ -623,6 +625,15 @@ endif
 # Tell gcc to never replace conditional load with a non-conditional one
 KBUILD_CFLAGS  += $(call cc-option,--param=allow-store-data-races=0)
 
+PHONY += gcc-plugins
+g

[PATCH v6 3/6] The GCC plugin infrastructure supports the arm and arm64 architectures too

2016-04-07 Thread Emese Revfy
The GCC plugin infrastructure now supports the arm and arm64 architectures too.

Signed-off-by: David Brown 
---
 arch/arm/Kconfig   | 1 +
 arch/arm64/Kconfig | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0846026..8f57eb6 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -55,6 +55,7 @@ config ARM
select HAVE_FUNCTION_GRAPH_TRACER if (!THUMB2_KERNEL)
select HAVE_FUNCTION_TRACER if (!XIP_KERNEL)
select HAVE_GENERIC_DMA_COHERENT
+   select HAVE_GCC_PLUGINS
select HAVE_HW_BREAKPOINT if (PERF_EVENTS && (CPU_V6 || CPU_V6K || 
CPU_V7))
select HAVE_IDE if PCI || ISA || PCMCIA
select HAVE_IRQ_TIME_ACCOUNTING
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4f43622..22c9473 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -72,6 +72,7 @@ config ARM64
select HAVE_FTRACE_MCOUNT_RECORD
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_GRAPH_TRACER
+   select HAVE_GCC_PLUGINS
select HAVE_GENERIC_DMA_COHERENT
select HAVE_HW_BREAKPOINT if PERF_EVENTS
select HAVE_IRQ_TIME_ACCOUNTING
-- 
2.4.1



[PATCH v6 4/6] Add Cyclomatic complexity GCC plugin

2016-04-07 Thread Emese Revfy
Add a very simple plugin to demonstrate the GCC plugin infrastructure. This GCC
plugin computes the cyclomatic complexity of each function.

The complexity M of a function's control flow graph is defined as:
 M = E - N + 2P
where
 E = the number of edges
 N = the number of nodes
 P = the number of connected components (exit nodes).

Signed-off-by: Emese Revfy 
---
 arch/Kconfig| 12 +
 scripts/Makefile.gcc-plugins|  2 +
 scripts/gcc-plugins/Makefile|  4 ++
 scripts/gcc-plugins/cyc_complexity_plugin.c | 73 +
 4 files changed, 91 insertions(+)
 create mode 100644 scripts/gcc-plugins/cyc_complexity_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 7c12571..ddf29b4 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -366,6 +366,18 @@ menuconfig GCC_PLUGINS
  GCC plugins are loadable modules that provide extra features to the
  compiler. They are useful for runtime instrumentation and static 
analysis.
 
+config GCC_PLUGIN_CYC_COMPLEXITY
+   bool "Compute the cyclomatic complexity of a function"
+   depends on GCC_PLUGINS
+   help
+ The complexity M of a function's control flow graph is defined as:
+  M = E - N + 2P
+ where
+
+ E = the number of edges
+ N = the number of nodes
+ P = the number of connected components (exit nodes).
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index b981b65..34ad58b 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -2,6 +2,8 @@ ifdef CONFIG_GCC_PLUGINS
   __PLUGINCC := $(call cc-ifversion, -ge, 0408, $(HOSTCXX), $(HOSTCC))
   PLUGINCC := $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-plugin.sh 
"$(__PLUGINCC)" "$(HOSTCXX)" "$(CC)")
 
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
+
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
   ifeq ($(PLUGINCC),)
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index b2d64af..31c72bf 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -12,4 +12,8 @@ endif
 
 export GCCPLUGINS_DIR HOSTLIBS
 
+$(HOSTLIBS)-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) := cyc_complexity_plugin.so
+
 always := $($(HOSTLIBS)-y)
+
+cyc_complexity_plugin-objs := cyc_complexity_plugin.o
diff --git a/scripts/gcc-plugins/cyc_complexity_plugin.c 
b/scripts/gcc-plugins/cyc_complexity_plugin.c
new file mode 100644
index 000..34df974
--- /dev/null
+++ b/scripts/gcc-plugins/cyc_complexity_plugin.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy 
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/cyclomatic_complexity
+ *
+ * http://en.wikipedia.org/wiki/Cyclomatic_complexity
+ * The complexity M is then defined as:
+ * M = E - N + 2P
+ * where
+ *
+ *  E = the number of edges of the graph
+ *  N = the number of nodes of the graph
+ *  P = the number of connected components (exit nodes).
+ *
+ * Usage (4.5 - 5):
+ * $ make clean; make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+static struct plugin_info cyc_complexity_plugin_info = {
+   .version= "20160225",
+   .help   = "Cyclomatic Complexity\n",
+};
+
+static unsigned int cyc_complexity_execute(void)
+{
+   int complexity;
+   expanded_location xloc;
+
+   /* M = E - N + 2P */
+   complexity = n_edges_for_fn(cfun) - n_basic_blocks_for_fn(cfun) + 2;
+
+   xloc = expand_location(DECL_SOURCE_LOCATION(current_function_decl));
+   fprintf(stderr, "Cyclomatic Complexity %d %s:%s\n", complexity,
+   xloc.file, DECL_NAME_POINTER(current_function_decl));
+
+   return 0;
+}
+
+#define PASS_NAME cyc_complexity
+
+#define NO_GATE
+#define TODO_FLAGS_FINISH TODO_dump_func
+
+#include "gcc-generate-gimple-pass.h"
+
+int plugin_init(struct plugin_name_args *plugin_info, struct 
plugin_gcc_version *version)
+{
+   const char * const plugin_name = plugin_info->base_name;
+   struct register_pass_info cyc_complexity_pass_info;
+
+   cyc_complexity_pass_info.pass   = 
make_cyc_complexity_pass();
+   cyc_complexity_pass_info.reference_pass_name= "ssa";
+   cyc_complexity_pass_info.ref_pass_instance_number   = 1;
+   cyc_complexity_pass_info.pos_op = 
PASS_POS_INSERT_AFTER;
+
+   if (!plugin_default_version_check(version, &gcc_version)) {
+   error(G_("incompatible gcc/plugin versions"));
+   return 1;
+   }
+
+   register_callback(plugin_name, PLUGIN_INFO, NULL,
+

[PATCH v6 5/6] Documentation for the GCC plugin infrastructure

2016-04-07 Thread Emese Revfy
This is the GCC infrastructure documentation about its operation, how to add
and use a new plugin with an example.

Signed-off-by: Emese Revfy 
---
 Documentation/gcc-plugins.txt | 83 +++
 arch/Kconfig  |  2 ++
 2 files changed, 85 insertions(+)
 create mode 100644 Documentation/gcc-plugins.txt

diff --git a/Documentation/gcc-plugins.txt b/Documentation/gcc-plugins.txt
new file mode 100644
index 000..9fa9bd2
--- /dev/null
+++ b/Documentation/gcc-plugins.txt
@@ -0,0 +1,83 @@
+GCC plugin infrastructure
+=
+
+
+1. Introduction
+===
+
+GCC plugins are loadable modules that provide extra features to the
+compiler [1]. They are useful for runtime instrumentation and static analysis.
+We can analyse, change and add further code during compilation via
+callbacks [2], GIMPLE [3], IPA [4] and RTL passes [5].
+
+The GCC plugin infrastructure of the kernel supports all gcc versions from
+4.5 to 6.0, building out-of-tree modules, cross-compilation and building in a
+separate directory.
+
+Currently the GCC plugin infrastructure supports only the x86, arm and arm64
+architectures.
+
+This infrastructure was ported from grsecurity [6] and PaX [7].
+
+--
+[1] https://gcc.gnu.org/onlinedocs/gccint/Plugins.html
+[2] https://gcc.gnu.org/onlinedocs/gccint/Plugin-API.html#Plugin-API
+[3] https://gcc.gnu.org/onlinedocs/gccint/GIMPLE.html
+[4] https://gcc.gnu.org/onlinedocs/gccint/IPA.html
+[5] https://gcc.gnu.org/onlinedocs/gccint/RTL.html
+[6] https://grsecurity.net/
+[7] https://pax.grsecurity.net/
+
+
+2. Files
+
+
+$(src)/scripts/gcc-plugins
+   This is the directory of the GCC plugins.
+
+$(src)/scripts/gcc-plugins/gcc-common.h
+   This is a compatibility header for GCC plugins.
+   It should be always included instead of individual gcc headers.
+
+$(src)/scripts/gcc-plugin.sh
+   This script checks the availability of the included headers in
+   gcc-common.h and chooses the proper host compiler to build the plugins
+   (gcc-4.7 can be built by either gcc or g++).
+
+$(src)/scripts/gcc-plugins/gcc-generate-gimple-pass.h
+$(src)/scripts/gcc-plugins/gcc-generate-ipa-pass.h
+$(src)/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h
+$(src)/scripts/gcc-plugins/gcc-generate-rtl-pass.h
+   These headers automatically generate the registration structures for
+   GIMPLE, SIMPLE_IPA, IPA and RTL passes. They support all gcc versions
+   from 4.5 to 6.0.
+   They should be preferred to creating the structures by hand.
+
+
+3. Usage
+
+
+You must install the gcc plugin headers for your gcc version,
+e.g., on Ubuntu for gcc-4.9:
+
+   apt-get install gcc-4.9-plugin-dev
+
+Enable a GCC plugin based feature in the kernel config:
+
+   CONFIG_GCC_PLUGIN_CYC_COMPLEXITY = y
+
+To compile only the plugin(s):
+
+   make gcc-plugins
+
+or just run the kernel make and compile the whole kernel with
+the cyclomatic complexity GCC plugin.
+
+
+4. How to add a new GCC plugin
+==
+
+The GCC plugins are in $(src)/scripts/gcc-plugins/. You can use a file or a 
directory
+here. It must be added to $(src)/scripts/gcc-plugins/Makefile,
+$(src)/scripts/Makefile.gcc-plugins and $(src)/arch/Kconfig.
+See the cyc_complexity_plugin.c (CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) GCC plugin.
diff --git a/arch/Kconfig b/arch/Kconfig
index ddf29b4..e783429 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -366,6 +366,8 @@ menuconfig GCC_PLUGINS
  GCC plugins are loadable modules that provide extra features to the
  compiler. They are useful for runtime instrumentation and static 
analysis.
 
+ See Documentation/gcc-plugins.txt for details.
+
 config GCC_PLUGIN_CYC_COMPLEXITY
bool "Compute the cyclomatic complexity of a function"
depends on GCC_PLUGINS
-- 
2.4.1



[PATCH v6 6/6] Add sancov plugin

2016-04-07 Thread Emese Revfy
The sancov gcc plugin inserts a __sanitizer_cov_trace_pc() call
at the start of basic blocks.

This plugin is a helper plugin for the kcov feature. It supports
all gcc versions with plugin support (from gcc-4.5 on).
It is based on the gcc commit "Add fuzzing coverage support" by Dmitry Vyukov
(https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296).

Signed-off-by: Emese Revfy 
---
 Makefile|   8 +-
 arch/Kconfig|   9 +++
 lib/Kconfig.debug   |   2 +
 scripts/Makefile.gcc-plugins|   9 +++
 scripts/gcc-plugins/Makefile|   2 +
 scripts/gcc-plugins/sancov_plugin.c | 143 
 6 files changed, 170 insertions(+), 3 deletions(-)
 create mode 100644 scripts/gcc-plugins/sancov_plugin.c

diff --git a/Makefile b/Makefile
index 3af7b9e..e079cb4 100644
--- a/Makefile
+++ b/Makefile
@@ -686,10 +686,12 @@ endif
 KBUILD_CFLAGS += $(stackp-flag)
 
 ifdef CONFIG_KCOV
-  ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
-$(warning Cannot use CONFIG_KCOV: \
+  ifneq ($(CFLAGS_KCOV),)
+ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
+  $(warning Cannot use CONFIG_KCOV: \
  -fsanitize-coverage=trace-pc is not supported by compiler)
-CFLAGS_KCOV =
+  CFLAGS_KCOV =
+endif
   endif
 endif
 
diff --git a/arch/Kconfig b/arch/Kconfig
index e783429..5d856c8 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -380,6 +380,15 @@ config GCC_PLUGIN_CYC_COMPLEXITY
  N = the number of nodes
  P = the number of connected components (exit nodes).
 
+config GCC_PLUGIN_SANCOV
+   bool
+   depends on GCC_PLUGINS
+   help
+ This plugin inserts a __sanitizer_cov_trace_pc() call at the start of
+ basic blocks. It supports all gcc versions with plugin support (from
+ gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
+ by Dmitry Vyukov .
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index f4b797a..507d3fc 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -707,6 +707,8 @@ config KCOV
bool "Code coverage for fuzzing"
depends on ARCH_HAS_KCOV
select DEBUG_FS
+   select GCC_PLUGINS
+   select GCC_PLUGIN_SANCOV
help
  KCOV exposes kernel code coverage information in a form suitable
  for coverage-guided fuzzing (randomized testing).
diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 34ad58b..25a70fb 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -4,6 +4,15 @@ ifdef CONFIG_GCC_PLUGINS
 
   gcc-plugin-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY)   += 
cyc_complexity_plugin.so
 
+  ifdef CONFIG_GCC_PLUGIN_SANCOV
+ifeq ($(call cc-option, $(CFLAGS_KCOV)),)
+  gcc-plugin-$(CONFIG_GCC_PLUGIN_SANCOV)   += sancov_plugin.so
+  ifneq ($(PLUGINCC),)
+CFLAGS_KCOV =
+  endif
+endif
+  endif
+
   GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
 
   ifeq ($(PLUGINCC),)
diff --git a/scripts/gcc-plugins/Makefile b/scripts/gcc-plugins/Makefile
index 31c72bf..97a923f 100644
--- a/scripts/gcc-plugins/Makefile
+++ b/scripts/gcc-plugins/Makefile
@@ -13,7 +13,9 @@ endif
 export GCCPLUGINS_DIR HOSTLIBS
 
 $(HOSTLIBS)-$(CONFIG_GCC_PLUGIN_CYC_COMPLEXITY) := cyc_complexity_plugin.so
+$(HOSTLIBS)-$(CONFIG_GCC_PLUGIN_SANCOV) += sancov_plugin.so
 
 always := $($(HOSTLIBS)-y)
 
 cyc_complexity_plugin-objs := cyc_complexity_plugin.o
+sancov_plugin-objs := sancov_plugin.o
diff --git a/scripts/gcc-plugins/sancov_plugin.c 
b/scripts/gcc-plugins/sancov_plugin.c
new file mode 100644
index 000..1311744
--- /dev/null
+++ b/scripts/gcc-plugins/sancov_plugin.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2011-2016 by Emese Revfy 
+ * Licensed under the GPL v2, or (at your option) v3
+ *
+ * Homepage:
+ * https://github.com/ephox-gcc-plugins/sancov
+ *
+ * This plugin inserts a __sanitizer_cov_trace_pc() call at the start of basic 
blocks.
+ * It supports all gcc versions with plugin support (from gcc-4.5 on).
+ * It is based on the commit "Add fuzzing coverage support" by Dmitry Vyukov 
.
+ *
+ * You can read about it more here:
+ *  
https://gcc.gnu.org/viewcvs/gcc?limit_changes=0&view=revision&revision=231296
+ *  http://lwn.net/Articles/674854/
+ *  https://github.com/google/syzkaller
+ *  https://lwn.net/Articles/677764/
+ *
+ * Usage:
+ * make run
+ */
+
+#include "gcc-common.h"
+
+int plugin_is_GPL_compatible;
+
+tree sancov_fndecl;
+
+static struct plugin_info sancov_plugin_info = {
+   .version= "20160402",
+   .help   = "sancov plugin\n",
+};
+
+static unsigned int sancov_execute(void)
+{
+   basic_block bb;
+
+   /* Remove this line when this plugin and kcov will be in the kerne

Re: [PATCH v6 0/6] Introduce GCC plugin infrastructure

2016-04-12 Thread Emese Revfy
On Tue, 12 Apr 2016 11:27:52 -0700
Kees Cook  wrote:

> Emese, were you thinking of doing the initify plugin next after this
> infrastructure lands?

I already started to work on the entropy plugin but after that I can work on 
initify.

-- 
Emese


Re: [lkp] [Add sancov plugin] 47faf3078f: BUG: kernel boot crashed

2016-04-12 Thread Emese Revfy
On Mon, 11 Apr 2016 09:40:19 +0800
kernel test robot  wrote:

> FYI, we noticed the below changes on
> 
> https://github.com/0day-ci/linux 
> Emese-Revfy/Introduce-GCC-plugin-infrastructure/20160408-052328
> commit 47faf3078f741dd7d854131a547615fa8e447dd5 ("Add sancov plugin")
> 
> 
> [0.00] percpu: Embedded 31 pages/cpu @880013e0 s88640 r8192 
> d30144 u1048576
> [0.00] pcpu-alloc: s88640 r8192 d30144 u1048576 alloc=1*2097152
> [0.00] pcpu-alloc: [0] 0 1 
> 
> Elapsed time: 10
> BUG: kernel boot crashed

Thanks for the report, I will fix it soon.

-- 
Emese


Re: [kernel-hardening] Re: [PATCH] video: constify geode ops structures

2015-11-09 Thread Emese Revfy
On Mon, 9 Nov 2015 14:50:47 + (GMT)
Julia Lawall  wrote:
> > Actually, it looks like Emese Revfy is going to merge the GCC plugin
> > constify stuff sooner rather than later so maybe adding all these consts
> > isn't going to be needed.
> 
> Is there any advantage of const over the plugin?  The consts are easy to
> add.

Hi,

I think it's a very good advantage that the plugin constifies automatically
without regular maintenance (e.g., generate patches with coccinelle, 
send patches to the maintainers every new kernel version). ;)
But if it doesn't convince you, I did constification by hand (with a coccinelle
script) some years ago.
There are too many types that can be const and it took too long to prepare and
get the maintainers to accept the patches.
And it never ends as there are always new types that can be const.

> Does the plugin help for structures that have non-function fields?
Yes, it does. See __do_const here:
http://www.openwall.com/lists/kernel-hardening/2015/11/06/11
or more about the constify plugin:
https://pax.grsecurity.net/docs/PaXTeam-H2HC13-PaX-gcc-plugins.pdf

-- 
Emese
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/3] powerpc: enable support for GCC plugins

2016-12-06 Thread Emese Revfy
On Tue,  6 Dec 2016 17:28:00 +1100
Andrew Donnellan  wrote:

> +  # Various gccs between 4.5 and 5.1 have bugs on powerpc due to missing
> +  # header files. gcc <= 4.6 doesn't work at all, gccs from 4.8 to 5.1 
> have
> +  # issues with 64-bit targets.
> +  ifeq ($(ARCH),powerpc)
> +ifeq ($(call cc-ifversion, -le, 0501, y), y)
> +   @echo "Cannot use CONFIG_GCC_PLUGINS: plugin support on gcc <= 5.1 is 
> buggy on powerpc, please upgrade to gcc 5.2 or newer" >&2 && exit 1
> +endif
> +  endif

Hi,

What are these missing headers? Because if they aren't necessary then they can
be removed from gcc-common.h. There were missing headers on arm/arm64 and these
archs are supported. I think this version check is unnecessary because
gcc-plugin.sh also checks the missing headers.

What is the problem on gcc-4.5/gcc-4.6?

-- 
Emese


Re: [PATCH v4 0/4] Introduce the initify gcc plugin

2017-01-17 Thread Emese Revfy
On Thu, 12 Jan 2017 15:40:41 -0800
Kees Cook  wrote:

> WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in
> reference from the function clk_gate() to the variable
> .init.rodata.str:__func__.29708
> The function clk_gate() references
> the variable __initconst __func__.29708.
> This is often because clk_gate lacks a __initconst
> annotation or the annotation of __func__.29708 is wrong.
>
> I used my initify v5 development tree, with the following patch, with
> "make allyesconfig":
> 
> http://git.kernel.org/cgit/linux/kernel/git/kees/linux.git/log/?h=for-next/gcc-plugin/initify

Hi,

I can't reproduce this mismatch with allyesconfig. Could you please send me 
your .config?

-- 
Emese


Re: linux-next: build warnings after merge of the kbuild tree

2016-06-09 Thread Emese Revfy
On Thu, 9 Jun 2016 12:57:16 +0200
Michal Marek  wrote:

> Dne 9.6.2016 v 06:05 Stephen Rothwell napsal(a):
> > On Wed, 8 Jun 2016 19:56:38 -0700 Kees Cook  wrote:
> >> Ah, yes, that should default to off. We'll get a fix landed ASAP.
> > 
> > Note that this was an allmodconfig build.  The default is 'n', but
> > allmodconfig will turn it on (as will allyesconfig).
> 
> I guess we should make GCC_PLUGINS depend on !COMPILE_TEST. Actually I
> thought this was already the case, but it is not.

Is it really necessary to disable all gcc plugins or would it be enough
to disable only the cyc_complexity plugin?

-- 
Emese


Re: linux-next: build warnings after merge of the kbuild tree

2016-06-09 Thread Emese Revfy
On Thu, 9 Jun 2016 12:22:58 +1000
Stephen Rothwell  wrote:

> Hi Michal,
> 
> After merging the kbuild tree, today's linux-next build (x86_64
> allmodconfig) produced these warnings:
> 
> Cyclomatic Complexity 1 scripts/mod/devicetable-offsets.c:main
> Cyclomatic Complexity 1 kernel/bounds.c:foo
> Cyclomatic Complexity 1 arch/x86/kernel/asm-offsets_64.c:main
> Cyclomatic Complexity 1 arch/x86/kernel/asm-offsets.c:common
> Cyclomatic Complexity 5 arch/x86/ia32/audit.c:ia32_classify_syscall
> 
> and so on (many, many of these - about 635,000 :-()
> 
> Introduced (presumably) by commits
> 
>   6b90bd4ba40b ("GCC plugin infrastructure")
>   0dae776c6bf3 ("Add Cyclomatic complexity GCC plugin")
> 
> I have disabled CONFIG_GCC_PLUGIN_CYC_COMPLEXITY (by making it depend
> on CONFIG_BROKEN) until it is not enabled by default.

These aren't warnings. This plugin is a static analyzer. It prints out
the cyclomatic complexity of all functions in the kernel.

I think it would be useful to enable it sometimes and report new functions
with a high enough complexity value. 

-- 
Emese


Re: [PATCH v2 0/3] Introduce the latent_entropy gcc plugin

2016-06-09 Thread Emese Revfy
On Thu, 9 Jun 2016 14:18:08 -0700
Kees Cook  wrote:

> By the way, as you work on v3, can you also be sure to put your
> patches through scripts/checkpatch.pl? There are a lot of >80
> character lines, and other nits. I'd like to minimize the warnings.

I only split those lines where the split doesn't make the code worse.
I checked it again and I made some changes:
https://github.com/ephox-gcc-plugins/latent_entropy/commit/e8e7c885b49db16903ea5bd4d6318ce1246f85f3

-- 
Emese


[PATCH v2 3/3] Constify some function parameters

2016-07-06 Thread Emese Revfy
Initify needs const pointer types, the initify plugin caught some __printf
arguments that weren't const yet.

Signed-off-by: Emese Revfy 
---
 drivers/isdn/hisax/config.c | 16 
 drivers/isdn/hisax/hisax.h  |  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index bf04d2a..2d12c6c 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -659,7 +659,7 @@ int jiftime(char *s, long mark)
 
 static u_char tmpbuf[HISAX_STATUS_BUFSIZE];
 
-void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
+void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt,
  va_list args)
 {
/* if head == NULL the fmt contains the full info */
@@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char 
*head, char *fmt,
u_char  *p;
isdn_ctrl   ic;
int len;
+   const u_char*data;
 
if (!cs) {
printk(KERN_WARNING "HiSax: No CardStatus for message");
return;
}
spin_lock_irqsave(&cs->statlock, flags);
-   p = tmpbuf;
if (head) {
+   p = tmpbuf;
p += jiftime(p, jiffies);
p += sprintf(p, " %s", head);
p += vsprintf(p, fmt, args);
*p++ = '\n';
*p = 0;
len = p - tmpbuf;
-   p = tmpbuf;
+   data = tmpbuf;
} else {
-   p = fmt;
+   data = fmt;
len = strlen(fmt);
}
if (len > HISAX_STATUS_BUFSIZE) {
@@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char 
*head, char *fmt,
if (i >= len)
i = len;
len -= i;
-   memcpy(cs->status_write, p, i);
+   memcpy(cs->status_write, data, i);
cs->status_write += i;
if (cs->status_write > cs->status_end)
cs->status_write = cs->status_buf;
-   p += i;
if (len) {
-   memcpy(cs->status_write, p, len);
+   memcpy(cs->status_write, data + i, len);
cs->status_write += len;
}
 #ifdef KERNELSTACK_DEBUG
@@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, 
char *fmt,
}
 }
 
-void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...)
+void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
...)
 {
va_list args;
 
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 6ead6314..338d040 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark);
 int HiSax_command(isdn_ctrl *ic);
 int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
 __printf(3, 4)
-void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
+void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
...);
 __printf(3, 0)
-void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list 
args);
+void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
va_list args);
 void HiSax_reportcard(int cardnr, int sel);
 int QuickHex(char *txt, u_char *p, int cnt);
 void LogFrame(struct IsdnCardState *cs, u_char *p, int size);
-- 
2.8.1



Re: [PATCH v2 3/3] Constify some function parameters

2016-07-06 Thread Emese Revfy
On Tue, 5 Jul 2016 07:58:04 +0800
kbuild test robot  wrote:

> All warnings (new ones prefixed by >>):
> 
>drivers/isdn/hisax/config.c: In function 'VHiSax_putstatus':
> >> drivers/isdn/hisax/config.c:688:5: warning: assignment discards 'const' 
> >> qualifier from pointer target type [-Wdiscarded-qualifiers]
>   p = fmt;

Hi,

Thanks for the report, I resent "[PATCH v2 3/3] Constify some function 
parameters" with the fix.

-- 
Emese


[PATCH v3 0/4] Introduce the latent_entropy gcc plugin

2016-06-14 Thread Emese Revfy
I would like to introduce the latent_entropy gcc plugin. This plugin mitigates
the problem of the kernel having too little entropy during and after boot
for generating crypto keys.

This plugin mixes random values into the latent_entropy global variable
in functions marked by the __latent_entropy attribute.
The value of this global variable is added to the kernel entropy pool
to increase the entropy.

It is a CII project supported by the Linux Foundation.

The latent_entropy plugin was ported from grsecurity/PaX originally written by
the PaX Team. You can find more about the plugin here:
https://grsecurity.net/pipermail/grsecurity/2012-July/001093.html

The plugin supports all gcc version from 4.5 to 6.0.

I do some changes above the PaX version. The important one is mixing
the stack pointer into the global variable too.
You can find more about the changes here:
https://github.com/ephox-gcc-plugins/latent_entropy

This patch set is based on the "Introduce GCC plugin infrastructure" patch set 
(v9 next-20160520).

Emese Revfy (4):
 Add support for passing gcc plugin arguments
 Add the latent_entropy gcc plugin
 Mark functions with the latent_entropy attribute
 Add the extra_latent_entropy kernel parameter


Changes from v2:
  * Moved the passing of gcc plugin arguments into a separate patch
(Suggested-by: Kees Cook )
  * Mix the global entropy variable with the stack pointer 
(latent_entropy_plugin.c)
  * Handle tail calls (latent_entropy_plugin.c)
  * Fix some indentation related warnings suggested by checkpatch.pl 
(latent_entropy_plugin.c)
  * Commented some latent_entropy plugin code
(Suggested-by: Kees Cook )

Changes from v1:
  * Remove unnecessary ifdefs
(Suggested-by: Kees Cook )
  * Separate the two definitions of add_latent_entropy()
(Suggested-by: Kees Cook )
  * Removed unnecessary global variable (latent_entropy_plugin.c)
  * About the latent_entropy gcc attribute (latent_entropy_plugin.c)
  * Measure the boot time performance impact of the latent_entropy plugin 
(arch/Kconfig)

---
 Documentation/kernel-parameters.txt |   5 +
 arch/Kconfig|  23 ++
 arch/powerpc/kernel/Makefile|   8 +-
 block/blk-softirq.c |   2 +-
 drivers/char/random.c   |   6 +-
 fs/namespace.c  |   2 +-
 include/linux/compiler-gcc.h|   7 +
 include/linux/compiler.h|   4 +
 include/linux/fdtable.h |   2 +-
 include/linux/genhd.h   |   2 +-
 include/linux/init.h|   4 +-
 include/linux/random.h  |  14 +-
 init/main.c |   1 +
 kernel/fork.c   |   5 +-
 kernel/rcu/tiny.c   |   2 +-
 kernel/rcu/tree.c   |   2 +-
 kernel/sched/fair.c |   2 +-
 kernel/softirq.c|   4 +-
 kernel/time/timer.c |   2 +-
 lib/irq_poll.c  |   2 +-
 lib/random32.c  |   2 +-
 mm/page_alloc.c |  30 ++
 net/core/dev.c  |   4 +-
 scripts/Makefile.gcc-plugins|  10 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 597 
 26 files changed, 714 insertions(+), 29 deletions(-)


[PATCH v3 1/4] Add support for passing gcc plugin arguments

2016-06-14 Thread Emese Revfy

Signed-off-by: Emese Revfy 
---
 scripts/Makefile.gcc-plugins | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scripts/Makefile.gcc-plugins b/scripts/Makefile.gcc-plugins
index 5e22b60..da7f86c 100644
--- a/scripts/Makefile.gcc-plugins
+++ b/scripts/Makefile.gcc-plugins
@@ -19,7 +19,7 @@ ifdef CONFIG_GCC_PLUGINS
 endif
   endif
 
-  GCC_PLUGINS_CFLAGS := $(addprefix -fplugin=$(objtree)/scripts/gcc-plugins/, 
$(gcc-plugin-y))
+  GCC_PLUGINS_CFLAGS := $(strip $(addprefix 
-fplugin=$(objtree)/scripts/gcc-plugins/, $(gcc-plugin-y)) 
$(gcc-plugin-cflags-y))
 
   export PLUGINCC GCC_PLUGINS_CFLAGS GCC_PLUGIN SANCOV_PLUGIN
 
-- 
2.8.1



[PATCH v3 2/4] Add the latent_entropy gcc plugin

2016-06-14 Thread Emese Revfy
This plugin mitigates the problem of the kernel having too little entropy during
and after boot for generating crypto keys.

It creates a local variable in every marked function. The value of this 
variable is
modified by randomly chosen operations (add, xor and rol) and
random values (gcc generates them at compile time and the stack pointer at 
runtime).
It depends on the control flow (e.g., loops, conditions).

Before the function returns the plugin writes this local variable
into the latent_entropy global variable. The value of this global variable is
added to the kernel entropy pool in do_one_initcall() and _do_fork().

Signed-off-by: Emese Revfy 
---
 arch/Kconfig|  18 +
 arch/powerpc/kernel/Makefile|   8 +-
 include/linux/random.h  |  10 +
 init/main.c |   1 +
 kernel/fork.c   |   1 +
 mm/page_alloc.c |   5 +
 scripts/Makefile.gcc-plugins|   8 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 597 
 9 files changed, 644 insertions(+), 5 deletions(-)
 create mode 100644 scripts/gcc-plugins/latent_entropy_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 566f922..c099ebd 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -394,6 +394,24 @@ config GCC_PLUGIN_SANCOV
  gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
  by Dmitry Vyukov .
 
+config GCC_PLUGIN_LATENT_ENTROPY
+   bool "Generate some entropy during boot and runtime"
+   depends on GCC_PLUGINS
+   help
+ By saying Y here the kernel will instrument some kernel code to
+ extract some entropy from both original and artificially created
+ program state.  This will help especially embedded systems where
+ there is little 'natural' source of entropy normally.  The cost
+ is some slowdown of the boot process (about 0.5%) and fork and
+ irq processing.
+
+ Note that entropy extracted this way is not known to be 
cryptographically
+ secure!
+
+ This plugin was ported from grsecurity/PaX. More information at:
+  * https://grsecurity.net/
+  * https://pax.grsecurity.net/
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2da380f..6c7e448 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,10 +16,10 @@ endif
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace early boot code
-CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
 # do not trace tracer code
 CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
 # timers used by tracing
diff --git a/include/linux/random.h b/include/linux/random.h
index e47e533..752e7df 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -18,6 +18,16 @@ struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+
+#if defined(CONFIG_GCC_PLUGIN_LATENT_ENTROPY) && !defined(__CHECKER__)
+static inline void add_latent_entropy(void)
+{
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+}
+#else
+static inline void add_latent_entropy(void) {}
+#endif
+
 extern void add_input_randomness(unsigned int type, unsigned int code,
 unsigned int value);
 extern void add_interrupt_randomness(int irq, int irq_flags);
diff --git a/init/main.c b/init/main.c
index 4c17fda..07e4174 100644
--- a/init/main.c
+++ b/init/main.c
@@ -781,6 +781,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
}
WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf);
 
+   add_latent_entropy();
return ret;
 }
 
diff --git a/kernel/fork.c b/kernel/fork.c
index cdf520f..d07d5a6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1766,6 +1766,7 @@ long _do_fork(unsigned long clone_flags,
 
p = copy_process(clone_flags, stack_start, stack_size,
 child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
+   add_latent_entropy();
/*
 * Do this prior waking up the new thread - the thread pointer
 * might get invalid after t

[PATCH v3 3/4] Mark functions with the latent_entropy attribute

2016-06-14 Thread Emese Revfy
The latent_entropy gcc attribute can be only on functions and variables.
If it is on a function then the plugin will instrument it. If the attribute
is on a variable then the plugin will initialize it with a random value.
The variable must be an integer, an integer array type or a structure with 
integer fields.

These functions have been selected because they are init functions or
are called at random times or they have variable loops.

Signed-off-by: Emese Revfy 
---
 block/blk-softirq.c  | 2 +-
 drivers/char/random.c| 6 +++---
 fs/namespace.c   | 2 +-
 include/linux/compiler-gcc.h | 7 +++
 include/linux/compiler.h | 4 
 include/linux/fdtable.h  | 2 +-
 include/linux/genhd.h| 2 +-
 include/linux/init.h | 4 ++--
 include/linux/random.h   | 4 ++--
 kernel/fork.c| 4 ++--
 kernel/rcu/tiny.c| 2 +-
 kernel/rcu/tree.c| 2 +-
 kernel/sched/fair.c  | 2 +-
 kernel/softirq.c | 4 ++--
 kernel/time/timer.c  | 2 +-
 lib/irq_poll.c   | 2 +-
 lib/random32.c   | 2 +-
 mm/page_alloc.c  | 2 +-
 net/core/dev.c   | 4 ++--
 19 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index 53b1737..489eab8 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
  * Softirq action handler - move entries to local list and loop over them
  * while passing them to the queue registered handler.
  */
-static void blk_done_softirq(struct softirq_action *h)
+static __latent_entropy void blk_done_softirq(struct softirq_action *h)
 {
struct list_head *cpu_list, local_list;
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0158d3b..6cca3ed 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -443,9 +443,9 @@ struct entropy_store {
 };
 
 static void push_to_pool(struct work_struct *work);
-static __u32 input_pool_data[INPUT_POOL_WORDS];
-static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
-static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
+static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
+static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
+static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
 
 static struct entropy_store input_pool = {
.poolinfo = &poolinfo_table[0],
diff --git a/fs/namespace.c b/fs/namespace.c
index 4fb1691..eed930c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2778,7 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct 
user_namespace *user_ns)
return new_ns;
 }
 
-struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace 
*ns,
+__latent_entropy struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct 
mnt_namespace *ns,
struct user_namespace *user_ns, struct fs_struct *new_fs)
 {
struct mnt_namespace *new_ns;
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index e294939..0ef8329 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -188,6 +188,13 @@
 #endif /* GCC_VERSION >= 40300 */
 
 #if GCC_VERSION >= 40500
+
+#ifndef __CHECKER__
+#ifdef LATENT_ENTROPY_PLUGIN
+#define __latent_entropy __attribute__((latent_entropy))
+#endif
+#endif
+
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 793c082..c65327b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile 
void *p, void *res, int s
 # define __attribute_const__   /* unimplemented */
 #endif
 
+#ifndef __latent_entropy
+# define __latent_entropy
+#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/fdtable.h b/include/linux/fdtable.h
index 5295535..9852c7e 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *);
 void put_files_struct(struct files_struct *fs);
 void reset_files_struct(struct files_struct *);
 int unshare_files(struct files_struct **);
-struct files_struct *dup_fd(struct files_struct *, int *);
+struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
int (*)(const void *, struct file *, unsigned),
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 359a8e4..8736c1f 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, 
unsigned int mask);
 extern unsigned int disk_cl

[PATCH v3 4/4] Add the extra_latent_entropy kernel parameter

2016-06-14 Thread Emese Revfy
When extra_latent_entropy is passed on the kernel command line,
entropy will be extracted from up to the first 4GB of RAM while the
runtime memory allocator is being initialized.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 Documentation/kernel-parameters.txt |  5 +
 arch/Kconfig|  5 +
 mm/page_alloc.c | 25 +
 3 files changed, 35 insertions(+)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 5349363..6c2496e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2862,6 +2862,11 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
the specified number of seconds.  This is to be used if
your oopses keep scrolling off the screen.
 
+   extra_latent_entropy
+   Enable a very simple form of latent entropy extraction
+   from the first 4GB of memory as the bootmem allocator
+   passes the memory pages to the buddy allocator.
+
pcbit=  [HW,ISDN]
 
pcd.[PARIDE]
diff --git a/arch/Kconfig b/arch/Kconfig
index c099ebd..8bf832e 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -405,6 +405,11 @@ config GCC_PLUGIN_LATENT_ENTROPY
  is some slowdown of the boot process (about 0.5%) and fork and
  irq processing.
 
+ When extra_latent_entropy is passed on the kernel command line,
+ entropy will be extracted from up to the first 4GB of RAM while the
+ runtime memory allocator is being initialized.  This costs even more
+ slowdown of the boot process.
+
  Note that entropy extracted this way is not known to be 
cryptographically
  secure!
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ffc4f4a..72c61bd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1234,6 +1235,15 @@ static void __free_pages_ok(struct page *page, unsigned 
int order)
local_irq_restore(flags);
 }
 
+bool __meminitdata extra_latent_entropy;
+
+static int __init setup_extra_latent_entropy(char *str)
+{
+   extra_latent_entropy = true;
+   return 0;
+}
+early_param("extra_latent_entropy", setup_extra_latent_entropy);
+
 #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
 volatile u64 latent_entropy __latent_entropy;
 EXPORT_SYMBOL(latent_entropy);
@@ -1254,6 +1264,21 @@ static void __init __free_pages_boot_core(struct page 
*page, unsigned int order)
__ClearPageReserved(p);
set_page_count(p, 0);
 
+   if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) < 
0x10) {
+   u64 hash = 0;
+   size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
+   const u64 *data = lowmem_page_address(page);
+
+   for (index = 0; index < end; index++)
+   hash ^= hash + data[index];
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+   latent_entropy ^= hash;
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+#else
+   add_device_randomness((const void *)&hash, sizeof(hash));
+#endif
+   }
+
page_zone(page)->managed_pages += nr_pages;
set_page_refcounted(page);
__free_pages(page, order);
-- 
2.8.1



Re: [PATCH v2 1/3] Add the latent_entropy gcc plugin

2016-06-14 Thread Emese Revfy
On Tue, 14 Jun 2016 11:27:00 -0700
Kees Cook  wrote:

> On Mon, Jun 13, 2016 at 2:49 PM, Emese Revfy  wrote:
> > On Thu, 9 Jun 2016 14:51:45 -0700
> > Kees Cook  wrote:
>
> >> > + * gcc plugin to help generate a little bit of entropy from program 
> >> > state,
> >> > + * used throughout the uptime of the kernel
> >>
> >> I think this comment needs a lot of expanding. What are all the ways
> >> that this plugin makes changes to code? Things I think I see are:
> >> pre-filling data variables with randomness, creating a local_entropy
> >> variable (local to what?), mixing stack pointer (into what?), updating
> >> latent_entropy global.
> >
> > I demonstrated the details here:
> > https://github.com/ephox-gcc-plugins/latent_entropy/commit/049acd9f478d47ee6526d8e93ab8cfcc3ff91b13
> 
> That helps, thanks. Can you also mention how __latent_entropy changes
> non-functions? (i.e. initializes them with random data.)
> 
> Also, I think this isn't accurate:
> 
>  * local_entropy ^= get_random_long();
> 
> Looking at the disassembly, it seems that static random values (i.e.
> randomly chosen at gcc runtime) are added, rather than making calls to
> the kernel's get_random_long() function.

The plugin doesn't insert calls to the kernel's get_random_long().
That was just an example (the plugin instrumentation would look like this in 
the kernel).
I rewrote these calls to a random constant.

-- 
Emese


Re: [PATCH v9 3/4] Add Cyclomatic complexity GCC plugin

2016-06-14 Thread Emese Revfy
On Tue, 14 Jun 2016 12:29:59 -0700
Laura Abbott  wrote:

> This has some weird interaction with ftrace. On x86
> 
> 1) make mrproper
> 2) make defconfig
> 3) enable GCC_PLUGINS, GCC_PLUGIN_CYC_COMPLEXITY
> 4) enable FUNCTION_TRACER (it will select other options as well)
> 5) make && make modules
> 
>MODPOST 18 modules
> ERROR: "__fentry__" [net/netfilter/xt_nat.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/xt_mark.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/xt_addrtype.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/xt_LOG.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/nf_nat_sip.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/nf_nat_irc.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/nf_nat_ftp.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/nf_nat.ko] undefined!
> ERROR: "__fentry__" [net/netfilter/nf_log_common.ko] undefined!
> ERROR: "__fentry__" [net/ipv6/netfilter/nf_log_ipv6.ko] undefined!
> ERROR: "__fentry__" [net/ipv4/netfilter/nf_nat_masquerade_ipv4.ko] undefined!
> ERROR: "__fentry__" [net/ipv4/netfilter/nf_nat_ipv4.ko] undefined!
> ERROR: "__fentry__" [net/ipv4/netfilter/nf_log_ipv4.ko] undefined!
> ERROR: "__fentry__" [net/ipv4/netfilter/nf_log_arp.ko] undefined!
> ERROR: "__fentry__" [net/ipv4/netfilter/iptable_nat.ko] undefined!
> ERROR: "__fentry__" [net/ipv4/netfilter/ipt_MASQUERADE.ko] undefined!
> ERROR: "__fentry__" [fs/efivarfs/efivarfs.ko] undefined!
> ERROR: "__fentry__" [drivers/thermal/x86_pkg_temp_thermal.ko] undefined!
> scripts/Makefile.modpost:91: recipe for target '__modpost' failed
> make[1]: *** [__modpost] Error 1
> 
> Verified with gcc-5.3.1 and gcc-6.1.1. You need to do a clean build
> with 'make mrproper' first to see this. Subsequent builds will
> succeed oddly enough. I suspect this

Thanks for the report, I'm looking into it.

-- 
Emese


Re: [PATCH v3 0/4] Introduce the latent_entropy gcc plugin

2016-06-15 Thread Emese Revfy
On Wed, 15 Jun 2016 11:55:44 -0700
Kees Cook  wrote:

>  The limit on the length of lines is 80 columns and this is a strongly
>  preferred limit.

I think the code looks worse when it is truncated to 80 columns but
I'll do it and resend the patches.

-- 
Emese


Re: [PATCH v3 2/4] Add the latent_entropy gcc plugin

2016-06-15 Thread Emese Revfy
On Wed, 15 Jun 2016 11:07:08 -0700
Kees Cook  wrote:

> On Tue, Jun 14, 2016 at 3:20 PM, Emese Revfy  wrote:
 
> This doesn't look right to me: these are CFLAGS_REMOVE_* entries, and
> I think you want to _add_ the DISABLE_LATENT_ENTROPY_PLUGIN to the
> CFLAGS here.

Thanks for the report. I think this patch fixes it:
https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next/commit/e7601ca00a0aeb5f6b96dc79a51a5089c4d32791

-- 
Emese


Re: [PATCH v9 3/4] Add Cyclomatic complexity GCC plugin

2016-06-15 Thread Emese Revfy
On Tue, 14 Jun 2016 12:29:59 -0700
Laura Abbott  wrote:

> On 05/23/2016 03:10 PM, Emese Revfy wrote:
> 1) make mrproper
> 2) make defconfig
> 3) enable GCC_PLUGINS, GCC_PLUGIN_CYC_COMPLEXITY
> 4) enable FUNCTION_TRACER (it will select other options as well)
> 5) make && make modules
> 
> ERROR: "__fentry__" [net/ipv4/netfilter/ipt_MASQUERADE.ko] undefined!
> ERROR: "__fentry__" [fs/efivarfs/efivarfs.ko] undefined!
> ERROR: "__fentry__" [drivers/thermal/x86_pkg_temp_thermal.ko] undefined!
> scripts/Makefile.modpost:91: recipe for target '__modpost' failed
> make[1]: *** [__modpost] Error 1

The patch below fixes this bug, but I think it is ugly.
https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next/commit/73e2d117daa7f3c6aee8935ecbb318354ff9cd82

If anyone has a better idea to fix this, please let me know.

Thanks
-- 
Emese


Re: [PATCH v2 1/3] Add the initify gcc plugin

2016-07-13 Thread Emese Revfy
On Tue, 12 Jul 2016 16:05:45 -0400
Kees Cook  wrote:

> /*
>  * The initify gcc-plugin attempts to identify const arguments that are only
>  * used during init (see __init), so they can be moved to the .init.rodata
>  * section. If an argument is passed to a non-init function, it must
>  * normally be assumed that such an argument has been captured by that
>  * function and may be used in the future when .init has been unmapped from
>  * memory. In order to identify functions that are confirmed to not capture
>  * their arguments, the __nocapture() attribute is used so that initify can
>  * better identify candidate variables.
>  */
> #ifdef INITIFY_PLUGIN
> # define __nocapture(...) __attribute__((nocapture(__VA_ARGS__)))
> #endif

Thanks, I'll take it in the next patch set with some additions (the attribute
also handles __exit functions and the plugin does other things e.g., it can
identify candidate init/exit functions and move them automatically to 
init.text/exit.text).

-- 
Emese


Re: [PATCH v2 1/3] Add the initify gcc plugin

2016-07-13 Thread Emese Revfy
On Tue, 12 Jul 2016 15:45:56 -0400
Kees Cook  wrote:

> On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy  wrote:
> > If a function is called by __init and __exit functions as well then
> > the plugin moves it to the __exit section. This causes false positive
> > section mismatch errors/warnings that I don't know how to handle yet.
> 
> Should the mismatch checker be updated to recognize this case? Without
> the plugin, I assume these kinds of functions would only ever be
> marked for __exit? If so, should the plugin strip the __init marking
> and only add __exit?

I don't modify the existing attributes. I just add a new __init/__exit when
a function hasn't a section attribute yet.
There are three cases:
 * when the function is called only by __init functions then the plugin adds
   the __init attribute
 * when the function is called only by __exit functions then the plugin adds
   the __exit attribute
 * when the function is called by __init and __exit functions too then the
   plugin adds the __exit attribute.
The last case causes the false positive(?) message of the section mismatch.

-- 
Emese


Re: [PATCH v2 1/3] Add the initify gcc plugin

2016-07-13 Thread Emese Revfy
On Tue, 12 Jul 2016 18:38:47 -0400
Kees Cook  wrote:

> On Tue, Jul 12, 2016 at 6:08 PM, Russell King - ARM Linux
>  wrote:
> > On Tue, Jul 12, 2016 at 03:45:56PM -0400, Kees Cook wrote:
> >> On Mon, Jul 4, 2016 at 7:40 PM, Emese Revfy  wrote:
> > That sounds like a problem for architectures that still discard the
> > __exit section at link time to reduce the size of the linked kernel
> > image - though, obviously, if using the plugin results in a smaller
> > kernel image _with_ the exit sections, then there's a net benefit
> > size-wise.
> 
> Ah right, __exit is dropped for non-modular builds. So, for "both
> __init and __exit" it sounds like the behavior depends on the build:
> 
> - if modular: remove __init marking (since we need it after init)
> - if non-modular: remove __exit marking (since we'll never call exit)

When gcc compiles vmlinux these functions should be in __init and when
it compiles *.ko then they can be in __exit. I have no time to do this
now but I added it to my todo list.

The temporary fix can be that I enable this section move only on x86
(on other archs it will decrase the coverage).

-- 
Emese


[PATCH v3 0/7] Introduce the initify gcc plugin

2016-07-26 Thread Emese Revfy
I would like to introduce the initify gcc plugin. 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 reduces memory usage.
The initify gcc plugin can be useful for embedded systems.

Originally it was a CII project supported by the Linux Foundation.

This plugin is the part of grsecurity/PaX.

The plugin supports all gcc versions from 4.5 to 6.0.

I made some changes on top of the PaX version (since March 6.). These are
the important ones:
 * move all local strings to init.rodata.str and exit.rodata.str
   (not just __func__)
 * report all initified strings and functions
   (GCC_PLUGIN_INITIFY_VERBOSE config option)
 * automatically discover init/exit functions and apply the __init or
   __exit attributes on them

You can find more about the changes here:
https://github.com/ephox-gcc-plugins/initify

This patch set is based on next-20160721.

Some statistics about the plugin:

On allyes config (amd64, gcc-6):
* 8412 initified strings
*  167 initified functions

On allmod config (i386, gcc-6):
* 8597 initified strings
*  159 initified functions

On allyes config (amd64, gcc-6):

section vanilla vanilla + initifychange
---
.rodata 21746728 (0x14bd428)21488680 (0x147e428)-258048
.init.data   1338376  (0x146c08) 1683016  (0x19ae48)+344640
.text   78270904 (0x4aa51b8)78228280 (0x4a9ab38) -42624
.init.text   1184725  (0x1213d5) 1223257  (0x12aa59) +38532
.exit.data   104  (0x68)   17760  (0x004560) +17656
.exit.text174473  (0x02a989)  175763  (0x02ae93)  +1290

FileSiz (vanilla)   FileSiz (vanilla + initify)  change

00  102936576 (0x622b000)   102678528 (0x61ec000)   -258048
03   28680192 (0x1b5a000)29081600 (0x1bbc000)   +401408

00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw
   .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata
   __param __modver
03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init
   .parainstructions .altinstructions .altinstr_replacement
   .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk


On defconfig (amd64, gcc-6):
* 1957 initified strings
*   29 initified functions

On defconfig (amd64, gcc-6):

section vanilla vanilla + initifychange
---
.rodata 2524240 (0x268450)  2462800 (0x259450)  -61440
.init.data   560256 (0x088c80)   644000 (0x09d3a0)  +83744
.text   9377367 (0x8f1657)  9373079 (0x8f0597)   -4288
.init.text   438586 (0x06b13a)   441828 (0x06bde4)   +3242
.exit.data0 832 (0x000340)+832
.exit.text 8857 (0x002299)  8857 (0x002299)  0

FileSiz (vanilla)   FileSiz (vanilla + initify)  change

00  13398016 (0xcc7000) 13336576 (0xcb8000) -61440
03   2203648 (0x21a000)  2293760 (0x23) +90112

00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw
   .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata
   __param __modver
03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init
   .parainstructions .altinstructions .altinstr_replacement
   .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk


Emese Revfy (7):
 Move type casts into is_kernel_rodata
 Split up struct warn_args to enable dataflow verification by the initify plugin
 Constify some function parameters
 Add the initify gcc plugin
 Mark functions with the __nocapture attribute
 Mark a few functions with the printf attribute
 Mark functions with the __unverified_nocapture attribute


Changed from v2:
 * Check all uses when walking a use-def chain.
 * Check all uses of initialized local variables and initify them if they
   have only nocapture uses. Previously only uses in call arguments
   determined whether the initializer value could be initified.
 * Handle the format gcc attribute from the plugin too.
 * Verify nocapture parameters of calls. Track uses of these parameters
   and verify that all uses are not captured. Verify only the nocapture
   attribute (The format attribute should be verified too.).
 * Fixed wrong indexing of function arguments.
 * Fixed decl comparison. When comparing two decls the tree codes must be
   the same.
 * Search capture uses of the return value. Use negative nocapture
   attribute parameter on a function

[PATCH v3 1/7] Move type casts into is_kernel_rodata

2016-07-26 Thread Emese Revfy
so that its parameter can be marked as nocapture.

Signed-off-by: Emese Revfy 
---
 mm/util.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/mm/util.c b/mm/util.c
index 662cddf..d95f10b 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -17,10 +17,10 @@
 
 #include "internal.h"
 
-static inline int is_kernel_rodata(unsigned long addr)
+static inline int is_kernel_rodata(const void *addr)
 {
-   return addr >= (unsigned long)__start_rodata &&
-   addr < (unsigned long)__end_rodata;
+   return (unsigned long)addr >= (unsigned long)__start_rodata &&
+   (unsigned long)addr < (unsigned long)__end_rodata;
 }
 
 /**
@@ -31,7 +31,7 @@ static inline int is_kernel_rodata(unsigned long addr)
  */
 void kfree_const(const void *x)
 {
-   if (!is_kernel_rodata((unsigned long)x))
+   if (!is_kernel_rodata(x))
kfree(x);
 }
 EXPORT_SYMBOL(kfree_const);
@@ -68,7 +68,7 @@ EXPORT_SYMBOL(kstrdup);
  */
 const char *kstrdup_const(const char *s, gfp_t gfp)
 {
-   if (is_kernel_rodata((unsigned long)s))
+   if (is_kernel_rodata(s))
return s;
 
return kstrdup(s, gfp);
-- 
2.8.1



[PATCH v3 2/7] Split up struct warn_args

2016-07-26 Thread Emese Revfy
to enable dataflow verification by the initify plugin. This allows marking
warn_slowpath* parameters as nocapture and compile time verification of
the related dataflows.

Signed-off-by: Emese Revfy 
---
 include/asm-generic/bug.h |  5 +
 kernel/panic.c| 32 
 lib/bug.c |  2 +-
 3 files changed, 14 insertions(+), 25 deletions(-)

diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h
index 6f96247..3048d10 100644
--- a/include/asm-generic/bug.h
+++ b/include/asm-generic/bug.h
@@ -81,11 +81,8 @@ extern void warn_slowpath_null(const char *file, const int 
line);
do { printk(arg); __WARN_TAINT(taint); } while (0)
 #endif
 
-/* used internally by panic.c */
-struct warn_args;
-
 void __warn(const char *file, int line, void *caller, unsigned taint,
-   struct pt_regs *regs, struct warn_args *args);
+   struct pt_regs *regs, const char *fmt, va_list args);
 
 #ifndef WARN_ON
 #define WARN_ON(condition) ({  \
diff --git a/kernel/panic.c b/kernel/panic.c
index ca8cea1..993ad20 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -475,13 +475,8 @@ void oops_exit(void)
kmsg_dump(KMSG_DUMP_OOPS);
 }
 
-struct warn_args {
-   const char *fmt;
-   va_list args;
-};
-
 void __warn(const char *file, int line, void *caller, unsigned taint,
-   struct pt_regs *regs, struct warn_args *args)
+   struct pt_regs *regs, const char *fmt, va_list args)
 {
disable_trace_on_warning();
 
@@ -495,8 +490,8 @@ void __warn(const char *file, int line, void *caller, 
unsigned taint,
pr_warn("WARNING: CPU: %d PID: %d at %pS\n",
raw_smp_processor_id(), current->pid, caller);
 
-   if (args)
-   vprintk(args->fmt, args->args);
+   if (fmt)
+   vprintk(fmt, args);
 
if (panic_on_warn) {
/*
@@ -525,31 +520,28 @@ void __warn(const char *file, int line, void *caller, 
unsigned taint,
 #ifdef WANT_WARN_ON_SLOWPATH
 void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
 {
-   struct warn_args args;
+   va_list args;
 
-   args.fmt = fmt;
-   va_start(args.args, fmt);
-   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL,
-  &args);
-   va_end(args.args);
+   va_start(args, fmt);
+   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, fmt, 
args);
+   va_end(args);
 }
 EXPORT_SYMBOL(warn_slowpath_fmt);
 
 void warn_slowpath_fmt_taint(const char *file, int line,
 unsigned taint, const char *fmt, ...)
 {
-   struct warn_args args;
+   va_list args;
 
-   args.fmt = fmt;
-   va_start(args.args, fmt);
-   __warn(file, line, __builtin_return_address(0), taint, NULL, &args);
-   va_end(args.args);
+   va_start(args, fmt);
+   __warn(file, line, __builtin_return_address(0), taint, NULL, fmt, args);
+   va_end(args);
 }
 EXPORT_SYMBOL(warn_slowpath_fmt_taint);
 
 void warn_slowpath_null(const char *file, int line)
 {
-   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL);
+   __warn(file, line, __builtin_return_address(0), TAINT_WARN, NULL, NULL, 
NULL);
 }
 EXPORT_SYMBOL(warn_slowpath_null);
 #endif
diff --git a/lib/bug.c b/lib/bug.c
index bc3656e..c8bdebb 100644
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -168,7 +168,7 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct 
pt_regs *regs)
if (warning) {
/* this is a WARN_ON rather than BUG/BUG_ON */
__warn(file, line, (void *)bugaddr, BUG_GET_TAINT(bug), regs,
-  NULL);
+  NULL, NULL);
return BUG_TRAP_TYPE_WARN;
}
 
-- 
2.8.1



[PATCH v3 3/7] Constify some function parameters

2016-07-26 Thread Emese Revfy
Initify needs const pointer types, the initify plugin caught some __printf
arguments that weren't const yet.

Signed-off-by: Emese Revfy 
---
 drivers/isdn/hisax/config.c | 16 
 drivers/isdn/hisax/hisax.h  |  4 ++--
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index bf04d2a..2d12c6c 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -659,7 +659,7 @@ int jiftime(char *s, long mark)
 
 static u_char tmpbuf[HISAX_STATUS_BUFSIZE];
 
-void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
+void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt,
  va_list args)
 {
/* if head == NULL the fmt contains the full info */
@@ -669,23 +669,24 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char 
*head, char *fmt,
u_char  *p;
isdn_ctrl   ic;
int len;
+   const u_char*data;
 
if (!cs) {
printk(KERN_WARNING "HiSax: No CardStatus for message");
return;
}
spin_lock_irqsave(&cs->statlock, flags);
-   p = tmpbuf;
if (head) {
+   p = tmpbuf;
p += jiftime(p, jiffies);
p += sprintf(p, " %s", head);
p += vsprintf(p, fmt, args);
*p++ = '\n';
*p = 0;
len = p - tmpbuf;
-   p = tmpbuf;
+   data = tmpbuf;
} else {
-   p = fmt;
+   data = fmt;
len = strlen(fmt);
}
if (len > HISAX_STATUS_BUFSIZE) {
@@ -699,13 +700,12 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char 
*head, char *fmt,
if (i >= len)
i = len;
len -= i;
-   memcpy(cs->status_write, p, i);
+   memcpy(cs->status_write, data, i);
cs->status_write += i;
if (cs->status_write > cs->status_end)
cs->status_write = cs->status_buf;
-   p += i;
if (len) {
-   memcpy(cs->status_write, p, len);
+   memcpy(cs->status_write, data + i, len);
cs->status_write += len;
}
 #ifdef KERNELSTACK_DEBUG
@@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, 
char *fmt,
}
 }
 
-void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...)
+void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
...)
 {
va_list args;
 
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 6ead6314..338d040 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark);
 int HiSax_command(isdn_ctrl *ic);
 int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
 __printf(3, 4)
-void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
+void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
...);
 __printf(3, 0)
-void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list 
args);
+void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
va_list args);
 void HiSax_reportcard(int cardnr, int sel);
 int QuickHex(char *txt, u_char *p, int cnt);
 void LogFrame(struct IsdnCardState *cs, u_char *p, int size);
-- 
2.8.1



[PATCH v3 4/7] Add the initify gcc plugin

2016-07-26 Thread Emese Revfy
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.

If a function is called by __init and __exit functions as well then
the plugin moves it to the __exit section. This causes false positive
section mismatch errors/warnings that I don't know how to handle yet.

The instrumentation pass of the latent_entropy plugin must run after
the initify plugin to increase coverage.

Signed-off-by: Emese Revfy 
---
 arch/Kconfig |   35 +
 arch/x86/Kconfig |1 +
 arch/x86/lib/Makefile|4 +
 include/asm-generic/vmlinux.lds.h|2 +
 include/linux/compiler-gcc.h |   14 +
 include/linux/compiler.h |4 +
 scripts/Makefile.gcc-plugins |9 +
 scripts/gcc-plugins/gcc-common.h |   41 +
 scripts/gcc-plugins/initify_plugin.c | 1883 ++
 9 files changed, 1993 insertions(+)
 create mode 100644 scripts/gcc-plugins/initify_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 88673c2..41eb562 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -417,6 +417,41 @@ 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 HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT
+   bool
+   depends on GCC_PLUGINS
+   help
+ Move functions to the exit section if they are called by __init and
+ __exit functions too.
+
+config GCC_PLUGIN_INITIFY_INIT_EXIT
+   bool
+   depends on GCC_PLUGIN_INITIFY && HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT
+
+config GCC_PLUGIN_INITIFY_VERBOSE
+   bool "Verbose"
+   depends on GCC_PLUGINS
+   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/arch/x86/Kconfig b/arch/x86/Kconfig
index c580d8c..921a13c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -114,6 +114,7 @@ config X86
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_GCC_PLUGINS
+   select HAVE_GCC_PLUGIN_INITIFY_INIT_EXIT if GCC_PLUGINS
select HAVE_GENERIC_DMA_COHERENTif X86_32
select HAVE_HW_BREAKPOINT
select HAVE_IDE
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index 34a7413..b98b8fd 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -29,6 +29,10 @@ lib-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
 obj-y += msr.o msr-reg.o msr-reg-export.o hweight.o
 
 ifeq ($(CONFIG_X86_32),y)
+CFLAGS_strstr_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS)
+CFLAGS_string_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS)
+CFLAGS_memcpy_32.o += $(INITIFY_DISABLE_VERIFIY_NOCAPTURE_FUNCTIONS)
+
 obj-y += atomic64_32.o
 lib-y += atomic64_cx8_32.o
 lib-y += checksum_32.o
diff --git a/include/asm-generic/vmlinux.lds.h 
b/include/asm-generic/vmlinux.lds.h
index 2456397..6e292f9 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -531,6 +531,7 @@
MEM_DISCARD(init.data)  \
KERNEL_CTORS()  \
MCOUNT_REC()\
+   *(.init.rodata.str) \
*(.init.rodata) \
FTRACE_EVENTS() \
TRACE_SYSCALLS()\
@@ -558,

[PATCH v3 5/7] Mark functions with the __nocapture attribute

2016-07-26 Thread Emese Revfy
The nocapture gcc attribute can be on functions only.
The attribute takes zero or more signed integer constants as parameters
that specify the function parameters to initify when the passed arguments
are of const char* type.

A negative attribute parameter value means that the corresponding function
parameter is returned by the function and the passed argument will only be
initified if the data flow of the returned value is not captured in the caller.

If no values are passed to the attribute then all function parameters are
treated as nocapture.

If the marked parameter is a vararg then the plugin initifies all vararg
arguments.

I couldn't test the arm, arm64 and powerpc architectures.

Signed-off-by: Emese Revfy 
---
 arch/arm/include/asm/string.h | 10 +++---
 arch/arm64/include/asm/string.h   | 25 ++---
 arch/powerpc/include/asm/string.h | 19 +-
 arch/x86/include/asm/string_32.h  | 25 ++---
 arch/x86/include/asm/string_64.h  | 20 +--
 arch/x86/kernel/hpet.c|  2 +-
 drivers/acpi/acpica/acutils.h |  2 +-
 fs/char_dev.c |  2 +-
 fs/ntfs/debug.h   |  6 ++--
 fs/ocfs2/cluster/masklog.h|  2 +-
 include/acpi/acpixf.h |  2 +-
 include/asm-generic/bug.h |  7 ++--
 include/drm/drmP.h|  2 +-
 include/linux/audit.h |  5 +--
 include/linux/fs.h|  8 +++--
 include/linux/printk.h|  2 +-
 include/linux/ratelimit.h |  3 +-
 include/linux/string.h| 75 ---
 lib/vsprintf.c|  6 ++--
 mm/util.c |  2 +-
 security/integrity/integrity.h|  2 +-
 21 files changed, 119 insertions(+), 108 deletions(-)

diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
index cf4f3aa..8f2f2d9 100644
--- a/arch/arm/include/asm/string.h
+++ b/arch/arm/include/asm/string.h
@@ -7,19 +7,19 @@
  */
 
 #define __HAVE_ARCH_STRRCHR
-extern char * strrchr(const char * s, int c);
+extern char * strrchr(const char * s, int c) __nocapture(-1);
 
 #define __HAVE_ARCH_STRCHR
-extern char * strchr(const char * s, int c);
+extern char * strchr(const char * s, int c) __nocapture(-1);
 
 #define __HAVE_ARCH_MEMCPY
-extern void * memcpy(void *, const void *, __kernel_size_t);
+extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMMOVE
-extern void * memmove(void *, const void *, __kernel_size_t);
+extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMCHR
-extern void * memchr(const void *, int, __kernel_size_t);
+extern void * memchr(const void *, int, __kernel_size_t) __nocapture(-1);
 
 #define __HAVE_ARCH_MEMSET
 extern void * memset(void *, int, __kernel_size_t);
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 2eb714c..188a102 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -17,40 +17,41 @@
 #define __ASM_STRING_H
 
 #define __HAVE_ARCH_STRRCHR
-extern char *strrchr(const char *, int c);
+extern char *strrchr(const char *, int c) __nocapture(-1);
 
 #define __HAVE_ARCH_STRCHR
-extern char *strchr(const char *, int c);
+extern char *strchr(const char *, int c) __nocapture(-1);
 
 #define __HAVE_ARCH_STRCMP
-extern int strcmp(const char *, const char *);
+extern int strcmp(const char *, const char *) __nocapture();
 
 #define __HAVE_ARCH_STRNCMP
-extern int strncmp(const char *, const char *, __kernel_size_t);
+extern int
+strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2);
 
 #define __HAVE_ARCH_STRLEN
-extern __kernel_size_t strlen(const char *);
+extern __kernel_size_t strlen(const char *) __nocapture(1);
 
 #define __HAVE_ARCH_STRNLEN
-extern __kernel_size_t strnlen(const char *, __kernel_size_t);
+extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1);
 
 #define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
-extern void *__memcpy(void *, const void *, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
+extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMMOVE
-extern void *memmove(void *, const void *, __kernel_size_t);
-extern void *__memmove(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2);
+extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMCHR
-extern void *memchr(const void *, int, __kernel_size_t);
+extern void *memchr(const void *, int, __kernel_size_t) __nocapture(-1);
 
 #define __HAVE_ARCH_MEMSET
 extern void *memset(void *, int, __kernel_size_t);
 extern void *__memset(void *, int, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *, const void *, size_t);
+extern int m

[PATCH v3 6/7] Mark a few functions with the printf attribute

2016-07-26 Thread Emese Revfy
This allows not only compile time format string checking but can also
increase the coverage of the initify plugin.

Signed-off-by: Emese Revfy 
---
 drivers/scsi/esas2r/esas2r_log.h | 4 ++--
 include/acpi/acpiosxf.h  | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/esas2r/esas2r_log.h b/drivers/scsi/esas2r/esas2r_log.h
index 7b6397b..75b9d23 100644
--- a/drivers/scsi/esas2r/esas2r_log.h
+++ b/drivers/scsi/esas2r/esas2r_log.h
@@ -61,8 +61,8 @@ enum {
 #endif
 };
 
-int esas2r_log(const long level, const char *format, ...);
-int esas2r_log_dev(const long level,
+__printf(2, 3) int esas2r_log(const long level, const char *format, ...);
+__printf(3, 4) int esas2r_log_dev(const long level,
   const struct device *dev,
   const char *format,
   ...);
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 562603d..7ee4475 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -337,11 +337,12 @@ acpi_status acpi_os_signal(u32 function, void *info);
  * Debug print routines
  */
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_printf
+__printf(1, 2)
 void ACPI_INTERNAL_VAR_XFACE acpi_os_printf(const char *format, ...);
 #endif
 
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_vprintf
-void acpi_os_vprintf(const char *format, va_list args);
+__printf(1, 0) void acpi_os_vprintf(const char *format, va_list args);
 #endif
 
 #ifndef ACPI_USE_ALTERNATE_PROTOTYPE_acpi_os_redirect_output
-- 
2.8.1



[PATCH v3 7/7] Mark functions with the __unverified_nocapture attribute

2016-07-26 Thread Emese Revfy
This attribute disables the compile data flow verification of the
designated nocapture parameters of the function. Use it only on function
parameters that are difficult for the plugin to analyze.

Signed-off-by: Emese Revfy 
---
 include/linux/compiler-gcc.h | 1 +
 include/linux/compiler.h | 4 
 lib/vsprintf.c   | 4 ++--
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 6697ea3..76797b9 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -207,6 +207,7 @@
  */
 #ifdef INITIFY_PLUGIN
 #define __nocapture(...) __attribute__((nocapture(__VA_ARGS__)))
+#define __unverified_nocapture(...) 
__attribute__((unverified_nocapture(__VA_ARGS__)))
 #endif
 
 /*
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 391b48b..f0b4156 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -416,6 +416,10 @@ static __always_inline void __write_once_size(volatile 
void *p, void *res, int s
 # define __nocapture(...)
 #endif
 
+#ifndef __unverified_nocapture
+# define __unverified_nocapture(...)
+#endif
+
 /*
  * Tell gcc if a function is cold. The compiler will assume any path
  * directly leading to the call is unlikely.
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a192761..cb964b5 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -118,7 +118,7 @@ long long simple_strtoll(const char *cp, char **endp, 
unsigned int base)
 }
 EXPORT_SYMBOL(simple_strtoll);
 
-static noinline_for_stack __nocapture(1)
+static noinline_for_stack __nocapture(1) __unverified_nocapture(1)
 int skip_atoi(const char **s)
 {
int i = 0;
@@ -1570,7 +1570,7 @@ int kptr_restrict __read_mostly;
  * function pointers are really function descriptors, which contain a
  * pointer to the real address.
  */
-static noinline_for_stack __nocapture(1)
+static noinline_for_stack __nocapture(1) __unverified_nocapture(1)
 char *pointer(const char *fmt, char *buf, char *end, void *ptr,
  struct printf_spec spec)
 {
-- 
2.8.1



Re: [PATCH v1 2/2] Mark functions with the __nocapture attribute

2016-07-01 Thread Emese Revfy
On Wed, 29 Jun 2016 17:12:45 -0700
Joe Perches  wrote:

> On Wed, 2016-06-29 at 20:42 +0200, Emese Revfy wrote:
> > On Tue, 28 Jun 2016 14:00:57 -0700 Joe Perches  wrote:
> > > On Tue, 2016-06-28 at 22:40 +0200, Emese Revfy wrote:
> > > > On Tue, 28 Jun 2016 09:43:31 -0700 Joe Perches  wrote:
> > > > > On Tue, 2016-06-28 at 13:36 +0200, Emese Revfy wrote:
> > > > > > The nocapture gcc attribute can be on functions only.
> > > > > > The attribute takes one or more unsigned integer constants as 
> > > > > > parameters
> > > > > > that specify the function argument(s) of const char* type to 
> > > > > > initify.
> > > > > Perhaps this should be const *
> > > > For me function arguments are the values passed to a function call so
> > > > the const char* type is good because this is the only one that the 
> > > > plugin handles
> > > > (for now at least).
> > > OK, but this function prototype specified takes a const void *
> > > 
> > > +extern void * memcpy(void *, const void *, __kernel_size_t) 
> > > __nocapture(2);
> > What matters for the plugin is the type of the passed arguments (which can 
> > be const char*
> > in the current implementation), not that of the parameters.
> 
> And how does this work when the prototype requires the compiler to
> implicit cast to const void * before calling the function?


The plugin searches for the nocapture attribute that does not depend on the 
type.
If the function argument is not a string constant just a pointer then
the plugin walks the data flow (use-def chain) and tries to find a string 
constant.
If there is a cast to void * then the use-def chain will walk across it.

-- 
Emese


[PATCH v2 0/3] Introduce the initify gcc plugin

2016-07-04 Thread Emese Revfy
I would like to introduce the initify gcc plugin. 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 reduces memory usage.
The initify gcc plugin can be useful for embedded systems.

It is a CII project supported by the Linux Foundation.

This plugin is the part of grsecurity/PaX.

The plugin supports all gcc versions from 4.5 to 6.0.

I made some changes on top of the PaX version (since March 6.). These are
the important ones:
 * move all local strings to init.rodata.str and exit.rodata.str
   (not just __func__)
 * report all initified strings and functions
   (GCC_PLUGIN_INITIFY_VERBOSE config option)
 * automatically discover init/exit functions and apply the __init or
   __exit attributes on them

You can find more about the changes here:
https://github.com/ephox-gcc-plugins/initify

This patch set is based on the "Add support for complex gcc plugins that
don't fit in a single file" patch set
(https://github.com/ephox-gcc-plugins/gcc-plugins_linux-next.git#initify
HEAD: e08eda5d85f7f52641640).

Some statistics about the plugin:

On allyes config (amd64, gcc-6):
* 7765 initified strings
*  231 initified functions

On allmod config (i386, gcc-6):
* 9177 initified strings
*  288 initified functions

On allyes config (amd64, gcc-6):

section vanilla vanilla + initifychange
---
.rodata 19054824 (0x122c0e8)18841832 (0x11f80e8)-212992
.init.data   1273768  (0x136fa8) 1583496  (0x182988)+309728
.text   46126301 (0x2bfd4dd)46099805 (0x2bf6d5d) -26496
.init.text836339  (0x0cc2f3)  855952  (0x0d0f90) +19613
.exit.data   104  (0x68)   16736  (0x004160) +16632
.exit.text125511  (0x01ea47)  133267  (0x020893)  +7756

FileSiz (vanilla)   FileSiz (vanilla + initify)  change

00  67727360 (0x4097000)65417216 (0x3e63000)-2310144
03   2453504  (0x257000) 2809856  (0x2ae000) +356352

00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw
   .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata
   __param __modver
03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init
   .parainstructions .altinstructions .altinstr_replacement
   .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk


On defconfig (amd64, gcc-6):
* 2044 initified strings
*   43 initified functions

On defconfig (amd64, gcc-6):

section vanilla vanilla + initifychange
---
.rodata 2466736 (0x25a3b0)  2405296 (0x24b3b0)  -61440
.init.data   564656 (0x089db0)   645616 (0x09d9f0)  +80960
.text   9364727 (0x8ee4f7)  9360823 (0x8ed5b7)   -3904
.init.text   436097 (0x06a781)   439161 (0x06b379)   +3064
.exit.data0 864 (0x000360)+864
.exit.text 8806 (0x002266) 9824 (0x002660)   +1018

FileSiz (vanilla)   FileSiz (vanilla + initify)  change

00  13340672 (0xcb9000) 13279232 (0xcaa000) -61440
03   1097728 (0x10c000)  1183744 (0x121000) +86016

00 .text .notes __ex_table .rodata __bug_table .pci_fixup .builtin_fw
   .tracedata __ksymtab __ksymtab_gpl __ksymtab_strings __init_rodata
   __param __modver
03 .init.text .altinstr_aux .init.data .x86_cpu_dev.init
   .parainstructions .altinstructions .altinstr_replacement
   .iommu_table .apicdrivers .exit.text .exit.data .smp_locks .bss .brk


Emese Revfy (3):
 Add the initify gcc plugin
 Mark functions with the __nocapture attribute
 Constify some function parameters


Changes from v1:
 * Removed unnecessary nocapture attributes from boot code
   (Reported-by: PaX Team )
 * Removed nocapture attributes from functions that return
   the marked parameter
   (Reported-by: Rasmus Villemoes )
 * Added nocapture attribute to strlen()
 * Updated gcc-common.h from PaX
 * Don't forcibly constify initified string types
   this caused the size reduction of the .data section
   (initify_plugin.c)
 * Added the section mismatch problem in the commit message

---
 arch/Kconfig |   23 +
 arch/arm/include/asm/string.h|4 +-
 arch/arm64/include/asm/string.h  |   19 +-
 arch/powerpc/include/asm/string.h|   19 +-
 arch/x86/include/asm/string_32.h |   21 +-
 arch/x86/include/asm/string_64.h |   20 +-
 arch/x86/kernel/hpet.c   |  

[PATCH v2 1/3] Add the initify gcc plugin

2016-07-04 Thread Emese Revfy
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.

If a function is called by __init and __exit functions as well then
the plugin moves it to the __exit section. This causes false positive
section mismatch errors/warnings that I don't know how to handle yet.

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/gcc-common.h |   41 ++
 scripts/gcc-plugins/initify_plugin.c | 1183 ++
 5 files changed, 1253 insertions(+)
 create mode 100644 scripts/gcc-plugins/initify_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 1c91f52..0c877f6 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 ec3b78d..c73537a 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -531,6 +531,7 @@
MEM_DISCARD(init.data)  \
KERNEL_CTORS()  \
MCOUNT_REC()\
+   *(.init.rodata.str) \
*(.init.rodata) \
FTRACE_EVENTS() \
TRACE_SYSCALLS()\
@@ -555,6 +556,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/gcc-common.h b/scripts/gcc-plugins/gcc-common.h
index 172850b..7f2eb16 100644
--- a/scripts/gcc-plugins/gcc-common.h
+++ b/scripts/gcc-plugins/gcc-common.h
@@ -286,6 +286,26 @@ static inline struct cgraph_node 
*cgraph_next_function_with_gimple_body(struct c
return NULL;
 }
 
+static inline bool cgraph_for_node_and_aliases(cgraph_node_ptr node,
+   bool (*callba

[PATCH v2 2/3] Mark functions with the __nocapture attribute

2016-07-04 Thread Emese Revfy
The nocapture gcc attribute can be on functions only.
The attribute takes one or more unsigned integer constants as parameters
that specify the function argument(s) of const char* type to initify.
If the marked argument is a vararg then the plugin initifies
all vararg arguments.

I couldn't test the arm, arm64 and powerpc architectures.

Signed-off-by: Emese Revfy 
---
 arch/arm/include/asm/string.h |  4 +--
 arch/arm64/include/asm/string.h   | 19 ++--
 arch/powerpc/include/asm/string.h | 19 ++--
 arch/x86/include/asm/string_32.h  | 21 ++---
 arch/x86/include/asm/string_64.h  | 20 ++---
 arch/x86/kernel/hpet.c|  2 +-
 include/asm-generic/bug.h |  6 ++--
 include/linux/compiler-gcc.h  | 10 +--
 include/linux/compiler.h  |  4 +++
 include/linux/fs.h|  5 ++--
 include/linux/printk.h|  2 +-
 include/linux/string.h| 63 ---
 12 files changed, 96 insertions(+), 79 deletions(-)

diff --git a/arch/arm/include/asm/string.h b/arch/arm/include/asm/string.h
index cf4f3aa..ddb9d58 100644
--- a/arch/arm/include/asm/string.h
+++ b/arch/arm/include/asm/string.h
@@ -13,10 +13,10 @@ extern char * strrchr(const char * s, int c);
 extern char * strchr(const char * s, int c);
 
 #define __HAVE_ARCH_MEMCPY
-extern void * memcpy(void *, const void *, __kernel_size_t);
+extern void * memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMMOVE
-extern void * memmove(void *, const void *, __kernel_size_t);
+extern void * memmove(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMCHR
 extern void * memchr(const void *, int, __kernel_size_t);
diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h
index 2eb714c..4263a27 100644
--- a/arch/arm64/include/asm/string.h
+++ b/arch/arm64/include/asm/string.h
@@ -23,24 +23,25 @@ extern char *strrchr(const char *, int c);
 extern char *strchr(const char *, int c);
 
 #define __HAVE_ARCH_STRCMP
-extern int strcmp(const char *, const char *);
+extern int strcmp(const char *, const char *) __nocapture(1, 2);
 
 #define __HAVE_ARCH_STRNCMP
-extern int strncmp(const char *, const char *, __kernel_size_t);
+extern int
+strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2);
 
 #define __HAVE_ARCH_STRLEN
-extern __kernel_size_t strlen(const char *);
+extern __kernel_size_t strlen(const char *) __nocapture(1);
 
 #define __HAVE_ARCH_STRNLEN
-extern __kernel_size_t strnlen(const char *, __kernel_size_t);
+extern __kernel_size_t strnlen(const char *, __kernel_size_t) __nocapture(1);
 
 #define __HAVE_ARCH_MEMCPY
-extern void *memcpy(void *, const void *, __kernel_size_t);
-extern void *__memcpy(void *, const void *, __kernel_size_t);
+extern void *memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
+extern void *__memcpy(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMMOVE
-extern void *memmove(void *, const void *, __kernel_size_t);
-extern void *__memmove(void *, const void *, __kernel_size_t);
+extern void *memmove(void *, const void *, __kernel_size_t) __nocapture(2);
+extern void *__memmove(void *, const void *, __kernel_size_t) __nocapture(2);
 
 #define __HAVE_ARCH_MEMCHR
 extern void *memchr(const void *, int, __kernel_size_t);
@@ -50,7 +51,7 @@ extern void *memset(void *, int, __kernel_size_t);
 extern void *__memset(void *, int, __kernel_size_t);
 
 #define __HAVE_ARCH_MEMCMP
-extern int memcmp(const void *, const void *, size_t);
+extern int memcmp(const void *, const void *, size_t) __nocapture(1, 2);
 
 
 #if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
diff --git a/arch/powerpc/include/asm/string.h 
b/arch/powerpc/include/asm/string.h
index da3cdff..e67f1eb 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -11,16 +11,17 @@
 #define __HAVE_ARCH_MEMCMP
 #define __HAVE_ARCH_MEMCHR
 
-extern char * strcpy(char *,const char *);
-extern char * strncpy(char *,const char *, __kernel_size_t);
-extern __kernel_size_t strlen(const char *);
-extern int strcmp(const char *,const char *);
-extern int strncmp(const char *, const char *, __kernel_size_t);
-extern char * strcat(char *, const char *);
+extern char * strcpy(char *,const char *) __nocapture(2);
+extern char * strncpy(char *,const char *, __kernel_size_t) __nocapture(2);
+extern __kernel_size_t strlen(const char *) __nocapture(1);
+extern int strcmp(const char *,const char *) __nocapture(1, 2);
+extern int
+strncmp(const char *, const char *, __kernel_size_t) __nocapture(1, 2);
+extern char * strcat(char *, const char *) __nocapture(2);
 extern void * memset(void *,int,__kernel_size_t);
-extern void * memcpy(void *,const void *,__kernel_size_t);
-extern void * memmove(void *,const void *,__kernel_size_t);
-extern int memcmp(const void *,const void *,__kernel_size_t);
+extern void * memcpy

[PATCH v2 3/3] Constify some function parameters

2016-07-04 Thread Emese Revfy
Initify needs const pointer types, the initify plugin caught some __printf
arguments that weren't const yet.

Signed-off-by: Emese Revfy 
---
 drivers/isdn/hisax/config.c | 4 ++--
 drivers/isdn/hisax/hisax.h  | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/isdn/hisax/config.c b/drivers/isdn/hisax/config.c
index bf04d2a..a7d53c9 100644
--- a/drivers/isdn/hisax/config.c
+++ b/drivers/isdn/hisax/config.c
@@ -659,7 +659,7 @@ int jiftime(char *s, long mark)
 
 static u_char tmpbuf[HISAX_STATUS_BUFSIZE];
 
-void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt,
+void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt,
  va_list args)
 {
/* if head == NULL the fmt contains the full info */
@@ -729,7 +729,7 @@ void VHiSax_putstatus(struct IsdnCardState *cs, char *head, 
char *fmt,
}
 }
 
-void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...)
+void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
...)
 {
va_list args;
 
diff --git a/drivers/isdn/hisax/hisax.h b/drivers/isdn/hisax/hisax.h
index 6ead6314..338d040 100644
--- a/drivers/isdn/hisax/hisax.h
+++ b/drivers/isdn/hisax/hisax.h
@@ -1288,9 +1288,9 @@ int jiftime(char *s, long mark);
 int HiSax_command(isdn_ctrl *ic);
 int HiSax_writebuf_skb(int id, int chan, int ack, struct sk_buff *skb);
 __printf(3, 4)
-void HiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, ...);
+void HiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
...);
 __printf(3, 0)
-void VHiSax_putstatus(struct IsdnCardState *cs, char *head, char *fmt, va_list 
args);
+void VHiSax_putstatus(struct IsdnCardState *cs, char *head, const char *fmt, 
va_list args);
 void HiSax_reportcard(int cardnr, int sel);
 int QuickHex(char *txt, u_char *p, int cnt);
 void LogFrame(struct IsdnCardState *cs, u_char *p, int size);
-- 
2.8.1



Re: [PATCH v1 1/3] Add the latent_entropy gcc plugin

2016-05-30 Thread Emese Revfy
On Tue, 24 May 2016 19:55:17 -0700
Kees Cook  wrote:
 
> Yeah, answering "how random is this?" is not easy, but that's not what
> I meant. I'm more curious about specific build configs or hardware
> where calling get_random_int() early enough would always produce the
> same value (or the same value across all threads, etc), and in these
> cases, the new entropy should be visible when using the latent entropy
> plugin.

I booted minimal configs (not allnoconfig because it can't boot in qemu)
many times. I couldn't produce same values.

-- 
Emese


[PATCH v2 0/3] Introduce the latent_entropy gcc plugin

2016-05-30 Thread Emese Revfy
I would like to introduce the latent_entropy gcc plugin. This plugin mitigates
the problem of the kernel having too little entropy during and after boot
for generating crypto keys.

This plugin mixes random values into the latent_entropy global variable
in functions marked by the __latent_entropy attribute.
The value of this global variable is added to the kernel entropy pool
to increase the entropy.

It is a CII project supported by the Linux Foundation.

The latent_entropy plugin was ported from grsecurity/PaX originally written by
the PaX Team. You can find more about the plugin here:
https://grsecurity.net/pipermail/grsecurity/2012-July/001093.html

The plugin supports all gcc version from 4.5 to 6.0.

I do some changes above the PaX version. The important one is mixing
the stack pointer into the global variable too.
You can find more about the changes here:
https://github.com/ephox-gcc-plugins/latent_entropy

This patch set is based on the "Introduce GCC plugin infrastructure" patch set 
(v9 next-20160520).

Emese Revfy (3):
 Add the latent_entropy gcc plugin
 Mark functions with the latent_entropy attribute
 Add the extra_latent_entropy kernel parameter


Changes from v1:
  * Remove unnecessary ifdefs
(Suggested-by: Kees Cook )
  * Separate the two definitions of add_latent_entropy()
(Suggested-by: Kees Cook )
  * Removed unnecessary global variable (latent_entropy_plugin.c)
  * About the latent_entropy gcc attribute (latent_entropy_plugin.c)
  * Measure the boot time performance impact of the latent_entropy plugin 
(arch/Kconfig)

---
 Documentation/kernel-parameters.txt |   5 +
 arch/Kconfig|  23 ++
 arch/powerpc/kernel/Makefile|   8 +-
 block/blk-softirq.c |   2 +-
 drivers/char/random.c   |   6 +-
 fs/namespace.c  |   2 +-
 include/linux/compiler-gcc.h|   5 +
 include/linux/compiler.h|   4 +
 include/linux/fdtable.h |   2 +-
 include/linux/genhd.h   |   2 +-
 include/linux/init.h|   4 +-
 include/linux/random.h  |  14 +-
 init/main.c |   1 +
 kernel/fork.c   |   5 +-
 kernel/rcu/tiny.c   |   2 +-
 kernel/rcu/tree.c   |   2 +-
 kernel/sched/fair.c |   2 +-
 kernel/softirq.c|   4 +-
 kernel/time/timer.c |   2 +-
 lib/irq_poll.c  |   2 +-
 lib/random32.c  |   2 +-
 mm/page_alloc.c |  30 ++
 net/core/dev.c  |   4 +-
 scripts/Makefile.gcc-plugins|  10 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 454 
 26 files changed, 569 insertions(+), 29 deletions(-)


[PATCH v2 1/3] Add the latent_entropy gcc plugin

2016-05-30 Thread Emese Revfy
This plugin mitigates the problem of the kernel having too little entropy during
and after boot for generating crypto keys.

It creates a local variable in every marked function. The value of this 
variable is
modified by randomly chosen operations (add, xor and rol) and
random values (gcc generates them at compile time and the stack pointer at 
runtime).
It depends on the control flow (e.g., loops, conditions).

Before the function returns the plugin writes this local variable
into the latent_entropy global variable. The value of this global variable is
added to the kernel entropy pool in do_one_initcall() and _do_fork().

Signed-off-by: Emese Revfy 
---
 arch/Kconfig|  18 ++
 arch/powerpc/kernel/Makefile|   8 +-
 include/linux/random.h  |  10 +
 init/main.c |   1 +
 kernel/fork.c   |   1 +
 mm/page_alloc.c |   5 +
 scripts/Makefile.gcc-plugins|  10 +-
 scripts/gcc-plugins/Makefile|   1 +
 scripts/gcc-plugins/latent_entropy_plugin.c | 454 
 9 files changed, 502 insertions(+), 6 deletions(-)
 create mode 100644 scripts/gcc-plugins/latent_entropy_plugin.c

diff --git a/arch/Kconfig b/arch/Kconfig
index 5feadad..7115867 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -393,6 +393,24 @@ config GCC_PLUGIN_SANCOV
  gcc-4.5 on). It is based on the commit "Add fuzzing coverage support"
  by Dmitry Vyukov .
 
+config GCC_PLUGIN_LATENT_ENTROPY
+   bool "Generate some entropy during boot and runtime"
+   depends on GCC_PLUGINS
+   help
+ By saying Y here the kernel will instrument some kernel code to
+ extract some entropy from both original and artificially created
+ program state.  This will help especially embedded systems where
+ there is little 'natural' source of entropy normally.  The cost
+ is some slowdown of the boot process (about 0.5%) and fork and
+ irq processing.
+
+ Note that entropy extracted this way is not known to be 
cryptographically
+ secure!
+
+ This plugin was ported from grsecurity/PaX. More information at:
+  * https://grsecurity.net/
+  * https://pax.grsecurity.net/
+
 config HAVE_CC_STACKPROTECTOR
bool
help
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2da380f..6c7e448 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -16,10 +16,10 @@ endif
 
 ifdef CONFIG_FUNCTION_TRACER
 # Do not trace early boot code
-CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
-CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
+CFLAGS_REMOVE_cputable.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_prom_init.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
+CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE) 
$(DISABLE_LATENT_ENTROPY_PLUGIN)
 # do not trace tracer code
 CFLAGS_REMOVE_ftrace.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
 # timers used by tracing
diff --git a/include/linux/random.h b/include/linux/random.h
index e47e533..4ea73ee 100644
--- a/include/linux/random.h
+++ b/include/linux/random.h
@@ -18,6 +18,16 @@ struct random_ready_callback {
 };
 
 extern void add_device_randomness(const void *, unsigned int);
+
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+static inline void add_latent_entropy(void)
+{
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+}
+#else
+static inline void add_latent_entropy(void) {}
+#endif
+
 extern void add_input_randomness(unsigned int type, unsigned int code,
 unsigned int value);
 extern void add_interrupt_randomness(int irq, int irq_flags);
diff --git a/init/main.c b/init/main.c
index 4c17fda..07e4174 100644
--- a/init/main.c
+++ b/init/main.c
@@ -781,6 +781,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
}
WARN(msgbuf[0], "initcall %pF returned with %s\n", fn, msgbuf);
 
+   add_latent_entropy();
return ret;
 }
 
diff --git a/kernel/fork.c b/kernel/fork.c
index cdf520f..d07d5a6 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1766,6 +1766,7 @@ long _do_fork(unsigned long clone_flags,
 
p = copy_process(clone_flags, stack_start, stack_size,
 child_tidptr, NULL, trace, tls, NUMA_NO_NODE);
+   add_latent_entropy();
/*
 * Do this prior waking up the new thread - the thread pointer
 * might get invalid after that point, if the thread exit

[PATCH v2 2/3] Mark functions with the latent_entropy attribute

2016-05-30 Thread Emese Revfy
The latent_entropy gcc attribute can be only on functions and variables.
If it is on a function then the plugin will instrument it. If the attribute
is on a variable then the plugin will initialize it with a random value.
The variable must be an integer, an integer array type or a structure with 
integer fields.

These functions have been selected because they are init functions or
are called at random times or they have variable loops.

Signed-off-by: Emese Revfy 
---
 block/blk-softirq.c  | 2 +-
 drivers/char/random.c| 6 +++---
 fs/namespace.c   | 2 +-
 include/linux/compiler-gcc.h | 5 +
 include/linux/compiler.h | 4 
 include/linux/fdtable.h  | 2 +-
 include/linux/genhd.h| 2 +-
 include/linux/init.h | 4 ++--
 include/linux/random.h   | 4 ++--
 kernel/fork.c| 4 ++--
 kernel/rcu/tiny.c| 2 +-
 kernel/rcu/tree.c| 2 +-
 kernel/sched/fair.c  | 2 +-
 kernel/softirq.c | 4 ++--
 kernel/time/timer.c  | 2 +-
 lib/irq_poll.c   | 2 +-
 lib/random32.c   | 2 +-
 mm/page_alloc.c  | 2 +-
 net/core/dev.c   | 4 ++--
 19 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/block/blk-softirq.c b/block/blk-softirq.c
index 53b1737..489eab8 100644
--- a/block/blk-softirq.c
+++ b/block/blk-softirq.c
@@ -18,7 +18,7 @@ static DEFINE_PER_CPU(struct list_head, blk_cpu_done);
  * Softirq action handler - move entries to local list and loop over them
  * while passing them to the queue registered handler.
  */
-static void blk_done_softirq(struct softirq_action *h)
+static __latent_entropy void blk_done_softirq(struct softirq_action *h)
 {
struct list_head *cpu_list, local_list;
 
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 0158d3b..6cca3ed 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -443,9 +443,9 @@ struct entropy_store {
 };
 
 static void push_to_pool(struct work_struct *work);
-static __u32 input_pool_data[INPUT_POOL_WORDS];
-static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
-static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
+static __u32 input_pool_data[INPUT_POOL_WORDS] __latent_entropy;
+static __u32 blocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
+static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS] __latent_entropy;
 
 static struct entropy_store input_pool = {
.poolinfo = &poolinfo_table[0],
diff --git a/fs/namespace.c b/fs/namespace.c
index 4fb1691..eed930c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2778,7 +2778,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct 
user_namespace *user_ns)
return new_ns;
 }
 
-struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace 
*ns,
+__latent_entropy struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct 
mnt_namespace *ns,
struct user_namespace *user_ns, struct fs_struct *new_fs)
 {
struct mnt_namespace *new_ns;
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index e294939..8d85907 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -188,6 +188,11 @@
 #endif /* GCC_VERSION >= 40300 */
 
 #if GCC_VERSION >= 40500
+
+#ifdef LATENT_ENTROPY_PLUGIN
+#define __latent_entropy __attribute__((latent_entropy))
+#endif
+
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 793c082..c65327b 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -425,6 +425,10 @@ static __always_inline void __write_once_size(volatile 
void *p, void *res, int s
 # define __attribute_const__   /* unimplemented */
 #endif
 
+#ifndef __latent_entropy
+# define __latent_entropy
+#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/fdtable.h b/include/linux/fdtable.h
index 5295535..9852c7e 100644
--- a/include/linux/fdtable.h
+++ b/include/linux/fdtable.h
@@ -105,7 +105,7 @@ struct files_struct *get_files_struct(struct task_struct *);
 void put_files_struct(struct files_struct *fs);
 void reset_files_struct(struct files_struct *);
 int unshare_files(struct files_struct **);
-struct files_struct *dup_fd(struct files_struct *, int *);
+struct files_struct *dup_fd(struct files_struct *, int *) __latent_entropy;
 void do_close_on_exec(struct files_struct *);
 int iterate_fd(struct files_struct *, unsigned,
int (*)(const void *, struct file *, unsigned),
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index 359a8e4..8736c1f 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -433,7 +433,7 @@ extern void disk_flush_events(struct gendisk *disk, 
unsigned int mask);
 extern unsigned int disk_clear_events(struct gendisk *disk

[PATCH v2 3/3] Add the extra_latent_entropy kernel parameter

2016-05-30 Thread Emese Revfy
When extra_latent_entropy is passed on the kernel command line,
entropy will be extracted from up to the first 4GB of RAM while the
runtime memory allocator is being initialized.

Based on work created by the PaX Team.

Signed-off-by: Emese Revfy 
---
 Documentation/kernel-parameters.txt |  5 +
 arch/Kconfig|  5 +
 mm/page_alloc.c | 25 +
 3 files changed, 35 insertions(+)

diff --git a/Documentation/kernel-parameters.txt 
b/Documentation/kernel-parameters.txt
index 5349363..6c2496e 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -2862,6 +2862,11 @@ bytes respectively. Such letter suffixes can also be 
entirely omitted.
the specified number of seconds.  This is to be used if
your oopses keep scrolling off the screen.
 
+   extra_latent_entropy
+   Enable a very simple form of latent entropy extraction
+   from the first 4GB of memory as the bootmem allocator
+   passes the memory pages to the buddy allocator.
+
pcbit=  [HW,ISDN]
 
pcd.[PARIDE]
diff --git a/arch/Kconfig b/arch/Kconfig
index 7115867..cbfa8d3 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -404,6 +404,11 @@ config GCC_PLUGIN_LATENT_ENTROPY
  is some slowdown of the boot process (about 0.5%) and fork and
  irq processing.
 
+ When extra_latent_entropy is passed on the kernel command line,
+ entropy will be extracted from up to the first 4GB of RAM while the
+ runtime memory allocator is being initialized.  This costs even more
+ slowdown of the boot process.
+
  Note that entropy extracted this way is not known to be 
cryptographically
  secure!
 
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index ffc4f4a..72c61bd 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -63,6 +63,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -1234,6 +1235,15 @@ static void __free_pages_ok(struct page *page, unsigned 
int order)
local_irq_restore(flags);
 }
 
+bool __meminitdata extra_latent_entropy;
+
+static int __init setup_extra_latent_entropy(char *str)
+{
+   extra_latent_entropy = true;
+   return 0;
+}
+early_param("extra_latent_entropy", setup_extra_latent_entropy);
+
 #ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
 volatile u64 latent_entropy __latent_entropy;
 EXPORT_SYMBOL(latent_entropy);
@@ -1254,6 +1264,21 @@ static void __init __free_pages_boot_core(struct page 
*page, unsigned int order)
__ClearPageReserved(p);
set_page_count(p, 0);
 
+   if (extra_latent_entropy && !PageHighMem(page) && page_to_pfn(page) < 
0x10) {
+   u64 hash = 0;
+   size_t index, end = PAGE_SIZE * nr_pages / sizeof hash;
+   const u64 *data = lowmem_page_address(page);
+
+   for (index = 0; index < end; index++)
+   hash ^= hash + data[index];
+#ifdef CONFIG_GCC_PLUGIN_LATENT_ENTROPY
+   latent_entropy ^= hash;
+   add_device_randomness((const void *)&latent_entropy, 
sizeof(latent_entropy));
+#else
+   add_device_randomness((const void *)&hash, sizeof(hash));
+#endif
+   }
+
page_zone(page)->managed_pages += nr_pages;
set_page_refcounted(page);
__free_pages(page, order);
-- 
2.8.1



Re: [PATCH] gcc-plugin: include memmodel.h and tree_vrp.h for gcc-7

2016-12-16 Thread Emese Revfy
On Fri, 16 Dec 2016 10:00:22 +0100
Arnd Bergmann  wrote:

> Cc: sta...@vger.kernel.org
> Suggested-by: Kugan 
> Signed-off-by: Arnd Bergmann 
> ---
>  scripts/gcc-plugins/gcc-common.h | 6 ++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/scripts/gcc-plugins/gcc-common.h 
> b/scripts/gcc-plugins/gcc-common.h
> index 950fd2e64bb7..cb4a9518b58a 100644
> --- a/scripts/gcc-plugins/gcc-common.h
> +++ b/scripts/gcc-plugins/gcc-common.h
> @@ -18,6 +18,9 @@
>  
>  #include "tree-inline.h"
>  #include "version.h"
> +#if BUILDING_GCC_VERSION >= 7000
> +#include "memmodel.h"
> +#endif
>  #include "rtl.h"
>  #include "tm_p.h"
>  #include "flags.h"
> @@ -66,6 +69,9 @@
>  #include "tree-flow.h"
>  #else
>  #include "tree-cfgcleanup.h"
> +#if BUILDING_GCC_VERSION >= 7000
> +#include "tree-vrp.h"
> +#endif
>  #include "tree-ssa-operands.h"
>  #include "tree-into-ssa.h"
>  #endif
 
Hi,

Could you please use the upstream gcc-common.h? You can find it here:
https://www.grsecurity.net/~paxguy1/gcc-common.h

Thanks
-- 
Emese


Re: [PATCH v4 0/4] Introduce the initify gcc plugin

2016-12-19 Thread Emese Revfy
On Fri, 16 Dec 2016 14:19:10 -0800
Kees Cook  wrote:
 
> FWIW, it still seems to me that these aren't false positives:
> 
> WARNING: vmlinux.o(.text.unlikely+0x1b1): Section mismatch in
> reference from the function uncore_pci_exit.part.22() to the function
> .init.text:uncore_free_pcibus_map()
> The function uncore_pci_exit.part.22() references
> the function __init uncore_free_pcibus_map().
> This is often because uncore_pci_exit.part.22 lacks a __init
> annotation or the annotation of uncore_free_pcibus_map is wrong.

Hi,

I can't reproduce this section mismatch. Could you please send me your .config?
Which gcc version did you use?
I used this tree: git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git 
initify-v4

Thanks
-- 
Emese


Re: enabling COMPILE_TEST support for GCC plugins in v4.11

2016-12-10 Thread Emese Revfy
On Fri, 9 Dec 2016 11:12:18 -0800
Kees Cook  wrote:

> On Fri, Dec 9, 2016 at 2:40 AM, Arnd Bergmann  wrote:
> > On Thursday, December 8, 2016 11:00:42 AM CET Kees Cook wrote:
> >
> >> If you have a moment, applying 215e2aa6c024[1] and reverting
> >> a519167e753e for an allyesconfig/allmodconfig build should let you
> >> know if things are working correctly with headers installed. If anyone
> >> sees any problems, please let me know and I can queue up fixes.
> >
> > Using gcc-4.9.3 or gcc-5.3.1 for an ARM allmodconfig build, I get tons of
> > errors such as this one:
> >
> > /git/arm-soc/init/initramfs.c: In function 'error':
> > /git/arm-soc/init/initramfs.c:50:1: error: unrecognizable insn:
> >  }
> >  ^
> > (insn 26 25 27 5 (set (reg:SI 111 [ local_entropy.243 ])
> > (rotatert:SI (reg:SI 116 [ local_entropy.243 ])
> > (const_int -30 [0xffe2]))) -1
> >  (nil))
> > *** WARNING *** there are active plugins, do not report this as a bug 
> > unless you can reproduce it without enabling any plugins.
> > Event| Plugins
> > PLUGIN_ATTRIBUTES| latent_entropy_plugin
> > PLUGIN_START_UNIT| latent_entropy_plugin
> > /git/arm-soc/init/initramfs.c:50:1: internal compiler error: in 
> > extract_insn, at recog.c:2202
> > /git/arm-soc/arch/arm/vfp/vfpmodule.c: In function 'vfp_init':
> > /git/arm-soc/arch/arm/vfp/vfpmodule.c:824:1: error: unrecognizable insn:
> >  }
> >  ^
> > (insn 138 137 139 17 (set (reg:SI 165 [ local_entropy.93 ])
> > (rotatert:SI (reg:SI 150 [ local_entropy.93 ])
> > (const_int -9 [0xfff7]))) -1
> >  (nil))
> > *** WARNING *** there are active plugins, do not report this as a bug 
> > unless you can reproduce it without enabling any plugins.
> 
> Well that's exciting! :P

Hi,

You can find the fix here:
https://github.com/ephox-gcc-plugins/latent_entropy/commit/c91275a1bfcebbcfc0ca1af03396e06039f04db8

-- 
Emese


Re: scripts/gcc-plugins/gcc-common.h:4:22: fatal error: bversion.h: No such file or directory

2016-11-06 Thread Emese Revfy
On Sun, 6 Nov 2016 07:09:57 +0800
kbuild test robot  wrote:

> Hi Emese,
> 
> FYI, the error/warning still remains.
>
>++(scripts/gcc-plugin.sh:12): main(): gcc-4.6 -E -x c++ - -o /dev/null 
> -Iscripts/gcc-plugins -Iplugin/include
>scripts/Makefile.gcc-plugins:30: warning: your gcc installation does not 
> support plugins, perhaps the necessary headers are missing?

Hi,

You should install the gcc-4.6 plugin headers (gcc-4.6-plugin-dev package on 
debian if I remember well) for the plugins.

-- 
Emese


Re: [PATCH v4 0/4] Introduce the initify gcc plugin

2017-02-14 Thread Emese Revfy
On Thu, 12 Jan 2017 15:40:41 -0800
Kees Cook  wrote:

> WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in
> reference from the function clk_gate() to the variable
> .init.rodata.str:__func__.29708
> The function clk_gate() references
> the variable __initconst __func__.29708.
> This is often because clk_gate lacks a __initconst
> annotation or the annotation of __func__.29708 is wrong.

Thanks for the report, it will be fixed in the next grsec patch.

-- 
Emese


Re: [PATCH v4 0/4] Introduce the initify gcc plugin

2017-02-20 Thread Emese Revfy
On Wed, 15 Feb 2017 11:27:06 -0800
Kees Cook  wrote:

> On Tue, Feb 14, 2017 at 4:23 PM, Emese Revfy  wrote:
> > On Thu, 12 Jan 2017 15:40:41 -0800
> > Kees Cook  wrote:
> >
> >> WARNING: drivers/clk/bcm/built-in.o(.text+0xec2): Section mismatch in
> >> reference from the function clk_gate() to the variable
> >> .init.rodata.str:__func__.29708
> >> The function clk_gate() references
> >> the variable __initconst __func__.29708.
> >> This is often because clk_gate lacks a __initconst
> >> annotation or the annotation of __func__.29708 is wrong.
> >
> > Thanks for the report, it will be fixed in the next grsec patch.
> 
> Very cool, thanks! What did the problem turn out to be?

You can find it here:
https://github.com/ephox-gcc-plugins/initify/commit/73e857aa47bde7cc78ed865a008d1519893c0f54

-- 
Emese


Re: [PATCH v4 0/4] Introduce the initify gcc plugin

2017-01-10 Thread Emese Revfy
On Tue, 3 Jan 2017 16:23:03 -0800
Kees Cook  wrote:

> On Mon, Dec 19, 2016 at 3:10 AM, Emese Revfy  wrote:
> > On Fri, 16 Dec 2016 14:19:10 -0800
> > Kees Cook  wrote:
> >
> >> FWIW, it still seems to me that these aren't false positives:
> >>
> >> WARNING: vmlinux.o(.text.unlikely+0x1b1): Section mismatch in
> >> reference from the function uncore_pci_exit.part.22() to the function
> >> .init.text:uncore_free_pcibus_map()
> >> The function uncore_pci_exit.part.22() references
> >> the function __init uncore_free_pcibus_map().
> >> This is often because uncore_pci_exit.part.22 lacks a __init
> >> annotation or the annotation of uncore_free_pcibus_map is wrong.

Thanks for the report, you can find the fix here:
https://github.com/ephox-gcc-plugins/initify/commit/5d93a54badd9751b79ef67ce8a8b4081fea37547

-- 
Emese


Re: [PATCH v4 0/4] Introduce the initify gcc plugin

2017-01-12 Thread Emese Revfy
On Tue, 10 Jan 2017 17:09:31 -0800
Kees Cook  wrote:

> WARNING: vmlinux.o(.text+0x1087e7): Section mismatch in reference from
> the function rebind_subsystems() to the variable
> .init.rodata.str:__func__.4400
> The function rebind_subsystems() references
> the variable __initconst __func__.4400.
> This is often because rebind_subsystems lacks a __initconst
> annotation or the annotation of __func__.4400 is wrong.

Thanks for the report, you can find the fix here:
https://github.com/ephox-gcc-plugins/initify/commit/25f34834e3373e067133bc5d39d42c50a3592d56
 
-- 
Emese


  1   2   >