aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_elf_fdpic.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/binfmt_elf_fdpic.c')
-rw-r--r--fs/binfmt_elf_fdpic.c236
1 files changed, 143 insertions, 93 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 38502c67987c..2c5f9a0e5d72 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -34,6 +34,7 @@
34#include <linux/elf.h> 34#include <linux/elf.h>
35#include <linux/elf-fdpic.h> 35#include <linux/elf-fdpic.h>
36#include <linux/elfcore.h> 36#include <linux/elfcore.h>
37#include <linux/coredump.h>
37 38
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
39#include <asm/param.h> 40#include <asm/param.h>
@@ -75,14 +76,14 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *,
75static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *, 76static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *,
76 struct file *, struct mm_struct *); 77 struct file *, struct mm_struct *);
77 78
78#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 79#ifdef CONFIG_ELF_CORE
79static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *, unsigned long limit); 80static int elf_fdpic_core_dump(struct coredump_params *cprm);
80#endif 81#endif
81 82
82static struct linux_binfmt elf_fdpic_format = { 83static struct linux_binfmt elf_fdpic_format = {
83 .module = THIS_MODULE, 84 .module = THIS_MODULE,
84 .load_binary = load_elf_fdpic_binary, 85 .load_binary = load_elf_fdpic_binary,
85#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 86#ifdef CONFIG_ELF_CORE
86 .core_dump = elf_fdpic_core_dump, 87 .core_dump = elf_fdpic_core_dump,
87#endif 88#endif
88 .min_coredump = ELF_EXEC_PAGESIZE, 89 .min_coredump = ELF_EXEC_PAGESIZE,
@@ -171,6 +172,9 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
171#ifdef ELF_FDPIC_PLAT_INIT 172#ifdef ELF_FDPIC_PLAT_INIT
172 unsigned long dynaddr; 173 unsigned long dynaddr;
173#endif 174#endif
175#ifndef CONFIG_MMU
176 unsigned long stack_prot;
177#endif
174 struct file *interpreter = NULL; /* to shut gcc up */ 178 struct file *interpreter = NULL; /* to shut gcc up */
175 char *interpreter_name = NULL; 179 char *interpreter_name = NULL;
176 int executable_stack; 180 int executable_stack;
@@ -316,6 +320,11 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
316 * defunct, deceased, etc. after this point we have to exit via 320 * defunct, deceased, etc. after this point we have to exit via
317 * error_kill */ 321 * error_kill */
318 set_personality(PER_LINUX_FDPIC); 322 set_personality(PER_LINUX_FDPIC);
323 if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
324 current->personality |= READ_IMPLIES_EXEC;
325
326 setup_new_exec(bprm);
327
319 set_binfmt(&elf_fdpic_format); 328 set_binfmt(&elf_fdpic_format);
320 329
321 current->mm->start_code = 0; 330 current->mm->start_code = 0;
@@ -377,10 +386,15 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm,
377 if (stack_size < PAGE_SIZE * 2) 386 if (stack_size < PAGE_SIZE * 2)
378 stack_size = PAGE_SIZE * 2; 387 stack_size = PAGE_SIZE * 2;
379 388
389 stack_prot = PROT_READ | PROT_WRITE;
390 if (executable_stack == EXSTACK_ENABLE_X ||
391 (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
392 stack_prot |= PROT_EXEC;
393
380 down_write(&current->mm->mmap_sem); 394 down_write(&current->mm->mmap_sem);
381 current->mm->start_brk = do_mmap(NULL, 0, stack_size, 395 current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
382 PROT_READ | PROT_WRITE | PROT_EXEC, 396 MAP_PRIVATE | MAP_ANONYMOUS |
383 MAP_PRIVATE | MAP_ANONYMOUS | MAP_GROWSDOWN, 397 MAP_UNINITIALIZED | MAP_GROWSDOWN,
384 0); 398 0);
385 399
386 if (IS_ERR_VALUE(current->mm->start_brk)) { 400 if (IS_ERR_VALUE(current->mm->start_brk)) {
@@ -991,15 +1005,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(
991 } 1005 }
992 } else if (!mm->start_data) { 1006 } else if (!mm->start_data) {
993 mm->start_data = seg->addr; 1007 mm->start_data = seg->addr;
994#ifndef CONFIG_MMU
995 mm->end_data = seg->addr + phdr->p_memsz; 1008 mm->end_data = seg->addr + phdr->p_memsz;
996#endif
997 } 1009 }
998
999#ifdef CONFIG_MMU
1000 if (seg->addr + phdr->p_memsz > mm->end_data)
1001 mm->end_data = seg->addr + phdr->p_memsz;
1002#endif
1003 } 1010 }
1004 1011
1005 seg++; 1012 seg++;
@@ -1200,27 +1207,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1200 * 1207 *
1201 * Modelled on fs/binfmt_elf.c core dumper 1208 * Modelled on fs/binfmt_elf.c core dumper
1202 */ 1209 */
1203#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 1210#ifdef CONFIG_ELF_CORE
1204
1205/*
1206 * These are the only things you should do on a core-file: use only these
1207 * functions to write out all the necessary info.
1208 */
1209static int dump_write(struct file *file, const void *addr, int nr)
1210{
1211 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1212}
1213
1214static int dump_seek(struct file *file, loff_t off)
1215{
1216 if (file->f_op->llseek) {
1217 if (file->f_op->llseek(file, off, SEEK_SET) != off)
1218 return 0;
1219 } else {
1220 file->f_pos = off;
1221 }
1222 return 1;
1223}
1224 1211
1225/* 1212/*
1226 * Decide whether a segment is worth dumping; default is yes to be 1213 * Decide whether a segment is worth dumping; default is yes to be
@@ -1300,34 +1287,35 @@ static int notesize(struct memelfnote *en)
1300 1287
1301/* #define DEBUG */ 1288/* #define DEBUG */
1302 1289
1303#define DUMP_WRITE(addr, nr) \ 1290#define DUMP_WRITE(addr, nr, foffset) \
1304 do { if (!dump_write(file, (addr), (nr))) return 0; } while(0) 1291 do { if (!dump_write(file, (addr), (nr))) return 0; *foffset += (nr); } while(0)
1305#define DUMP_SEEK(off) \
1306 do { if (!dump_seek(file, (off))) return 0; } while(0)
1307 1292
1308static int writenote(struct memelfnote *men, struct file *file) 1293static int alignfile(struct file *file, loff_t *foffset)
1309{ 1294{
1310 struct elf_note en; 1295 static const char buf[4] = { 0, };
1296 DUMP_WRITE(buf, roundup(*foffset, 4) - *foffset, foffset);
1297 return 1;
1298}
1311 1299
1300static int writenote(struct memelfnote *men, struct file *file,
1301 loff_t *foffset)
1302{
1303 struct elf_note en;
1312 en.n_namesz = strlen(men->name) + 1; 1304 en.n_namesz = strlen(men->name) + 1;
1313 en.n_descsz = men->datasz; 1305 en.n_descsz = men->datasz;
1314 en.n_type = men->type; 1306 en.n_type = men->type;
1315 1307
1316 DUMP_WRITE(&en, sizeof(en)); 1308 DUMP_WRITE(&en, sizeof(en), foffset);
1317 DUMP_WRITE(men->name, en.n_namesz); 1309 DUMP_WRITE(men->name, en.n_namesz, foffset);
1318 /* XXX - cast from long long to long to avoid need for libgcc.a */ 1310 if (!alignfile(file, foffset))
1319 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ 1311 return 0;
1320 DUMP_WRITE(men->data, men->datasz); 1312 DUMP_WRITE(men->data, men->datasz, foffset);
1321 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */ 1313 if (!alignfile(file, foffset))
1314 return 0;
1322 1315
1323 return 1; 1316 return 1;
1324} 1317}
1325#undef DUMP_WRITE 1318#undef DUMP_WRITE
1326#undef DUMP_SEEK
1327
1328#define DUMP_WRITE(addr, nr) \
1329 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
1330 goto end_coredump;
1331 1319
1332static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs) 1320static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
1333{ 1321{
@@ -1379,7 +1367,7 @@ static inline void fill_note(struct memelfnote *note, const char *name, int type
1379 1367
1380/* 1368/*
1381 * fill up all the fields in prstatus from the given task struct, except 1369 * fill up all the fields in prstatus from the given task struct, except
1382 * registers which need to be filled up seperately. 1370 * registers which need to be filled up separately.
1383 */ 1371 */
1384static void fill_prstatus(struct elf_prstatus *prstatus, 1372static void fill_prstatus(struct elf_prstatus *prstatus,
1385 struct task_struct *p, long signr) 1373 struct task_struct *p, long signr)
@@ -1510,6 +1498,22 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1510 return sz; 1498 return sz;
1511} 1499}
1512 1500
1501static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
1502 elf_addr_t e_shoff, int segs)
1503{
1504 elf->e_shoff = e_shoff;
1505 elf->e_shentsize = sizeof(*shdr4extnum);
1506 elf->e_shnum = 1;
1507 elf->e_shstrndx = SHN_UNDEF;
1508
1509 memset(shdr4extnum, 0, sizeof(*shdr4extnum));
1510
1511 shdr4extnum->sh_type = SHT_NULL;
1512 shdr4extnum->sh_size = elf->e_shnum;
1513 shdr4extnum->sh_link = elf->e_shstrndx;
1514 shdr4extnum->sh_info = segs;
1515}
1516
1513/* 1517/*
1514 * dump the segments for an MMU process 1518 * dump the segments for an MMU process
1515 */ 1519 */
@@ -1538,7 +1542,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1538 err = -EIO; 1542 err = -EIO;
1539 kunmap(page); 1543 kunmap(page);
1540 page_cache_release(page); 1544 page_cache_release(page);
1541 } else if (!dump_seek(file, file->f_pos + PAGE_SIZE)) 1545 } else if (!dump_seek(file, PAGE_SIZE))
1542 err = -EFBIG; 1546 err = -EFBIG;
1543 if (err) 1547 if (err)
1544 goto out; 1548 goto out;
@@ -1574,6 +1578,17 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1574} 1578}
1575#endif 1579#endif
1576 1580
1581static size_t elf_core_vma_data_size(unsigned long mm_flags)
1582{
1583 struct vm_area_struct *vma;
1584 size_t size = 0;
1585
1586 for (vma = current->mm->mmap; vma; vma = vma->vm_next)
1587 if (maydump(vma, mm_flags))
1588 size += vma->vm_end - vma->vm_start;
1589 return size;
1590}
1591
1577/* 1592/*
1578 * Actual dumper 1593 * Actual dumper
1579 * 1594 *
@@ -1581,8 +1596,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1581 * and then they are actually written out. If we run out of core limit 1596 * and then they are actually written out. If we run out of core limit
1582 * we just truncate. 1597 * we just truncate.
1583 */ 1598 */
1584static int elf_fdpic_core_dump(long signr, struct pt_regs *regs, 1599static int elf_fdpic_core_dump(struct coredump_params *cprm)
1585 struct file *file, unsigned long limit)
1586{ 1600{
1587#define NUM_NOTES 6 1601#define NUM_NOTES 6
1588 int has_dumped = 0; 1602 int has_dumped = 0;
@@ -1592,7 +1606,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1592 int i; 1606 int i;
1593 struct vm_area_struct *vma; 1607 struct vm_area_struct *vma;
1594 struct elfhdr *elf = NULL; 1608 struct elfhdr *elf = NULL;
1595 loff_t offset = 0, dataoff; 1609 loff_t offset = 0, dataoff, foffset;
1596 int numnote; 1610 int numnote;
1597 struct memelfnote *notes = NULL; 1611 struct memelfnote *notes = NULL;
1598 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */ 1612 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
@@ -1605,7 +1619,10 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1605#endif 1619#endif
1606 int thread_status_size = 0; 1620 int thread_status_size = 0;
1607 elf_addr_t *auxv; 1621 elf_addr_t *auxv;
1608 unsigned long mm_flags; 1622 struct elf_phdr *phdr4note = NULL;
1623 struct elf_shdr *shdr4extnum = NULL;
1624 Elf_Half e_phnum;
1625 elf_addr_t e_shoff;
1609 1626
1610 /* 1627 /*
1611 * We no longer stop all VM operations. 1628 * We no longer stop all VM operations.
@@ -1641,7 +1658,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1641 goto cleanup; 1658 goto cleanup;
1642#endif 1659#endif
1643 1660
1644 if (signr) { 1661 if (cprm->signr) {
1645 struct core_thread *ct; 1662 struct core_thread *ct;
1646 struct elf_thread_status *tmp; 1663 struct elf_thread_status *tmp;
1647 1664
@@ -1660,22 +1677,28 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1660 int sz; 1677 int sz;
1661 1678
1662 tmp = list_entry(t, struct elf_thread_status, list); 1679 tmp = list_entry(t, struct elf_thread_status, list);
1663 sz = elf_dump_thread_status(signr, tmp); 1680 sz = elf_dump_thread_status(cprm->signr, tmp);
1664 thread_status_size += sz; 1681 thread_status_size += sz;
1665 } 1682 }
1666 } 1683 }
1667 1684
1668 /* now collect the dump for the current */ 1685 /* now collect the dump for the current */
1669 fill_prstatus(prstatus, current, signr); 1686 fill_prstatus(prstatus, current, cprm->signr);
1670 elf_core_copy_regs(&prstatus->pr_reg, regs); 1687 elf_core_copy_regs(&prstatus->pr_reg, cprm->regs);
1671 1688
1672 segs = current->mm->map_count; 1689 segs = current->mm->map_count;
1673#ifdef ELF_CORE_EXTRA_PHDRS 1690 segs += elf_core_extra_phdrs();
1674 segs += ELF_CORE_EXTRA_PHDRS; 1691
1675#endif 1692 /* for notes section */
1693 segs++;
1694
1695 /* If segs > PN_XNUM(0xffff), then e_phnum overflows. To avoid
1696 * this, kernel supports extended numbering. Have a look at
1697 * include/linux/elf.h for further information. */
1698 e_phnum = segs > PN_XNUM ? PN_XNUM : segs;
1676 1699
1677 /* Set up header */ 1700 /* Set up header */
1678 fill_elf_fdpic_header(elf, segs + 1); /* including notes section */ 1701 fill_elf_fdpic_header(elf, e_phnum);
1679 1702
1680 has_dumped = 1; 1703 has_dumped = 1;
1681 current->flags |= PF_DUMPCORE; 1704 current->flags |= PF_DUMPCORE;
@@ -1702,7 +1725,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1702 1725
1703 /* Try to dump the FPU. */ 1726 /* Try to dump the FPU. */
1704 if ((prstatus->pr_fpvalid = 1727 if ((prstatus->pr_fpvalid =
1705 elf_core_copy_task_fpregs(current, regs, fpu))) 1728 elf_core_copy_task_fpregs(current, cprm->regs, fpu)))
1706 fill_note(notes + numnote++, 1729 fill_note(notes + numnote++,
1707 "CORE", NT_PRFPREG, sizeof(*fpu), fpu); 1730 "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
1708#ifdef ELF_CORE_COPY_XFPREGS 1731#ifdef ELF_CORE_COPY_XFPREGS
@@ -1714,13 +1737,12 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1714 fs = get_fs(); 1737 fs = get_fs();
1715 set_fs(KERNEL_DS); 1738 set_fs(KERNEL_DS);
1716 1739
1717 DUMP_WRITE(elf, sizeof(*elf));
1718 offset += sizeof(*elf); /* Elf header */ 1740 offset += sizeof(*elf); /* Elf header */
1719 offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */ 1741 offset += segs * sizeof(struct elf_phdr); /* Program headers */
1742 foffset = offset;
1720 1743
1721 /* Write notes phdr entry */ 1744 /* Write notes phdr entry */
1722 { 1745 {
1723 struct elf_phdr phdr;
1724 int sz = 0; 1746 int sz = 0;
1725 1747
1726 for (i = 0; i < numnote; i++) 1748 for (i = 0; i < numnote; i++)
@@ -1728,20 +1750,38 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1728 1750
1729 sz += thread_status_size; 1751 sz += thread_status_size;
1730 1752
1731 fill_elf_note_phdr(&phdr, sz, offset); 1753 phdr4note = kmalloc(sizeof(*phdr4note), GFP_KERNEL);
1754 if (!phdr4note)
1755 goto end_coredump;
1756
1757 fill_elf_note_phdr(phdr4note, sz, offset);
1732 offset += sz; 1758 offset += sz;
1733 DUMP_WRITE(&phdr, sizeof(phdr));
1734 } 1759 }
1735 1760
1736 /* Page-align dumped data */ 1761 /* Page-align dumped data */
1737 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1762 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1738 1763
1739 /* 1764 offset += elf_core_vma_data_size(cprm->mm_flags);
1740 * We must use the same mm->flags while dumping core to avoid 1765 offset += elf_core_extra_data_size();
1741 * inconsistency between the program headers and bodies, otherwise an 1766 e_shoff = offset;
1742 * unusable core file can be generated. 1767
1743 */ 1768 if (e_phnum == PN_XNUM) {
1744 mm_flags = current->mm->flags; 1769 shdr4extnum = kmalloc(sizeof(*shdr4extnum), GFP_KERNEL);
1770 if (!shdr4extnum)
1771 goto end_coredump;
1772 fill_extnum_info(elf, shdr4extnum, e_shoff, segs);
1773 }
1774
1775 offset = dataoff;
1776
1777 size += sizeof(*elf);
1778 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
1779 goto end_coredump;
1780
1781 size += sizeof(*phdr4note);
1782 if (size > cprm->limit
1783 || !dump_write(cprm->file, phdr4note, sizeof(*phdr4note)))
1784 goto end_coredump;
1745 1785
1746 /* write program headers for segments dump */ 1786 /* write program headers for segments dump */
1747 for (vma = current->mm->mmap; vma; vma = vma->vm_next) { 1787 for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
@@ -1754,7 +1794,7 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1754 phdr.p_offset = offset; 1794 phdr.p_offset = offset;
1755 phdr.p_vaddr = vma->vm_start; 1795 phdr.p_vaddr = vma->vm_start;
1756 phdr.p_paddr = 0; 1796 phdr.p_paddr = 0;
1757 phdr.p_filesz = maydump(vma, mm_flags) ? sz : 0; 1797 phdr.p_filesz = maydump(vma, cprm->mm_flags) ? sz : 0;
1758 phdr.p_memsz = sz; 1798 phdr.p_memsz = sz;
1759 offset += phdr.p_filesz; 1799 offset += phdr.p_filesz;
1760 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0; 1800 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
@@ -1764,16 +1804,18 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1764 phdr.p_flags |= PF_X; 1804 phdr.p_flags |= PF_X;
1765 phdr.p_align = ELF_EXEC_PAGESIZE; 1805 phdr.p_align = ELF_EXEC_PAGESIZE;
1766 1806
1767 DUMP_WRITE(&phdr, sizeof(phdr)); 1807 size += sizeof(phdr);
1808 if (size > cprm->limit
1809 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
1810 goto end_coredump;
1768 } 1811 }
1769 1812
1770#ifdef ELF_CORE_WRITE_EXTRA_PHDRS 1813 if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit))
1771 ELF_CORE_WRITE_EXTRA_PHDRS; 1814 goto end_coredump;
1772#endif
1773 1815
1774 /* write out the notes section */ 1816 /* write out the notes section */
1775 for (i = 0; i < numnote; i++) 1817 for (i = 0; i < numnote; i++)
1776 if (!writenote(notes + i, file)) 1818 if (!writenote(notes + i, cprm->file, &foffset))
1777 goto end_coredump; 1819 goto end_coredump;
1778 1820
1779 /* write out the thread status notes section */ 1821 /* write out the thread status notes section */
@@ -1782,25 +1824,33 @@ static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1782 list_entry(t, struct elf_thread_status, list); 1824 list_entry(t, struct elf_thread_status, list);
1783 1825
1784 for (i = 0; i < tmp->num_notes; i++) 1826 for (i = 0; i < tmp->num_notes; i++)
1785 if (!writenote(&tmp->notes[i], file)) 1827 if (!writenote(&tmp->notes[i], cprm->file, &foffset))
1786 goto end_coredump; 1828 goto end_coredump;
1787 } 1829 }
1788 1830
1789 if (!dump_seek(file, dataoff)) 1831 if (!dump_seek(cprm->file, dataoff - foffset))
1790 goto end_coredump; 1832 goto end_coredump;
1791 1833
1792 if (elf_fdpic_dump_segments(file, &size, &limit, mm_flags) < 0) 1834 if (elf_fdpic_dump_segments(cprm->file, &size, &cprm->limit,
1835 cprm->mm_flags) < 0)
1793 goto end_coredump; 1836 goto end_coredump;
1794 1837
1795#ifdef ELF_CORE_WRITE_EXTRA_DATA 1838 if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit))
1796 ELF_CORE_WRITE_EXTRA_DATA; 1839 goto end_coredump;
1797#endif
1798 1840
1799 if (file->f_pos != offset) { 1841 if (e_phnum == PN_XNUM) {
1842 size += sizeof(*shdr4extnum);
1843 if (size > cprm->limit
1844 || !dump_write(cprm->file, shdr4extnum,
1845 sizeof(*shdr4extnum)))
1846 goto end_coredump;
1847 }
1848
1849 if (cprm->file->f_pos != offset) {
1800 /* Sanity check */ 1850 /* Sanity check */
1801 printk(KERN_WARNING 1851 printk(KERN_WARNING
1802 "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n", 1852 "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n",
1803 file->f_pos, offset); 1853 cprm->file->f_pos, offset);
1804 } 1854 }
1805 1855
1806end_coredump: 1856end_coredump:
@@ -1812,7 +1862,7 @@ cleanup:
1812 list_del(tmp); 1862 list_del(tmp);
1813 kfree(list_entry(tmp, struct elf_thread_status, list)); 1863 kfree(list_entry(tmp, struct elf_thread_status, list));
1814 } 1864 }
1815 1865 kfree(phdr4note);
1816 kfree(elf); 1866 kfree(elf);
1817 kfree(prstatus); 1867 kfree(prstatus);
1818 kfree(psinfo); 1868 kfree(psinfo);
@@ -1825,4 +1875,4 @@ cleanup:
1825#undef NUM_NOTES 1875#undef NUM_NOTES
1826} 1876}
1827 1877
1828#endif /* USE_ELF_CORE_DUMP */ 1878#endif /* CONFIG_ELF_CORE */