Follow @Openwall on Twitter for new release announcements and other news
[<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: [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
>

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.