Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1393764 > unrolled thread

[PATCH v3 0/4] x86, boot: KASLR memory randomization

Started byThomas Garnier <thgarnie@google.com>
First post2016-05-03 21:40 +0200
Last post2016-05-10 20:50 +0200
Articles 5 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 0/4] x86, boot: KASLR memory randomization Thomas Garnier <thgarnie@google.com> - 2016-05-03 21:40 +0200
    [PATCH v3 2/4] x86, boot: PUD VA support for physical mapping (x86_64) Thomas Garnier <thgarnie@google.com> - 2016-05-03 21:40 +0200
    [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization Thomas Garnier <thgarnie@google.com> - 2016-05-03 21:40 +0200
      Re: [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization Kees Cook <keescook@chromium.org> - 2016-05-10 20:30 +0200
        Re: [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization Thomas Garnier <thgarnie@google.com> - 2016-05-10 20:50 +0200

#1393764 — [PATCH v3 0/4] x86, boot: KASLR memory randomization

FromThomas Garnier <thgarnie@google.com>
Date2016-05-03 21:40 +0200
Subject[PATCH v3 0/4] x86, boot: KASLR memory randomization
Message-ID<ruOkN-5Mr-3@gated-at.bofh.it>
This is PATCH v3 for KASLR memory implementation for x86_64.

Recent changes:
    Add performance information on commit.
    Add details on PUD alignment.
    Add information on testing against the KASLR bypass exploit.
    Rebase on next-20160502.

***Background:
The current implementation of KASLR randomizes only the base address of
the kernel and its modules. Research was published showing that static
memory can be overwitten to elevate privileges bypassing KASLR.

In more details:

   The physical memory mapping holds most allocations from boot and heap
   allocators. Knowning the base address and physical memory size, an
   attacker can deduce the PDE virtual address for the vDSO memory page.
   This attack was demonstrated at CanSecWest 2016, in the "Getting
   Physical Extreme Abuse of Intel Based Paged Systems"
   https://goo.gl/ANpWdV (see second part of the presentation). The
   exploits used against Linux worked successfuly against 4.6+ but fail
   with KASLR memory enabled (https://goo.gl/iTtXMJ). Similar research
   was done at Google leading to this patch proposal. Variants exists to
   overwrite /proc or /sys objects ACLs leading to elevation of privileges.
   These variants were testeda against 4.6+.

This set of patches randomizes base address and padding of three
major memory sections (physical memory mapping, vmalloc & vmemmap).
It mitigates exploits relying on predictable kernel addresses. This
feature can be enabled with the CONFIG_RANDOMIZE_MEMORY option.

Padding for the memory hotplug support is managed by
CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING. The default value is 10
terabytes.

The patches were tested on qemu & physical machines. Xen compatibility was
also verified. Multiple reboots were used to verify entropy for each
memory section.

***Problems that needed solving:
 - The three target memory sections are never at the same place between
   boots.
 - The physical memory mapping can use a virtual address not aligned on
   the PGD page table.
 - Have good entropy early at boot before get_random_bytes is available.
 - Add optional padding for memory hotplug compatibility.

***Parts:
 - The first part prepares for the KASLR memory randomization by
   refactoring entropy functions used by the current implementation and
   support PUD level virtual addresses for physical mapping.
   (Patches 01-02)
 - The second part implements the KASLR memory randomization for all
   sections mentioned.
   (Patch 03)
 - The third part adds support for memory hotplug by adding an option to
   define the padding used between the physical memory mapping section
   and the others.
   (Patch 04)

Performance data:

Kernbench shows almost no difference (-+ less than 1%):

Before:

Average Optimal load -j 12 Run (std deviation):
Elapsed Time 102.63 (1.2695)
User Time 1034.89 (1.18115)
System Time 87.056 (0.456416)
Percent CPU 1092.9 (13.892)
Context Switches 199805 (3455.33)
Sleeps 97907.8 (900.636)

After:

Average Optimal load -j 12 Run (std deviation):
Elapsed Time 102.489 (1.10636)
User Time 1034.86 (1.36053)
System Time 87.764 (0.49345)
Percent CPU 1095 (12.7715)
Context Switches 199036 (4298.1)
Sleeps 97681.6 (1031.11)

Hackbench shows 0% difference on average (hackbench 90
repeated 10 times):

attemp,before,after
1,0.076,0.069
2,0.072,0.069
3,0.066,0.066
4,0.066,0.068
5,0.066,0.067
6,0.066,0.069
7,0.067,0.066
8,0.063,0.067
9,0.067,0.065
10,0.068,0.071
average,0.0677,0.0677

Thanks!

[toc] | [next] | [standalone]


#1393765 — [PATCH v3 2/4] x86, boot: PUD VA support for physical mapping (x86_64)

FromThomas Garnier <thgarnie@google.com>
Date2016-05-03 21:40 +0200
Subject[PATCH v3 2/4] x86, boot: PUD VA support for physical mapping (x86_64)
Message-ID<ruOkO-5Mr-17@gated-at.bofh.it>
In reply to#1393764
Minor change that allows early boot physical mapping of PUD level virtual
addresses. The current implementation expect the virtual address to be
PUD aligned. For KASLR memory randomization, we need to be able to
randomize the offset used on the PUD table.

It has no impact on current usage.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20160502
---
 arch/x86/mm/init_64.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 89d9747..6adfbce 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -526,10 +526,10 @@ phys_pud_init(pud_t *pud_page, unsigned long addr, unsigned long end,
 {
 	unsigned long pages = 0, next;
 	unsigned long last_map_addr = end;
-	int i = pud_index(addr);
+	int i = pud_index((unsigned long)__va(addr));
 
 	for (; i < PTRS_PER_PUD; i++, addr = next) {
-		pud_t *pud = pud_page + pud_index(addr);
+		pud_t *pud = pud_page + pud_index((unsigned long)__va(addr));
 		pmd_t *pmd;
 		pgprot_t prot = PAGE_KERNEL;
 
-- 
2.8.0.rc3.226.g39d4020

[toc] | [prev] | [next] | [standalone]


#1393769 — [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization

FromThomas Garnier <thgarnie@google.com>
Date2016-05-03 21:40 +0200
Subject[PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization
Message-ID<ruOkO-5Mr-29@gated-at.bofh.it>
In reply to#1393764
Add a new option (CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING) to define
the padding used for the physical memory mapping section when KASLR
memory is enabled. It ensures there is enough virtual address space when
CONFIG_MEMORY_HOTPLUG is used. The default value is 10 terabytes. If
CONFIG_MEMORY_HOTPLUG is not used, no space is reserved increasing the
entropy available.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20160502
---
 arch/x86/Kconfig    | 15 +++++++++++++++
 arch/x86/mm/kaslr.c | 14 ++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 60f33c7..5124d9c 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2003,6 +2003,21 @@ config RANDOMIZE_MEMORY
 
 	   If unsure, say N.
 
+config RANDOMIZE_MEMORY_PHYSICAL_PADDING
+	hex "Physical memory mapping padding" if EXPERT
+	depends on RANDOMIZE_MEMORY
+	default "0xa" if MEMORY_HOTPLUG
+	default "0x0"
+	range 0x1 0x40 if MEMORY_HOTPLUG
+	range 0x0 0x40
+	---help---
+	   Define the padding in terabyte added to the existing physical memory
+	   size during kernel memory randomization. It is useful for memory
+	   hotplug support but reduces the entropy available for address
+	   randomization.
+
+	   If unsure, leave at the default value.
+
 config HOTPLUG_CPU
 	bool "Support for hot-pluggable CPUs"
 	depends on SMP
diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
index 3b330a9..ef3dc19 100644
--- a/arch/x86/mm/kaslr.c
+++ b/arch/x86/mm/kaslr.c
@@ -68,15 +68,25 @@ void __init kernel_randomize_memory(void)
 {
 	size_t i;
 	unsigned long addr = memory_rand_start;
-	unsigned long padding, rand, mem_tb;
+	unsigned long padding, rand, mem_tb, page_offset_padding;
 	struct rnd_state rnd_st;
 	unsigned long remain_padding = memory_rand_end - memory_rand_start;
 
 	if (!kaslr_enabled())
 		return;
 
+	/*
+	 * Update Physical memory mapping to available and
+	 * add padding if needed (especially for memory hotplug support).
+	 */
+	page_offset_padding = CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
+
+#ifdef CONFIG_MEMORY_HOTPLUG
+	page_offset_padding = max(1UL, page_offset_padding);
+#endif
+
 	BUG_ON(kaslr_regions[0].base != &page_offset_base);
-	mem_tb = ((max_pfn << PAGE_SHIFT) >> TB_SHIFT);
+	mem_tb = ((max_pfn << PAGE_SHIFT) >> TB_SHIFT) + page_offset_padding;
 
 	if (mem_tb < kaslr_regions[0].size_tb)
 		kaslr_regions[0].size_tb = mem_tb;
-- 
2.8.0.rc3.226.g39d4020

[toc] | [prev] | [next] | [standalone]


#1398385 — Re: [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization

FromKees Cook <keescook@chromium.org>
Date2016-05-10 20:30 +0200
SubjectRe: [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization
Message-ID<rxkzU-8dm-25@gated-at.bofh.it>
In reply to#1393769
On Tue, May 3, 2016 at 12:31 PM, Thomas Garnier <thgarnie@google.com> wrote:
> Add a new option (CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING) to define
> the padding used for the physical memory mapping section when KASLR
> memory is enabled. It ensures there is enough virtual address space when
> CONFIG_MEMORY_HOTPLUG is used. The default value is 10 terabytes. If
> CONFIG_MEMORY_HOTPLUG is not used, no space is reserved increasing the
> entropy available.
>
> Signed-off-by: Thomas Garnier <thgarnie@google.com>
> ---
> Based on next-20160502
> ---
>  arch/x86/Kconfig    | 15 +++++++++++++++
>  arch/x86/mm/kaslr.c | 14 ++++++++++++--
>  2 files changed, 27 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
> index 60f33c7..5124d9c 100644
> --- a/arch/x86/Kconfig
> +++ b/arch/x86/Kconfig
> @@ -2003,6 +2003,21 @@ config RANDOMIZE_MEMORY
>
>            If unsure, say N.
>
> +config RANDOMIZE_MEMORY_PHYSICAL_PADDING
> +       hex "Physical memory mapping padding" if EXPERT
> +       depends on RANDOMIZE_MEMORY
> +       default "0xa" if MEMORY_HOTPLUG
> +       default "0x0"
> +       range 0x1 0x40 if MEMORY_HOTPLUG
> +       range 0x0 0x40
> +       ---help---
> +          Define the padding in terabyte added to the existing physical memory
> +          size during kernel memory randomization. It is useful for memory
> +          hotplug support but reduces the entropy available for address
> +          randomization.
> +
> +          If unsure, leave at the default value.
> +
>  config HOTPLUG_CPU
>         bool "Support for hot-pluggable CPUs"
>         depends on SMP
> diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
> index 3b330a9..ef3dc19 100644
> --- a/arch/x86/mm/kaslr.c
> +++ b/arch/x86/mm/kaslr.c
> @@ -68,15 +68,25 @@ void __init kernel_randomize_memory(void)
>  {
>         size_t i;
>         unsigned long addr = memory_rand_start;
> -       unsigned long padding, rand, mem_tb;
> +       unsigned long padding, rand, mem_tb, page_offset_padding;
>         struct rnd_state rnd_st;
>         unsigned long remain_padding = memory_rand_end - memory_rand_start;
>
>         if (!kaslr_enabled())
>                 return;
>
> +       /*
> +        * Update Physical memory mapping to available and
> +        * add padding if needed (especially for memory hotplug support).
> +        */
> +       page_offset_padding = CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
> +
> +#ifdef CONFIG_MEMORY_HOTPLUG
> +       page_offset_padding = max(1UL, page_offset_padding);
> +#endif

Can't the ifdef and max lines be dropped? The Kconfig already enforces
the range to have a minimum of 1 when CONFIG_MEMORY_HOTPLUG is used,
IIUC.

> +
>         BUG_ON(kaslr_regions[0].base != &page_offset_base);
> -       mem_tb = ((max_pfn << PAGE_SHIFT) >> TB_SHIFT);
> +       mem_tb = ((max_pfn << PAGE_SHIFT) >> TB_SHIFT) + page_offset_padding;

In fact, can't this variable be entirely dropped and the mem_tb
calculation could just refer to RANDOMIZE_MEMORY_PHYSICAL_PADDING
directly?

-Kees

>
>         if (mem_tb < kaslr_regions[0].size_tb)
>                 kaslr_regions[0].size_tb = mem_tb;
> --
> 2.8.0.rc3.226.g39d4020
>



-- 
Kees Cook
Chrome OS & Brillo Security

[toc] | [prev] | [next] | [standalone]


#1398397 — Re: [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization

FromThomas Garnier <thgarnie@google.com>
Date2016-05-10 20:50 +0200
SubjectRe: [PATCH v3 4/4] x86, boot: Memory hotplug support for KASLR memory randomization
Message-ID<rxkTg-8nX-21@gated-at.bofh.it>
In reply to#1398385
On Tue, May 10, 2016 at 11:24 AM, Kees Cook <keescook@chromium.org> wrote:
> On Tue, May 3, 2016 at 12:31 PM, Thomas Garnier <thgarnie@google.com> wrote:
>> Add a new option (CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING) to define
>> the padding used for the physical memory mapping section when KASLR
>> memory is enabled. It ensures there is enough virtual address space when
>> CONFIG_MEMORY_HOTPLUG is used. The default value is 10 terabytes. If
>> CONFIG_MEMORY_HOTPLUG is not used, no space is reserved increasing the
>> entropy available.
>>
>> Signed-off-by: Thomas Garnier <thgarnie@google.com>
>> ---
>> Based on next-20160502
>> ---
>>  arch/x86/Kconfig    | 15 +++++++++++++++
>>  arch/x86/mm/kaslr.c | 14 ++++++++++++--
>>  2 files changed, 27 insertions(+), 2 deletions(-)
>>
>> diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
>> index 60f33c7..5124d9c 100644
>> --- a/arch/x86/Kconfig
>> +++ b/arch/x86/Kconfig
>> @@ -2003,6 +2003,21 @@ config RANDOMIZE_MEMORY
>>
>>            If unsure, say N.
>>
>> +config RANDOMIZE_MEMORY_PHYSICAL_PADDING
>> +       hex "Physical memory mapping padding" if EXPERT
>> +       depends on RANDOMIZE_MEMORY
>> +       default "0xa" if MEMORY_HOTPLUG
>> +       default "0x0"
>> +       range 0x1 0x40 if MEMORY_HOTPLUG
>> +       range 0x0 0x40
>> +       ---help---
>> +          Define the padding in terabyte added to the existing physical memory
>> +          size during kernel memory randomization. It is useful for memory
>> +          hotplug support but reduces the entropy available for address
>> +          randomization.
>> +
>> +          If unsure, leave at the default value.
>> +
>>  config HOTPLUG_CPU
>>         bool "Support for hot-pluggable CPUs"
>>         depends on SMP
>> diff --git a/arch/x86/mm/kaslr.c b/arch/x86/mm/kaslr.c
>> index 3b330a9..ef3dc19 100644
>> --- a/arch/x86/mm/kaslr.c
>> +++ b/arch/x86/mm/kaslr.c
>> @@ -68,15 +68,25 @@ void __init kernel_randomize_memory(void)
>>  {
>>         size_t i;
>>         unsigned long addr = memory_rand_start;
>> -       unsigned long padding, rand, mem_tb;
>> +       unsigned long padding, rand, mem_tb, page_offset_padding;
>>         struct rnd_state rnd_st;
>>         unsigned long remain_padding = memory_rand_end - memory_rand_start;
>>
>>         if (!kaslr_enabled())
>>                 return;
>>
>> +       /*
>> +        * Update Physical memory mapping to available and
>> +        * add padding if needed (especially for memory hotplug support).
>> +        */
>> +       page_offset_padding = CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
>> +
>> +#ifdef CONFIG_MEMORY_HOTPLUG
>> +       page_offset_padding = max(1UL, page_offset_padding);
>> +#endif
>
> Can't the ifdef and max lines be dropped? The Kconfig already enforces
> the range to have a minimum of 1 when CONFIG_MEMORY_HOTPLUG is used,
> IIUC.
>

Sure, I thought I had a bug when enabling it before hotplug but it
seems to work so I can drop it.

>> +
>>         BUG_ON(kaslr_regions[0].base != &page_offset_base);
>> -       mem_tb = ((max_pfn << PAGE_SHIFT) >> TB_SHIFT);
>> +       mem_tb = ((max_pfn << PAGE_SHIFT) >> TB_SHIFT) + page_offset_padding;
>
> In fact, can't this variable be entirely dropped and the mem_tb
> calculation could just refer to RANDOMIZE_MEMORY_PHYSICAL_PADDING
> directly?
>

Yes it can, I will do it on next iteration.

> -Kees
>
>>
>>         if (mem_tb < kaslr_regions[0].size_tb)
>>                 kaslr_regions[0].size_tb = mem_tb;
>> --
>> 2.8.0.rc3.226.g39d4020
>>
>
>
>
> --
> Kees Cook
> Chrome OS & Brillo Security

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web