aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r--fs/binfmt_elf.c178
1 files changed, 92 insertions, 86 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index edd90c49003c..535e763ab1a6 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -31,6 +31,7 @@
31#include <linux/random.h> 31#include <linux/random.h>
32#include <linux/elf.h> 32#include <linux/elf.h>
33#include <linux/utsname.h> 33#include <linux/utsname.h>
34#include <linux/coredump.h>
34#include <asm/uaccess.h> 35#include <asm/uaccess.h>
35#include <asm/param.h> 36#include <asm/param.h>
36#include <asm/page.h> 37#include <asm/page.h>
@@ -662,27 +663,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
662 if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0') 663 if (elf_interpreter[elf_ppnt->p_filesz - 1] != '\0')
663 goto out_free_interp; 664 goto out_free_interp;
664 665
665 /*
666 * The early SET_PERSONALITY here is so that the lookup
667 * for the interpreter happens in the namespace of the
668 * to-be-execed image. SET_PERSONALITY can select an
669 * alternate root.
670 *
671 * However, SET_PERSONALITY is NOT allowed to switch
672 * this task into the new images's memory mapping
673 * policy - that is, TASK_SIZE must still evaluate to
674 * that which is appropriate to the execing application.
675 * This is because exit_mmap() needs to have TASK_SIZE
676 * evaluate to the size of the old image.
677 *
678 * So if (say) a 64-bit application is execing a 32-bit
679 * application it is the architecture's responsibility
680 * to defer changing the value of TASK_SIZE until the
681 * switch really is going to happen - do this in
682 * flush_thread(). - akpm
683 */
684 SET_PERSONALITY(loc->elf_ex);
685
686 interpreter = open_exec(elf_interpreter); 666 interpreter = open_exec(elf_interpreter);
687 retval = PTR_ERR(interpreter); 667 retval = PTR_ERR(interpreter);
688 if (IS_ERR(interpreter)) 668 if (IS_ERR(interpreter))
@@ -730,9 +710,6 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
730 /* Verify the interpreter has a valid arch */ 710 /* Verify the interpreter has a valid arch */
731 if (!elf_check_arch(&loc->interp_elf_ex)) 711 if (!elf_check_arch(&loc->interp_elf_ex))
732 goto out_free_dentry; 712 goto out_free_dentry;
733 } else {
734 /* Executables without an interpreter also need a personality */
735 SET_PERSONALITY(loc->elf_ex);
736 } 713 }
737 714
738 /* Flush all traces of the currently running executable */ 715 /* Flush all traces of the currently running executable */
@@ -752,7 +729,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
752 729
753 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space) 730 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
754 current->flags |= PF_RANDOMIZE; 731 current->flags |= PF_RANDOMIZE;
755 arch_pick_mmap_layout(current->mm); 732
733 setup_new_exec(bprm);
756 734
757 /* Do this so that we can load the interpreter, if need be. We will 735 /* Do this so that we can load the interpreter, if need be. We will
758 change some of these later */ 736 change some of these later */
@@ -1108,36 +1086,6 @@ out:
1108 * Modelled on fs/exec.c:aout_core_dump() 1086 * Modelled on fs/exec.c:aout_core_dump()
1109 * Jeremy Fitzhardinge <jeremy@sw.oz.au> 1087 * Jeremy Fitzhardinge <jeremy@sw.oz.au>
1110 */ 1088 */
1111/*
1112 * These are the only things you should do on a core-file: use only these
1113 * functions to write out all the necessary info.
1114 */
1115static int dump_write(struct file *file, const void *addr, int nr)
1116{
1117 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1118}
1119
1120static int dump_seek(struct file *file, loff_t off)
1121{
1122 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
1123 if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
1124 return 0;
1125 } else {
1126 char *buf = (char *)get_zeroed_page(GFP_KERNEL);
1127 if (!buf)
1128 return 0;
1129 while (off > 0) {
1130 unsigned long n = off;
1131 if (n > PAGE_SIZE)
1132 n = PAGE_SIZE;
1133 if (!dump_write(file, buf, n))
1134 return 0;
1135 off -= n;
1136 }
1137 free_page((unsigned long)buf);
1138 }
1139 return 1;
1140}
1141 1089
1142/* 1090/*
1143 * Decide what to dump of a segment, part, all or none. 1091 * Decide what to dump of a segment, part, all or none.
@@ -1272,11 +1220,6 @@ static int writenote(struct memelfnote *men, struct file *file,
1272} 1220}
1273#undef DUMP_WRITE 1221#undef DUMP_WRITE
1274 1222
1275#define DUMP_WRITE(addr, nr) \
1276 if ((size += (nr)) > cprm->limit || \
1277 !dump_write(cprm->file, (addr), (nr))) \
1278 goto end_coredump;
1279
1280static void fill_elf_header(struct elfhdr *elf, int segs, 1223static void fill_elf_header(struct elfhdr *elf, int segs,
1281 u16 machine, u32 flags, u8 osabi) 1224 u16 machine, u32 flags, u8 osabi)
1282{ 1225{
@@ -1895,6 +1838,34 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
1895 return gate_vma; 1838 return gate_vma;
1896} 1839}
1897 1840
1841static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
1842 elf_addr_t e_shoff, int segs)
1843{
1844 elf->e_shoff = e_shoff;
1845 elf->e_shentsize = sizeof(*shdr4extnum);
1846 elf->e_shnum = 1;
1847 elf->e_shstrndx = SHN_UNDEF;
1848
1849 memset(shdr4extnum, 0, sizeof(*shdr4extnum));
1850
1851 shdr4extnum->sh_type = SHT_NULL;
1852 shdr4extnum->sh_size = elf->e_shnum;
1853 shdr4extnum->sh_link = elf->e_shstrndx;
1854 shdr4extnum->sh_info = segs;
1855}
1856
1857static size_t elf_core_vma_data_size(struct vm_area_struct *gate_vma,
1858 unsigned long mm_flags)
1859{
1860 struct vm_area_struct *vma;
1861 size_t size = 0;
1862
1863 for (vma = first_vma(current, gate_vma); vma != NULL;
1864 vma = next_vma(vma, gate_vma))
1865 size += vma_dump_size(vma, mm_flags);
1866 return size;
1867}
1868
1898/* 1869/*
1899 * Actual dumper 1870 * Actual dumper
1900 * 1871 *
@@ -1911,8 +1882,11 @@ static int elf_core_dump(struct coredump_params *cprm)
1911 struct vm_area_struct *vma, *gate_vma; 1882 struct vm_area_struct *vma, *gate_vma;
1912 struct elfhdr *elf = NULL; 1883 struct elfhdr *elf = NULL;
1913 loff_t offset = 0, dataoff, foffset; 1884 loff_t offset = 0, dataoff, foffset;
1914 unsigned long mm_flags;
1915 struct elf_note_info info; 1885 struct elf_note_info info;
1886 struct elf_phdr *phdr4note = NULL;
1887 struct elf_shdr *shdr4extnum = NULL;
1888 Elf_Half e_phnum;
1889 elf_addr_t e_shoff;
1916 1890
1917 /* 1891 /*
1918 * We no longer stop all VM operations. 1892 * We no longer stop all VM operations.
@@ -1935,20 +1909,25 @@ static int elf_core_dump(struct coredump_params *cprm)
1935 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here. 1909 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
1936 */ 1910 */
1937 segs = current->mm->map_count; 1911 segs = current->mm->map_count;
1938#ifdef ELF_CORE_EXTRA_PHDRS 1912 segs += elf_core_extra_phdrs();
1939 segs += ELF_CORE_EXTRA_PHDRS;
1940#endif
1941 1913
1942 gate_vma = get_gate_vma(current); 1914 gate_vma = get_gate_vma(current);
1943 if (gate_vma != NULL) 1915 if (gate_vma != NULL)
1944 segs++; 1916 segs++;
1945 1917
1918 /* for notes section */
1919 segs++;
1920
1921 /* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
1922 * this, kernel supports extended numbering. Have a look at
1923 * include/linux/elf.h for further information. */
1924 e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
1925
1946 /* 1926 /*
1947 * Collect all the non-memory information about the process for the 1927 * Collect all the non-memory information about the process for the
1948 * notes. This also sets up the file header. 1928 * notes. This also sets up the file header.
1949 */ 1929 */
1950 if (!fill_note_info(elf, segs + 1, /* including notes section */ 1930 if (!fill_note_info(elf, e_phnum, &info, cprm->signr, cprm->regs))
1951 &info, cprm->signr, cprm->regs))
1952 goto cleanup; 1931 goto cleanup;
1953 1932
1954 has_dumped = 1; 1933 has_dumped = 1;
@@ -1957,31 +1936,47 @@ static int elf_core_dump(struct coredump_params *cprm)
1957 fs = get_fs(); 1936 fs = get_fs();
1958 set_fs(KERNEL_DS); 1937 set_fs(KERNEL_DS);
1959 1938
1960 DUMP_WRITE(elf, sizeof(*elf));
1961 offset += sizeof(*elf); /* Elf header */ 1939 offset += sizeof(*elf); /* Elf header */
1962 offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */ 1940 offset += segs * sizeof(struct elf_phdr); /* Program headers */
1963 foffset = offset; 1941 foffset = offset;
1964 1942
1965 /* Write notes phdr entry */ 1943 /* Write notes phdr entry */
1966 { 1944 {
1967 struct elf_phdr phdr;
1968 size_t sz = get_note_info_size(&info); 1945 size_t sz = get_note_info_size(&info);
1969 1946
1970 sz += elf_coredump_extra_notes_size(); 1947 sz += elf_coredump_extra_notes_size();
1971 1948
1972 fill_elf_note_phdr(&phdr, sz, offset); 1949 phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
1950 if (!phdr4note)
1951 goto end_coredump;
1952
1953 fill_elf_note_phdr(phdr4note, sz, offset);
1973 offset += sz; 1954 offset += sz;
1974 DUMP_WRITE(&phdr, sizeof(phdr));
1975 } 1955 }
1976 1956
1977 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1957 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1978 1958
1979 /* 1959 offset += elf_core_vma_data_size(gate_vma, cprm->mm_flags);
1980 * We must use the same mm->flags while dumping core to avoid 1960 offset += elf_core_extra_data_size();
1981 * inconsistency between the program headers and bodies, otherwise an 1961 e_shoff = offset;
1982 * unusable core file can be generated. 1962
1983 */ 1963 if (e_phnum == PN_XNUM) {
1984 mm_flags = current->mm->flags; 1964 shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
1965 if (!shdr4extnum)
1966 goto end_coredump;
1967 fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
1968 }
1969
1970 offset = dataoff;
1971
1972 size += sizeof(*elf);
1973 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
1974 goto end_coredump;
1975
1976 size += sizeof(*phdr4note);
1977 if (size > cprm->limit
1978 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
1979 goto end_coredump;
1985 1980
1986 /* Write program headers for segments dump */ 1981 /* Write program headers for segments dump */
1987 for (vma = first_vma(current, gate_vma); vma != NULL; 1982 for (vma = first_vma(current, gate_vma); vma != NULL;
@@ -1992,7 +1987,7 @@ static int elf_core_dump(struct coredump_params *cprm)
1992 phdr.p_offset = offset; 1987 phdr.p_offset = offset;
1993 phdr.p_vaddr = vma->vm_start; 1988 phdr.p_vaddr = vma->vm_start;
1994 phdr.p_paddr = 0; 1989 phdr.p_paddr = 0;
1995 phdr.p_filesz = vma_dump_size(vma, mm_flags); 1990 phdr.p_filesz = vma_dump_size(vma, cprm->mm_flags);
1996 phdr.p_memsz = vma->vm_end - vma->vm_start; 1991 phdr.p_memsz = vma->vm_end - vma->vm_start;
1997 offset += phdr.p_filesz; 1992 offset += phdr.p_filesz;
1998 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1993 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -2002,12 +1997,14 @@ static int elf_core_dump(struct coredump_params *cprm)
2002 phdr.p_flags |= PF_X; 1997 phdr.p_flags |= PF_X;
2003 phdr.p_align = ELF_EXEC_PAGESIZE; 1998 phdr.p_align = ELF_EXEC_PAGESIZE;
2004 1999
2005 DUMP_WRITE(&phdr, sizeof(phdr)); 2000 size += sizeof(phdr);
2001 if (size > cprm->limit
2002 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
2003 goto end_coredump;
2006 } 2004 }
2007 2005
2008#ifdef ELF_CORE_WRITE_EXTRA_PHDRS 2006 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
2009 ELF_CORE_WRITE_EXTRA_PHDRS; 2007 goto end_coredump;
2010#endif
2011 2008
2012 /* write out the notes section */ 2009 /* write out the notes section */
2013 if (!write_note_info(&info, cprm->file, &foffset)) 2010 if (!write_note_info(&info, cprm->file, &foffset))
@@ -2025,7 +2022,7 @@ static int elf_core_dump(struct coredump_params *cprm)
2025 unsigned long addr; 2022 unsigned long addr;
2026 unsigned long end; 2023 unsigned long end;
2027 2024
2028 end = vma->vm_start + vma_dump_size(vma, mm_flags); 2025 end = vma->vm_start + vma_dump_size(vma, cprm->mm_flags);
2029 2026
2030 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) { 2027 for (addr = vma->vm_start; addr < end; addr += PAGE_SIZE) {
2031 struct page *page; 2028 struct page *page;
@@ -2046,15 +2043,24 @@ static int elf_core_dump(struct coredump_params *cprm)
2046 } 2043 }
2047 } 2044 }
2048 2045
2049#ifdef ELF_CORE_WRITE_EXTRA_DATA 2046 if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
2050 ELF_CORE_WRITE_EXTRA_DATA; 2047 goto end_coredump;
2051#endif 2048
2049 if (e_phnum == PN_XNUM) {
2050 size += sizeof(*shdr4extnum);
2051 if (size > cprm->limit
2052 || !dump_write(cprm->file, shdr4extnum,
2053 sizeof(*shdr4extnum)))
2054 goto end_coredump;
2055 }
2052 2056
2053end_coredump: 2057end_coredump:
2054 set_fs(fs); 2058 set_fs(fs);
2055 2059
2056cleanup: 2060cleanup:
2057 free_note_info(&info); 2061 free_note_info(&info);
2062 kfree(shdr4extnum);
2063 kfree(phdr4note);
2058 kfree(elf); 2064 kfree(elf);
2059out: 2065out:
2060 return has_dumped; 2066 return has_dumped;