public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] i386 and x86_64: randomize brk()
@ 2007-08-22 16:05 Jiri Kosina
  2007-08-22 22:58 ` Andrew Morton
  0 siblings, 1 reply; 17+ messages in thread
From: Jiri Kosina @ 2007-08-22 16:05 UTC (permalink / raw)
  To: Andrew Morton
  Cc: linux-kernel, Ingo Molnar, Jakub Jelinek, H. Peter Anvin,
	Andi Kleen, Kees Cook, Arjan van de Ven

From: Jiri Kosina <jkosina@suse.cz>

i386 and x86_64: randomize brk()

This patch randomizes the location of the heap (brk) for i386 and x86_64. 
The range is randomized in the range starting at current brk location up 
to 0x02000000 offset on both architectures. This, together with 
pie-executable-randomization.patch and 
pie-executable-randomization-fix.patch, should make the address space 
randomization on i386 and x86_64 complete (modulo vDSO randomization).

The code is based on execshield code written by Ingo Molnar.

Cc: Ingo Molnar <mingo@elte.hu>
Cc: Jakub Jelinek <jakub@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Andi Kleen <ak@suse.de>
Cc: Kees Cook <kees@outflux.net>
Cc: Arjan van de Ven <arjan@infradead.org>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8466471..21edde5 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -949,3 +949,15 @@ unsigned long arch_align_stack(unsigned long sp)
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_randomize_brk(void)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = current->mm->start_brk = new_brk;
+}
+
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 2842f50..37613f3 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -902,3 +902,15 @@ unsigned long arch_align_stack(unsigned long sp)
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_randomize_brk(void)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = current->mm->start_brk = new_brk;
+}
+
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d65f1d9..790b09e 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1073,6 +1073,11 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
+#ifdef ARCH_HAS_RANDOMIZE_BRK
+	if (current->flags & PF_RANDOMIZE)
+		arch_randomize_brk();
+#endif
+
 	if (current->personality & MMAP_PAGE_ZERO) {
 		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
 		   and some applications "depend" upon this behavior.
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index b32df3a..34752bc 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -160,4 +160,7 @@ do if (vdso_enabled) {							\
 
 #endif
 
+#define ARCH_HAS_RANDOMIZE_BRK
+extern void arch_randomize_brk(void);
+
 #endif
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
index b4fbe47..ec56e67 100644
--- a/include/asm-x86_64/elf.h
+++ b/include/asm-x86_64/elf.h
@@ -177,4 +177,7 @@ do if (vdso_enabled) {						\
 
 #endif
 
+#define ARCH_HAS_RANDOMIZE_BRK
+extern void arch_randomize_brk(void);
+
 #endif

^ permalink raw reply related	[flat|nested] 17+ messages in thread
* [PATCH] i386 and x86_64: randomize brk()
@ 2007-08-30 13:47 Jiri Kosina
  2007-08-30 14:01 ` Mike Frysinger
  0 siblings, 1 reply; 17+ messages in thread
From: Jiri Kosina @ 2007-08-30 13:47 UTC (permalink / raw)
  To: Andrew Morton; +Cc: linux-kernel

[resending, as discussed last week, thanks]


From: Jiri Kosina <jkosina@suse.cz>

i386 and x86_64: randomize brk()

This patch randomizes the location of the heap (brk) for i386 and x86_64. 
The range is randomized in the range starting at current brk location up 
to 0x02000000 offset for both architectures. This, together with 
pie-executable-randomization.patch and 
pie-executable-randomization-fix.patch, should make the address space 
randomization on i386 and x86_64 complete.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>

diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 8466471..5817749 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -949,3 +949,15 @@ unsigned long arch_align_stack(unsigned long sp)
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_randomize_brk(void)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = current->mm->start_brk = new_brk;
+}
+
diff --git a/arch/x86_64/ia32/ia32_binfmt.c b/arch/x86_64/ia32/ia32_binfmt.c
index dffd2ac..ccc4350 100644
--- a/arch/x86_64/ia32/ia32_binfmt.c
+++ b/arch/x86_64/ia32/ia32_binfmt.c
@@ -262,6 +262,7 @@ static void elf32_init(struct pt_regs *);
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
 #define arch_setup_additional_pages syscall32_setup_pages
 extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
+extern void arch_randomize_brk(void);
 
 #include "../../../fs/binfmt_elf.c" 
 
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c
index 2842f50..5c3953c 100644
--- a/arch/x86_64/kernel/process.c
+++ b/arch/x86_64/kernel/process.c
@@ -902,3 +902,15 @@ unsigned long arch_align_stack(unsigned long sp)
 		sp -= get_random_int() % 8192;
 	return sp & ~0xf;
 }
+
+void arch_randomize_brk(void)
+{
+	unsigned long new_brk, range_start, range_end;
+
+	range_start = current->mm->brk;
+	range_end = range_start + 0x02000000;
+	new_brk = randomize_range(range_start, range_end, 0);
+	if (new_brk)
+		current->mm->brk = current->mm->start_brk = new_brk;
+}
+
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d65f1d9..4c92461 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1073,6 +1073,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
 	current->mm->end_data = end_data;
 	current->mm->start_stack = bprm->p;
 
