revert "PIE randomization"

2007-07-21 Thread Linux Kernel Mailing List
Gitweb: 
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=d4e3cc387ea1b74c3ad2ef2f6f5c05fd6fc314b8
Commit: d4e3cc387ea1b74c3ad2ef2f6f5c05fd6fc314b8
Parent: 80e27982a66ea8306a704ba8bdf634ed480d4b46
Author: Andrew Morton <[EMAIL PROTECTED]>
AuthorDate: Sat Jul 21 04:37:32 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Sat Jul 21 17:49:14 2007 -0700

    revert "PIE randomization"

There are reports of this causing userspace failures
(http://lkml.org/lkml/2007/7/20/421).

Revert.

Cc: Jan Kratochvil <[EMAIL PROTECTED]>
Cc: Jiri Kosina <[EMAIL PROTECTED]>
Cc: Ingo Molnar <[EMAIL PROTECTED]>
Cc: Roland McGrath <[EMAIL PROTECTED]>
Cc: Jakub Jelinek <[EMAIL PROTECTED]>
Cc: Ulrich Kunitz <[EMAIL PROTECTED]>
Cc: "H. Peter Anvin" <[EMAIL PROTECTED]>
Cc: "Bret Towe" <[EMAIL PROTECTED]>
Cc: "Luck, Tony" <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 arch/ia64/ia32/binfmt_elf32.c |2 +-
 fs/binfmt_elf.c   |  109 +
 2 files changed, 24 insertions(+), 87 deletions(-)

diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index e1189ba..1cfab32 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -226,7 +226,7 @@ elf32_set_personality (void)
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int 
prot, int type, unsigned long unused)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int 
prot, int type)
 {
unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
 
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index ba24cb2..4482a06 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -45,7 +45,7 @@
 
 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static int load_elf_library(struct file *);
-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, 
int, int, unsigned long);
+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, 
int, int);
 
 /*
  * If we don't support core dumping, then supply a NULL so we
@@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = {
.hasvdso= 1
 };
 
-#define BAD_ADDR(x) IS_ERR_VALUE(x)
+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
 
 static int set_brk(unsigned long start, unsigned long end)
 {
@@ -295,70 +295,33 @@ create_elf_tables(struct linux_binprm *bprm, struct 
elfhdr *exec,
 #ifndef elf_map
 
 static unsigned long elf_map(struct file *filep, unsigned long addr,
-   struct elf_phdr *eppnt, int prot, int type,
-   unsigned long total_size)
+   struct elf_phdr *eppnt, int prot, int type)
 {
unsigned long map_addr;
-   unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
-   unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
-   addr = ELF_PAGESTART(addr);
-   size = ELF_PAGEALIGN(size);
+   unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr);
 
+   down_write(¤t->mm->mmap_sem);
/* mmap() will return -EINVAL if given a zero size, but a
 * segment with zero filesize is perfectly valid */
-   if (!size)
-   return addr;
-
-   down_write(¤t->mm->mmap_sem);
-   /*
-   * total_size is the size of the ELF (interpreter) image.
-   * The _first_ mmap needs to know the full size, otherwise
-   * randomization might put this image into an overlapping
-   * position with the ELF binary image. (since size < total_size)
-   * So we first map the 'big' image - and unmap the remainder at
-   * the end. (which unmap is needed for ELF images with holes.)
-   */
-   if (total_size) {
-   total_size = ELF_PAGEALIGN(total_size);
-   map_addr = do_mmap(filep, addr, total_size, prot, type, off);
-   if (!BAD_ADDR(map_addr))
-   do_munmap(current->mm, map_addr+size, total_size-size);
-   } else
-   map_addr = do_mmap(filep, addr, size, prot, type, off);
-
+   if (eppnt->p_filesz + pageoffset)
+   map_addr = do_mmap(filep, ELF_PAGESTART(addr),
+  eppnt->p_filesz + pageoffset, prot, type,
+  eppnt->p_offset - pageoffset);
+   else
+   map_addr = ELF_PAGESTART(addr);
up_write(¤t->mm->mmap_sem);
return(map_addr);
 }
 
 #endif /* !elf_map */
 
