public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Hector Marco <hecmargi@upv.es>
To: linux-kernel@vger.kernel.org
Cc: akpm@linux-foundation.org, tglx@linutronix.de, mingo@redhat.com,
	hpa@zytor.com, linux@arm.linux.org.uk, catalin.marinas@arm.com,
	will.deacon@arm.com, oleg@redhat.com, luto@amacapital.net,
	keescook@chromium.org
Subject: [PATCH] ASLRv3: randomize_va_space=3 preventing offset2lib attack
Date: Fri, 05 Dec 2014 01:07:50 +0100	[thread overview]
Message-ID: <5480F756.90106@upv.es> (raw)

[PATCH] ASLRv3: randomize_va_space=3 preventing offset2lib attack

  The issue appears on PIE linked executables when all memory areas of
  a process are randomized (randomize_va_space=2). In this case, the
  attack "offset2lib" de-randomizes all library areas on 64 bit Linux
  systems in less than one second.

  Further details of the PoC attack at:
  http://cybersecurity.upv.es/attacks/offset2lib/offset2lib.html

  PIE linked applications are loaded side by side with the dynamic
  libraries, which is exploited by the offset2lib attack. Moving away
  the executable from the mmap_base area (libraries area) prevents the
  attack.

  This patch loads the PIE linked executable in a different area than
  the libraries when randomize_va_space=3.

  Patch implementation details:

   - The ELF_ET_DYN_BASE address is used as the base to load randomly
     the PIE executable.

   - The executable image has the same entropy than
     randomize_va_space=2.


  If the randomize_va_space is set to 2 then this patch does not change
  any behavior when loading new processes.

  The patch has been tested on x86_64/32 and ARM/ARM64.


diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c
index 5e85ed3..6602f5e 100644
--- a/arch/arm/mm/mmap.c
+++ b/arch/arm/mm/mmap.c
@@ -10,6 +10,7 @@
 #include <linux/personality.h>
 #include <linux/random.h>
 #include <asm/cachetype.h>
+#include <asm/elf.h>

 #define COLOUR_ALIGN(addr,pgoff)		\
 	((((addr)+SHMLBA-1)&~(SHMLBA-1)) +	\
@@ -19,6 +20,14 @@
 #define MIN_GAP (128*1024*1024UL)
 #define MAX_GAP ((TASK_SIZE)/6*5)

+#if ELF_EXEC_PAGESIZE > PAGE_SIZE
+#define ELF_MIN_ALIGN   ELF_EXEC_PAGESIZE
+#else
+#define ELF_MIN_ALIGN   PAGE_SIZE
+#endif
+
+#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))
+
 static int mmap_is_legacy(void)
 {
 	if (current->personality & ADDR_COMPAT_LAYOUT)
@@ -184,6 +193,9 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 	} else {
 		mm->mmap_base = mmap_base(random_factor);
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		if (randomize_va_space > 2)
+			mm->exec_base = ELF_PAGESTART(ELF_ET_DYN_BASE -
+				((get_random_int() % (1 << 8)) << PAGE_SHIFT));
 	}
 }

diff --git a/arch/arm64/mm/mmap.c b/arch/arm64/mm/mmap.c
index 1d73662..32be3fd 100644
--- a/arch/arm64/mm/mmap.c
+++ b/arch/arm64/mm/mmap.c
@@ -28,6 +28,16 @@
 #include <linux/random.h>

 #include <asm/cputype.h>
+#include <asm/elf.h>
+
+
+#if ELF_EXEC_PAGESIZE > PAGE_SIZE
+#define ELF_MIN_ALIGN   ELF_EXEC_PAGESIZE
+#else
+#define ELF_MIN_ALIGN   PAGE_SIZE
+#endif
+
+#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))

 /*
  * Leave enough space between the mmap area and the stack to honour
ulimit in
@@ -93,6 +103,8 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 	} else {
 		mm->mmap_base = mmap_base();
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		if (randomize_va_space > 2)
+			mm->exec_base = ELF_PAGESTART(ELF_ET_DYN_BASE - mmap_rnd());
 	}
 }
 EXPORT_SYMBOL_GPL(arch_pick_mmap_layout);
diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 919b912..8cb9855 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -31,6 +31,14 @@
 #include <linux/sched.h>
 #include <asm/elf.h>

+#if ELF_EXEC_PAGESIZE > PAGE_SIZE
+#define ELF_MIN_ALIGN   ELF_EXEC_PAGESIZE
+#else
+#define ELF_MIN_ALIGN   PAGE_SIZE
+#endif
+
+#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))
+
 struct va_alignment __read_mostly va_align = {
 	.flags = -1,
 };
@@ -120,5 +128,7 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
 		mm->get_unmapped_area = arch_get_unmapped_area;
 	} else {
 		mm->get_unmapped_area = arch_get_unmapped_area_topdown;
+		if (randomize_va_space > 2)
+			mm->exec_base = ELF_PAGESTART(ELF_ET_DYN_BASE - mmap_rnd());
 	}
 }
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d8fc060..6f319c1 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -804,8 +804,11 @@ static int load_elf_binary(struct linux_binprm *bprm)
 			 * load_bias value in order to establish proper
 			 * non-randomized mappings.
 			 */
