revert "PIE randomization"
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
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);