-static unsigned long total_mapping_size(struct elf_phdr *cmds, int nr)
-{
-   int i, first_i

PIE randomization

2007-07-16 Thread Linux Kernel Mailing List
Gitweb: 
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=60bfba7e85f88fe834e623ead799cf580de20971
Commit: 60bfba7e85f88fe834e623ead799cf580de20971
Parent: f057eac0d7ad967138390a9dd7fd8267e1e39d19
Author: Jan Kratochvil <[EMAIL PROTECTED]>
AuthorDate: Sun Jul 15 23:40:06 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Mon Jul 16 09:05:42 2007 -0700

PIE randomization

This patch is using mmap()'s randomization functionality in such a way that
it maps the main executable of (specially compiled/linked -pie/-fpie)
ET_DYN binaries onto a random address (in cases in which mmap() is allowed
to perform a randomization).

Origin of this patch is in exec-shield
(http://people.redhat.com/mingo/exec-shield/)

[EMAIL PROTECTED]: pie randomization: fix BAD_ADDR macro]
Signed-off-by: Jan Kratochvil <[EMAIL PROTECTED]>
Signed-off-by: Jiri Kosina <[EMAIL PROTECTED]>
Cc: Ingo Molnar <[EMAIL PROTECTED]>
Cc: Roland McGrath <[EMAIL PROTECTED]>
Cc: Jakub Jelinek <[EMAIL PROTECTED]>
Signed-off-by: Jiri Kosina <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 arch/ia64/ia32/binfmt_elf32.c |2 +-
 fs/binfmt_elf.c   |  109 -
 2 files changed, 87 insertions(+), 24 deletions(-)

diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index c05bda6..6f4d3d0 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -261,7 +261,7 @@ elf32_set_personality (void)
 }
 
 static unsigned long
-elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int 
prot, int type)
+elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int 
prot, int type, unsigned long unused)
 {
unsigned long pgoff = (eppnt->p_vaddr) & ~IA32_PAGE_MASK;
 
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 08e4414..5cfa735 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -45,7 +45,7 @@
 
 static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs);
 static int load_elf_library(struct file *);
-static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, 
int, int);
+static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, 
int, int, unsigned long);
 
 /*
  * If we don't support core dumping, then supply a NULL so we
@@ -80,7 +80,7 @@ static struct linux_binfmt elf_format = {
.hasvdso= 1
 };
 
-#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
+#define BAD_ADDR(x) IS_ERR_VALUE(x)
 
 static int set_brk(unsigned long start, unsigned long end)
 {
@@ -285,33 +285,70 @@ create_elf_tables(struct linux_binprm *bprm, struct 
elfhdr *exec,
 #ifndef elf_map
 
 static unsigned long elf_map(struct file *filep, unsigned long addr,
-   struct elf_phdr *eppnt, int prot, int type)
+   struct elf_phdr *eppnt, int prot, int type,
+   unsigned long total_size)
 {
unsigned long map_addr;
-   unsigned long pageoffset = ELF_PAGEOFFSET(eppnt->p_vaddr);
+   unsigned long size = eppnt->p_filesz + ELF_PAGEOFFSET(eppnt->p_vaddr);
+   unsigned long off = eppnt->p_offset - ELF_PAGEOFFSET(eppnt->p_vaddr);
+   addr = ELF_PAGESTART(addr);
+   size = ELF_PAGEALIGN(size);
 
-   down_write(¤t->mm->mmap_sem);
/* mmap() will return -EINVAL if given a zero size, but a
 * segment with zero filesize is perfectly valid */
-   if (eppnt->p_filesz + pageoffset)
-   map_addr = do_mmap(filep, ELF_PAGESTART(addr),
-  eppnt->p_filesz + pageoffset, prot, type,
-  eppnt->p_offset - pageoffset);
-   else
-   map_addr = ELF_PAGESTART(addr);
+   if (!size)
+   return addr;
+
+   down_write(¤t->mm->mmap_sem);
+   /*
+   * total_size is the size of the ELF (interpreter) image.
+   * The _first_ mmap needs to know the full size, otherwise
+   * randomization might put this image into an overlapping
+   * position with the ELF binary image. (since size < total_size)
+   * So we first map the 'big' image - and unmap the remainder at
+   * the end. (which unmap is needed for ELF images with holes.)
+   */
+   if (total_size) {
+   total_size = ELF_PAGEALIGN(total_size);
+   map_addr = do_mmap(filep, addr, total_size, prot, type, off);
+   if (!BAD_ADDR(map_addr))
+   do_munmap(current->mm, map_addr+size, total_size-size);
+   } else
+   map_addr = do_mmap(filep, addr, size, prot, type, off);
+
up_write(¤t->mm->mmap_sem);