|
@@ -1428,6 +1428,32 @@ static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
|
|
|
return sz;
|
|
|
}
|
|
|
|
|
|
+static struct vm_area_struct *first_vma(struct task_struct *tsk,
|
|
|
+ struct vm_area_struct *gate_vma)
|
|
|
+{
|
|
|
+ struct vm_area_struct *ret = tsk->mm->mmap;
|
|
|
+
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ return gate_vma;
|
|
|
+}
|
|
|
+/*
|
|
|
+ * Helper function for iterating across a vma list. It ensures that the caller
|
|
|
+ * will visit `gate_vma' prior to terminating the search.
|
|
|
+ */
|
|
|
+static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
|
|
|
+ struct vm_area_struct *gate_vma)
|
|
|
+{
|
|
|
+ struct vm_area_struct *ret;
|
|
|
+
|
|
|
+ ret = this_vma->vm_next;
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ if (this_vma == gate_vma)
|
|
|
+ return NULL;
|
|
|
+ return gate_vma;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Actual dumper
|
|
|
*
|
|
@@ -1443,7 +1469,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
|
|
|
int segs;
|
|
|
size_t size = 0;
|
|
|
int i;
|
|
|
- struct vm_area_struct *vma;
|
|
|
+ struct vm_area_struct *vma, *gate_vma;
|
|
|
struct elfhdr *elf = NULL;
|
|
|
loff_t offset = 0, dataoff, foffset;
|
|
|
unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
|
|
@@ -1529,6 +1555,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
|
|
|
segs += ELF_CORE_EXTRA_PHDRS;
|
|
|
#endif
|
|
|
|
|
|
+ gate_vma = get_gate_vma(current);
|
|
|
+ if (gate_vma != NULL)
|
|
|
+ segs++;
|
|
|
+
|
|
|
/* Set up header */
|
|
|
fill_elf_header(elf, segs + 1); /* including notes section */
|
|
|
|
|
@@ -1596,7 +1626,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
|
|
|
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
|
|
|
|
|
|
/* Write program headers for segments dump */
|
|
|
- for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
|
|
|
+ for (vma = first_vma(current, gate_vma); vma != NULL;
|
|
|
+ vma = next_vma(vma, gate_vma)) {
|
|
|
struct elf_phdr phdr;
|
|
|
size_t sz;
|
|
|
|
|
@@ -1645,7 +1676,8 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
|
|
|
/* Align to page */
|
|
|
DUMP_SEEK(dataoff - foffset);
|
|
|
|
|
|
- for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
|
|
|
+ for (vma = first_vma(current, gate_vma); vma != NULL;
|
|
|
+ vma = next_vma(vma, gate_vma)) {
|
|
|
unsigned long addr;
|
|
|
|
|
|
if (!maydump(vma))
|