[resending, as discussed last week, thanks]
From: Jiri Kosina <[email protected]>
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 <[email protected]>
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 */
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]