[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CA+rthh9QuQ-V+=Of8GB-SwqX-Z8SUEz48YLyBfbng5j3wd23Jw@mail.gmail.com>
Date: Fri, 26 Apr 2013 08:13:53 +0200
From: Mathias Krause <minipli@...glemail.com>
To: Kees Cook <keescook@...omium.org>
Cc: "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
kernel-hardening@...ts.openwall.com,
"H. Peter Anvin" <hpa@...or.com>,
Thomas Gleixner <tglx@...utronix.de>,
Ingo Molnar <mingo@...hat.com>, x86@...nel.org,
Jarkko Sakkinen <jarkko.sakkinen@...el.com>,
Matthew Garrett <mjg@...hat.com>,
Matt Fleming <matt.fleming@...el.com>,
Eric Northup <digitaleric@...gle.com>,
Dan Rosenberg <drosenberg@...curity.com>,
Julien Tinnes <jln@...gle.com>, Will Drewry <wad@...omium.org>
Subject: Re: [kernel-hardening] [PATCH 4/6] x86: kaslr: select random base offset
On Thu, Apr 25, 2013 at 11:54 PM, Kees Cook <keescook@...omium.org> wrote:
> Select a random location when CONFIG_RANDOMIZE_BASE is used, bounded
> by CONFIG_RANDOMIZE_BASE_MAX_OFFSET. Sources of randomness currently
> include RDRAND and RDTSC.
>
> Signed-off-by: Kees Cook <keescook@...omium.org>
> ---
> arch/x86/Kconfig | 29 +++++++++++++--
> arch/x86/boot/compressed/aslr.c | 75 +++++++++++++++++++++++++++++++++++++--
> 2 files changed, 100 insertions(+), 4 deletions(-)
>
> [snip]
>
> diff --git a/arch/x86/boot/compressed/aslr.c b/arch/x86/boot/compressed/aslr.c
> index d5331ee..11a91c6 100644
> --- a/arch/x86/boot/compressed/aslr.c
> +++ b/arch/x86/boot/compressed/aslr.c
> @@ -2,18 +2,89 @@
>
> #ifdef CONFIG_RANDOMIZE_BASE
>
> +#include <asm/archrandom.h>
> +static inline int rdrand(unsigned long *v)
> +{
> + int ok;
> + asm volatile("1: " RDRAND_LONG "\n\t"
> + "jc 2f\n\t"
> + "decl %0\n\t"
> + "jnz 1b\n\t"
> + "2:"
> + : "=r" (ok), "=a" (*v)
> + : "0" (RDRAND_RETRY_LOOPS));
> + return ok;
> +}
> +
> +static inline uint32_t rdtsc(void)
> +{
> + uint32_t timer;
> +
> + asm volatile("rdtsc\n" : "=a" (timer));
'\n' in the assembly statement is not needed. Also, RDTSC trashes
edx/rdx as well so it should be mentioned in the clobber list, at
least.
Maybe using rdtscl() from <asm/msr.h> instead is an option?
> +
> + return timer;
> +}
> +
> +static unsigned long get_random_long(void)
> +{
> + if (has_cpuflag(X86_FEATURE_RDRAND)) {
> + unsigned long random;
> +
> + debug_putstr("KASLR using RDRAND...\n");
> + if (rdrand(&random))
> + return random;
> + }
> +
> + if (has_cpuflag(X86_FEATURE_TSC)) {
> + uint32_t raw;
> + unsigned long timer;
> +
> + debug_putstr("KASLR using RDTSC...\n");
> + raw = rdtsc();
> +
> + /* Repeat the low bits of rdtsc. */
> + timer = raw & 0xffff;
> + timer |= (timer << 16);
> +#ifdef CONFIG_X86_64
> + timer |= (timer << 32) | (timer << 48);
> +#endif
> +
> + return timer;
> + }
> +
> + debug_putstr("KASLR found no entropy source...\n");
> + return 0;
> +}
> +
> unsigned char *choose_kernel_location(unsigned char *hint, unsigned long size)
> {
> unsigned char *choice = hint;
> - unsigned long random;
> + unsigned long random, mask;
>
> if (cmdline_find_option_bool("noaslr")) {
> debug_putstr("KASLR disabled...\n");
> goto out;
> }
>
> - /* XXX: choose random location. */
> + random = get_random_long();
> +
> + /* Clip off top of the range. */
> + mask = CONFIG_RANDOMIZE_BASE_MAX_OFFSET - 1;
> + random &= mask;
> +
> + /* XXX: Find an appropriate E820 hole, instead of adding hint. */
> + random += (unsigned long)hint;
> +
> + /* XXX: Clip to E820 hole, instead of just using hint. */
> + mask = (unsigned long)hint + CONFIG_RANDOMIZE_BASE_MAX_OFFSET;
> + while (random + size > mask)
> + random >>= 1;
> +
> + /* Clip off bottom of range (via alignment). */
> + mask = CONFIG_PHYSICAL_ALIGN - 1;
> + random &= ~mask;
>
> + choice = (unsigned char *)random;
> out:
> return choice;
> }
> --
> 1.7.9.5
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists