diff options
Diffstat (limited to 'fs/binfmt_elf.c')
-rw-r--r-- | fs/binfmt_elf.c | 52 |
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 | */ | ||
1092 | static 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 | |||
1097 | static 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 | |||
1257 | static void fill_elf_header(struct elfhdr *elf, int segs, | 1223 | static 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 |