Commit ec0063b4 authored by Suleiman Souhlal's avatar Suleiman Souhlal Committed by Linus Torvalds

[PATCH] x86_64: Don't write out segments from vsyscall32 DSO if it is not mapped

It's possible to get an invalid page fault in kernel mode when we try to
write out segments from vsyscall32 when dumping core for a 32bit process if
the vsyscall32 DSO is not mapped in its address space (which can happen if,
for example, ulimit -v 100 is run).
Signed-off-by: default avatarSuleiman Souhlal <suleiman@google.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 01ebb77b
...@@ -73,39 +73,44 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; ...@@ -73,39 +73,44 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
* Dumping its extra ELF program headers includes all the other information * Dumping its extra ELF program headers includes all the other information
* a debugger needs to easily find how the vsyscall DSO was being used. * a debugger needs to easily find how the vsyscall DSO was being used.
*/ */
#define ELF_CORE_EXTRA_PHDRS (VSYSCALL32_EHDR->e_phnum) #define ELF_CORE_EXTRA_PHDRS (find_vma(current->mm, VSYSCALL32_BASE) ? \
(VSYSCALL32_EHDR->e_phnum) : 0)
#define ELF_CORE_WRITE_EXTRA_PHDRS \ #define ELF_CORE_WRITE_EXTRA_PHDRS \
do { \ do { \
const struct elf32_phdr *const vsyscall_phdrs = \ if (find_vma(current->mm, VSYSCALL32_BASE)) { \
(const struct elf32_phdr *) (VSYSCALL32_BASE \ const struct elf32_phdr *const vsyscall_phdrs = \
+ VSYSCALL32_EHDR->e_phoff); \ (const struct elf32_phdr *) (VSYSCALL32_BASE \
int i; \ + VSYSCALL32_EHDR->e_phoff);\
Elf32_Off ofs = 0; \ int i; \
for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ Elf32_Off ofs = 0; \
struct elf32_phdr phdr = vsyscall_phdrs[i]; \ for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \
if (phdr.p_type == PT_LOAD) { \ struct elf32_phdr phdr = vsyscall_phdrs[i]; \
BUG_ON(ofs != 0); \ if (phdr.p_type == PT_LOAD) { \
ofs = phdr.p_offset = offset; \ BUG_ON(ofs != 0); \
phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ ofs = phdr.p_offset = offset; \
phdr.p_filesz = phdr.p_memsz; \ phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \
offset += phdr.p_filesz; \ phdr.p_filesz = phdr.p_memsz; \
offset += phdr.p_filesz; \
} \
else \
phdr.p_offset += ofs; \
phdr.p_paddr = 0; /* match other core phdrs */ \
DUMP_WRITE(&phdr, sizeof(phdr)); \
} \ } \
else \
phdr.p_offset += ofs; \
phdr.p_paddr = 0; /* match other core phdrs */ \
DUMP_WRITE(&phdr, sizeof(phdr)); \
} \ } \
} while (0) } while (0)
#define ELF_CORE_WRITE_EXTRA_DATA \ #define ELF_CORE_WRITE_EXTRA_DATA \
do { \ do { \
const struct elf32_phdr *const vsyscall_phdrs = \ if (find_vma(current->mm, VSYSCALL32_BASE)) { \
(const struct elf32_phdr *) (VSYSCALL32_BASE \ const struct elf32_phdr *const vsyscall_phdrs = \
+ VSYSCALL32_EHDR->e_phoff); \ (const struct elf32_phdr *) (VSYSCALL32_BASE \
int i; \ + VSYSCALL32_EHDR->e_phoff); \
for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \ int i; \
if (vsyscall_phdrs[i].p_type == PT_LOAD) \ for (i = 0; i < VSYSCALL32_EHDR->e_phnum; ++i) { \
DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr, \ if (vsyscall_phdrs[i].p_type == PT_LOAD) \
PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \ DUMP_WRITE((void *) (u64) vsyscall_phdrs[i].p_vaddr,\
PAGE_ALIGN(vsyscall_phdrs[i].p_memsz)); \
} \
} \ } \
} while (0) } while (0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment