All of lore.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.