+	if (current->flags & PF_RANDOMIZE)
+		arch_randomize_brk();
+
 	if (current->personality & MMAP_PAGE_ZERO) {
 		/* Why this, you ask???  Well SVr4 maps page 0 as read-only,
 		   and some applications "depend" upon this behavior.
diff --git a/include/asm-alpha/elf.h b/include/asm-alpha/elf.h
index 6c2d78f..18210cc 100644
--- a/include/asm-alpha/elf.h
+++ b/include/asm-alpha/elf.h
@@ -163,5 +163,9 @@ extern int alpha_l3_cacheshape;
     NEW_AUX_ENT(AT_L3_CACHESHAPE, alpha_l3_cacheshape);		\
   } while (0)
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* __KERNEL__ */
 #endif /* __ASM_ALPHA_ELF_H */
diff --git a/include/asm-arm/elf.h b/include/asm-arm/elf.h
index ec1c685..eeeee3f 100644
--- a/include/asm-arm/elf.h
+++ b/include/asm-arm/elf.h
@@ -116,4 +116,8 @@ extern char elf_platform[];
 
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-avr32/elf.h b/include/asm-avr32/elf.h
index d334b49..61b7d81 100644
--- a/include/asm-avr32/elf.h
+++ b/include/asm-avr32/elf.h
@@ -107,4 +107,8 @@ typedef struct user_fpu_struct elf_fpregset_t;
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* __ASM_AVR32_ELF_H */
diff --git a/include/asm-blackfin/elf.h b/include/asm-blackfin/elf.h
index 5264b55..9223b86 100644
--- a/include/asm-blackfin/elf.h
+++ b/include/asm-blackfin/elf.h
@@ -124,4 +124,8 @@ do {											\
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-cris/elf.h b/include/asm-cris/elf.h
index 96a40c1..10607c7 100644
--- a/include/asm-cris/elf.h
+++ b/include/asm-cris/elf.h
@@ -93,4 +93,8 @@ typedef unsigned long elf_fpregset_t;
 
 #endif /* __KERNEL__ */
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-frv/elf.h b/include/asm-frv/elf.h
index 7df58a3..07df9dd 100644
--- a/include/asm-frv/elf.h
+++ b/include/asm-frv/elf.h
@@ -141,4 +141,8 @@ do {											\
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-h8300/elf.h b/include/asm-h8300/elf.h
index 7ba6a0a..4ee6d1d 100644
--- a/include/asm-h8300/elf.h
+++ b/include/asm-h8300/elf.h
@@ -103,4 +103,8 @@ typedef unsigned long elf_fpregset_t;
 #define R_H8_ABS32     65
 #define R_H8_ABS32A16 127
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-i386/elf.h b/include/asm-i386/elf.h
index b32df3a..5935d4c 100644
--- a/include/asm-i386/elf.h
+++ b/include/asm-i386/elf.h
@@ -160,4 +160,6 @@ do if (vdso_enabled) {							\
 
 #endif
 
+extern void arch_randomize_brk(void);
+
 #endif
diff --git a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
index 25f9835..3b84b0d 100644
--- a/include/asm-ia64/elf.h
+++ b/include/asm-ia64/elf.h
@@ -249,4 +249,8 @@ do {									\
 
 #endif /* __KERNEL__ */
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* _ASM_IA64_ELF_H */
diff --git a/include/asm-m32r/elf.h b/include/asm-m32r/elf.h
index bbee8b2..33a5244 100644
--- a/include/asm-m32r/elf.h
+++ b/include/asm-m32r/elf.h
@@ -133,4 +133,8 @@ typedef elf_fpreg_t elf_fpregset_t;
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif  /* _ASM_M32R__ELF_H */
diff --git a/include/asm-m68k/elf.h b/include/asm-m68k/elf.h
index eb63b85..f6ff4fe 100644
--- a/include/asm-m68k/elf.h
+++ b/include/asm-m68k/elf.h
@@ -118,4 +118,8 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-m68knommu/elf.h b/include/asm-m68knommu/elf.h
index 40b1ed6..d73f1d5 100644
--- a/include/asm-m68knommu/elf.h
+++ b/include/asm-m68knommu/elf.h
@@ -109,4 +109,8 @@ typedef struct user_m68kfp_struct elf_fpregset_t;
 #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h
index e7d95d4..571cd80 100644
--- a/include/asm-mips/elf.h
+++ b/include/asm-mips/elf.h
@@ -372,4 +372,8 @@ extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *);
 #define ELF_ET_DYN_BASE         (TASK_SIZE / 3 * 2)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* _ASM_ELF_H */
diff --git a/include/asm-parisc/elf.h b/include/asm-parisc/elf.h
index f628ac7..9807cae 100644
--- a/include/asm-parisc/elf.h
+++ b/include/asm-parisc/elf.h
@@ -344,4 +344,8 @@ struct pt_regs;	/* forward declaration... */
 #define ELF_HWCAP	0
 /* (boot_cpu_data.x86_capability) */
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index de50799..af45d0e 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -422,4 +422,8 @@ extern void arch_write_notes(struct file *file);
 #define ARCH_HAVE_EXTRA_ELF_NOTES
 #endif /* CONFIG_PPC_CELL */
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* _ASM_POWERPC_ELF_H */
diff --git a/include/asm-s390/elf.h b/include/asm-s390/elf.h
index 91d0632..0a32ac3 100644
--- a/include/asm-s390/elf.h
+++ b/include/asm-s390/elf.h
@@ -216,4 +216,8 @@ do {							\
 #endif /* __s390x__ */
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif
diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h
index 43ca244..f055a68 100644
--- a/include/asm-sh/elf.h
+++ b/include/asm-sh/elf.h
@@ -140,4 +140,8 @@ do {								\
 } while (0)
 #endif /* CONFIG_VSYSCALL */
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* __ASM_SH_ELF_H */
diff --git a/include/asm-sh64/elf.h b/include/asm-sh64/elf.h
index f994286..5d6dd4b 100644
--- a/include/asm-sh64/elf.h
+++ b/include/asm-sh64/elf.h
@@ -104,4 +104,8 @@ typedef struct user_fpu_struct elf_fpregset_t;
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* __ASM_SH64_ELF_H */
diff --git a/include/asm-sparc/elf.h b/include/asm-sparc/elf.h
index aaf6ef4..94b273d 100644
--- a/include/asm-sparc/elf.h
+++ b/include/asm-sparc/elf.h
@@ -168,4 +168,8 @@ do {	unsigned long *dest = &(__elf_regs[0]);		\
 
 #endif /* __KERNEL__ */
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* !(__ASMSPARC_ELF_H) */
diff --git a/include/asm-sparc64/elf.h b/include/asm-sparc64/elf.h
index 303d85e..8afe25f 100644
--- a/include/asm-sparc64/elf.h
+++ b/include/asm-sparc64/elf.h
@@ -190,4 +190,8 @@ do {	unsigned long new_flags = current_thread_info()->flags; \
 } while (0)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* !(__ASM_SPARC64_ELF_H) */
diff --git a/include/asm-um/elf-i386.h b/include/asm-um/elf-i386.h
diff --git a/include/asm-um/elf-ppc.h b/include/asm-um/elf-ppc.h
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h
index 8a8246d..4b8d4c6 100644
--- a/include/asm-um/elf-x86_64.h
+++ b/include/asm-um/elf-x86_64.h
@@ -81,6 +81,10 @@ extern long elf_aux_hwcap;
 
 #define SET_PERSONALITY(ex, ibcs2) do ; while(0)
 
+static inline void arch_randomize_brk(void) 
+{ 
+}
+
 #endif
 
 /*
diff --git a/include/asm-v850/elf.h b/include/asm-v850/elf.h
index 7db8edf..2e72192 100644
--- a/include/asm-v850/elf.h
+++ b/include/asm-v850/elf.h
@@ -98,4 +98,8 @@ typedef struct user_fpu_struct elf_fpregset_t;
 #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT)
 #endif
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif /* __V850_ELF_H__ */
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
index b4fbe47..5a1adf9 100644
--- a/include/asm-x86_64/elf.h
+++ b/include/asm-x86_64/elf.h
@@ -177,4 +177,6 @@ do if (vdso_enabled) {						\
 
 #endif
 
+extern void arch_randomize_brk(void);
+
 #endif
diff --git a/include/asm-xtensa/elf.h b/include/asm-xtensa/elf.h
index 1569b53..10e60bf 100644
--- a/include/asm-xtensa/elf.h
+++ b/include/asm-xtensa/elf.h
@@ -222,5 +222,9 @@ extern void do_save_fpregs (elf_fpregset_t*, struct pt_regs*,
 extern int do_restore_fpregs (elf_fpregset_t*, struct pt_regs*,
 			      struct task_struct*);
 
+static inline void arch_randomize_brk(void)
+{
+}
+
 #endif	/* __KERNEL__ */
 #endif	/* _XTENSA_ELF_H */

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2007-09-03 20:44 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-22 16:05 [PATCH] i386 and x86_64: randomize brk() Jiri Kosina
2007-08-22 22:58 ` Andrew Morton
2007-08-22 23:04   ` Jiri Kosina
  -- strict thread matches above, loose matches on Subject: below --
2007-08-30 13:47 Jiri Kosina
2007-08-30 14:01 ` Mike Frysinger
2007-08-30 14:21   ` Jiri Kosina
2007-08-30 14:26     ` Mike Frysinger
2007-08-30 15:10       ` Jiri Kosina
2007-08-30 15:33         ` Franck Bui-Huu
2007-08-31  1:05         ` Andrew Morton
2007-08-31 11:56           ` Jiri Kosina
2007-09-01 20:19           ` Franck Bui-Huu
2007-09-02 20:28             ` Andrew Morton
2007-09-03  9:34               ` Jiri Kosina
2007-09-03 10:03                 ` Jiri Kosina
2007-09-03 17:38                   ` Franck Bui-Huu
2007-09-03 20:44                     ` Jiri Kosina

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox