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

2016-06-21 Thread Kees Cook
On Tue, Jun 21, 2016 at 5:58 AM, Christoph Hellwig  wrote:
> On Mon, Jun 20, 2016 at 08:41:19PM +0200, Emese Revfy wrote:
>> --- /dev/null
>> +++ b/scripts/gcc-plugins/latent_entropy_plugin.c
>> @@ -0,0 +1,639 @@
>> +/*
>> + * Copyright 2012-2016 by the PaX Team 
>> + * Copyright 2016 by Emese Revfy 
>> + * Licensed under the GPL v2
>> + *
>> + * Note: the choice of the license means that the compilation process is
>> + *   NOT 'eligible' as defined by gcc's library exception to the GPL v3,
>> + *   but for the kernel it doesn't matter since it doesn't link against
>> + *   any of the gcc libraries
>
> I remember we used to have architectures that actually linked against
> libgcc.  Isn't that the case anymore?

There are a few, but they don't (and won't) select HAVE_GCC_PLUGINS.

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security


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

2016-06-21 Thread Kees Cook
On Tue, Jun 21, 2016 at 5:58 AM, Christoph Hellwig  wrote:
> On Mon, Jun 20, 2016 at 08:41:19PM +0200, Emese Revfy wrote:
>> --- /dev/null
>> +++ b/scripts/gcc-plugins/latent_entropy_plugin.c
>> @@ -0,0 +1,639 @@
>> +/*
>> + * Copyright 2012-2016 by the PaX Team 
>> + * Copyright 2016 by Emese Revfy 
>> + * Licensed under the GPL v2
>> + *
>> + * Note: the choice of the license means that the compilation process is
>> + *   NOT 'eligible' as defined by gcc's library exception to the GPL v3,
>> + *   but for the kernel it doesn't matter since it doesn't link against
>> + *   any of the gcc libraries
>
> I remember we used to have architectures that actually linked against
> libgcc.  Isn't that the case anymore?

There are a few, but they don't (and won't) select HAVE_GCC_PLUGINS.

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security


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

2016-06-21 Thread Christoph Hellwig
On Mon, Jun 20, 2016 at 08:41:19PM +0200, Emese Revfy wrote:
> --- /dev/null
> +++ b/scripts/gcc-plugins/latent_entropy_plugin.c
> @@ -0,0 +1,639 @@
> +/*
> + * Copyright 2012-2016 by the PaX Team 
> + * Copyright 2016 by Emese Revfy 
> + * Licensed under the GPL v2
> + *
> + * Note: the choice of the license means that the compilation process is
> + *   NOT 'eligible' as defined by gcc's library exception to the GPL v3,
> + *   but for the kernel it doesn't matter since it doesn't link against
> + *   any of the gcc libraries

I remember we used to have architectures that actually linked against
libgcc.  Isn't that the case anymore?


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

2016-06-21 Thread Christoph Hellwig
On Mon, Jun 20, 2016 at 08:41:19PM +0200, Emese Revfy wrote:
> --- /dev/null
> +++ b/scripts/gcc-plugins/latent_entropy_plugin.c
> @@ -0,0 +1,639 @@
> +/*
> + * Copyright 2012-2016 by the PaX Team 
> + * Copyright 2016 by Emese Revfy 
> + * Licensed under the GPL v2
> + *
> + * Note: the choice of the license means that the compilation process is
> + *   NOT 'eligible' as defined by gcc's library exception to the GPL v3,
> + *   but for the kernel it doesn't matter since it doesn't link against
> + *   any of the gcc libraries

I remember we used to have architectures that actually linked against
libgcc.  Isn't that the case anymore?


[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 *)_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
+
 static void 

[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 *)_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
+
 static void __init __free_pages_boot_core(struct page