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.c52
1 files changed, 14 insertions, 38 deletions
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index fd5b2ea5d299..0bcfbb05c32d 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>
@@ -1085,36 +1086,6 @@ out:
1085 * Modelled on fs/exec.c:aout_core_dump() 1086 * Modelled on fs/exec.c:aout_core_dump()
1086 * Jeremy Fitzhardinge <jeremy@sw.oz.au> 1087 * Jeremy Fitzhardinge <jeremy@sw.oz.au>
1087 */ 1088 */
1088/*
1089 * These are the only things you should do on a core-file: use only these
1090 * functions to write out all the necessary info.
1091 */
1092static int dump_write(struct file *file, const void *addr, int nr)
1093{
1094 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1095}
1096
1097static int dump_seek(struct file *file, loff_t off)
1098{
1099 if (file->f_op->llseek && file->f_op->llseek != no_llseek) {
1100 if (file->f_op->llseek(file, off, SEEK_CUR) < 0)
1101 return 0;
1102 } else {
1103 char *buf = (char *)get_zeroed_page(GFP_KERNEL);
1104 if (!buf)
1105 return 0;
1106 while (off > 0) {
1107 unsigned long n = off;
1108 if (n > PAGE_SIZE)
1109 n = PAGE_SIZE;
1110 if (!dump_write(file, buf, n))
1111 return 0;
1112 off -= n;
1113 }
1114 free_page((unsigned long)buf);
1115 }
1116 return 1;
1117}
1118 1089
1119/* 1090/*
1120 * Decide what to dump of a segment, part, all or none. 1091 * Decide what to dump of a segment, part, all or none.
@@ -1249,11 +1220,6 @@ static int writenote(struct memelfnote *men, struct file *file,
1249} 1220}
1250#undef DUMP_WRITE 1221#undef DUMP_WRITE
1251 1222
1252#define DUMP_WRITE(addr, nr) \
1253 if ((size += (nr)) > cprm->limit || \
1254 !dump_write(cprm->file, (addr), (nr))) \
1255 goto end_coredump;
1256
1257static void fill_elf_header(struct elfhdr *elf, int segs, 1223static void fill_elf_header(struct elfhdr *elf, int segs,
1258 u16 machine, u32 flags, u8 osabi) 1224 u16 machine, u32 flags, u8 osabi)
1259{ 1225{
@@ -1934,7 +1900,10 @@ static int elf_core_dump(struct coredump_params *cprm)
1934 fs = get_fs(); 1900 fs = get_fs();
1935 set_fs(KERNEL_DS); 1901 set_fs(KERNEL_DS);
1936 1902
1937 DUMP_WRITE(elf, sizeof(*elf)); 1903 size += sizeof(*elf);
1904 if (size > cprm->limit || !dump_write(cprm->file, elf, sizeof(*elf)))
1905 goto end_coredump;
1906
1938 offset += sizeof(*elf); /* Elf header */ 1907 offset += sizeof(*elf); /* Elf header */
1939 offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */ 1908 offset += (segs + 1) * sizeof(struct elf_phdr); /* Program headers */
1940 foffset = offset; 1909 foffset = offset;
@@ -1948,7 +1917,11 @@ static int elf_core_dump(struct coredump_params *cprm)
1948 1917
1949 fill_elf_note_phdr(&phdr, sz, offset); 1918 fill_elf_note_phdr(&phdr, sz, offset);
1950 offset += sz; 1919 offset += sz;
1951 DUMP_WRITE(&phdr, sizeof(phdr)); 1920
1921 size += sizeof(phdr);
1922 if (size > cprm->limit
1923 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
1924 goto end_coredump;
1952 } 1925 }
1953 1926
1954 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE); 1927 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
@@ -1979,7 +1952,10 @@ static int elf_core_dump(struct coredump_params *cprm)
1979 phdr.p_flags |= PF_X; 1952 phdr.p_flags |= PF_X;
1980 phdr.p_align = ELF_EXEC_PAGESIZE; 1953 phdr.p_align = ELF_EXEC_PAGESIZE;
1981 1954
1982 DUMP_WRITE(&phdr, sizeof(phdr)); 1955 size += sizeof(phdr);
1956 if (size > cprm->limit
1957 || !dump_write(cprm->file, &phdr, sizeof(phdr)))
1958 goto end_coredump;
1983 } 1959 }
1984 1960
1985#ifdef ELF_CORE_WRITE_EXTRA_PHDRS 1961#ifdef ELF_CORE_WRITE_EXTRA_PHDRS