-			if (current->flags & PF_RANDOMIZE)
+			if (current->flags & PF_RANDOMIZE) {
 				load_bias = 0;
+				if (randomize_va_space > 2)
+					load_bias = current->mm->exec_base;
+			}
 			else
 				load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr);
 #else
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 6e0b286..dd052ec 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -353,6 +353,7 @@ struct mm_struct {
 #endif
 	unsigned long mmap_base;		/* base of mmap area */
 	unsigned long mmap_legacy_base;         /* base of mmap area in
bottom-up allocations */
+	unsigned long exec_base;		/* base of exec area */
 	unsigned long task_size;		/* size of task vm space */
 	unsigned long highest_vm_end;		/* highest vma end address */
 	pgd_t * pgd;
diff --git a/kernel/fork.c b/kernel/fork.c
index 9b7d746..1fd4553 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -551,6 +551,7 @@ static void mm_init_owner(struct mm_struct *mm,
struct task_struct *p)
 static struct mm_struct *mm_init(struct mm_struct *mm, struct
task_struct *p)
 {
 	mm->mmap = NULL;
+	mm->exec_base = 0;
 	mm->mm_rb = RB_ROOT;
 	mm->vmacache_seqnum = 0;
 	atomic_set(&mm->mm_users, 1);


  Signed-off-by: Hector Marco-Gisbert <hecmargi@upv.es>
  Signed-off-by: Ismael Ripoll <iripoll@upv.es>

             reply	other threads:[~2014-12-05  0:25 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-12-05  0:07 Hector Marco [this message]
2014-12-05 20:08 ` [PATCH] ASLRv3: randomize_va_space=3 preventing offset2lib attack Kees Cook
2014-12-08 22:15   ` Hector Marco Gisbert
2014-12-05 22:00 ` Andy Lutomirski
2014-12-08 20:09 ` Christian Borntraeger
2014-12-09 17:37   ` Kees Cook
     [not found] <5489E6D2.2060200@upv.es>
2014-12-11 20:12 ` Hector Marco
2014-12-11 22:11   ` Kees Cook
2014-12-12 16:32     ` Hector Marco
2014-12-12 17:17       ` Andy Lutomirski
2014-12-19 22:04         ` Hector Marco
2014-12-19 22:11           ` Andy Lutomirski
2014-12-19 22:19             ` Cyrill Gorcunov
2014-12-19 23:53             ` Andy Lutomirski
2014-12-22 17:36               ` Hector Marco Gisbert
2014-12-22 17:56                 ` Andy Lutomirski
2014-12-22 19:49                   ` Jiri Kosina
2014-12-22 20:00                     ` Andy Lutomirski
2014-12-22 20:03                       ` Jiri Kosina
2014-12-22 20:13                         ` Andy Lutomirski
2014-12-22 23:23                   ` Hector Marco Gisbert
2014-12-22 23:38                     ` Andy Lutomirski
     [not found]                       ` <CAH4rwTKeN0P84FJnocoKV4t9rc2Ox_EYc+LEibD+Y83n7C8aVA@mail.gmail.com>
2014-12-23  8:15                         ` Andy Lutomirski
2014-12-23 20:06                           ` Hector Marco Gisbert
2014-12-23 20:53                             ` Andy Lutomirski
2015-01-07 17:26     ` Hector Marco Gisbert

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5480F756.90106@upv.es \
    --to=hecmargi@upv.es \
    --cc=akpm@linux-foundation.org \
    --cc=catalin.marinas@arm.com \
    --cc=hpa@zytor.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@arm.linux.org.uk \
    --cc=luto@amacapital.net \
    --cc=mingo@redhat.com \
    --cc=oleg@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox