Revert "coredump: Snapshot the vmas in do_coredump"

This reverts commit 936c8be4d1.

It breaks the abi and is not needed for Android devices so it can be
dropped.

Bug: 161946584
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Change-Id: I2af6e8472f55475bbb841e04ad18a84fdd2d9379
This commit is contained in:
Greg Kroah-Hartman
2022-04-19 18:41:47 +02:00
parent b7dbb1ee1f
commit 8f4bd2a63f
5 changed files with 46 additions and 39 deletions

View File

@@ -2166,7 +2166,8 @@ static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
static int elf_core_dump(struct coredump_params *cprm)
{
int has_dumped = 0;
int segs, i;
int vma_count, segs, i;
size_t vma_data_size;
struct elfhdr elf;
loff_t offset = 0, dataoff;
struct elf_note_info info = { };
@@ -2174,12 +2175,16 @@ static int elf_core_dump(struct coredump_params *cprm)
struct elf_shdr *shdr4extnum = NULL;
Elf_Half e_phnum;
elf_addr_t e_shoff;
struct core_vma_metadata *vma_meta;
if (dump_vma_snapshot(cprm, &vma_count, &vma_meta, &vma_data_size))
return 0;
/*
* The number of segs are recored into ELF header as 16bit value.
* Please check DEFAULT_MAX_MAP_COUNT definition when you modify here.
*/
segs = cprm->vma_count + elf_core_extra_phdrs();
segs = vma_count + elf_core_extra_phdrs();
/* for notes section */
segs++;
@@ -2217,7 +2222,7 @@ static int elf_core_dump(struct coredump_params *cprm)
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
offset += cprm->vma_data_size;
offset += vma_data_size;
offset += elf_core_extra_data_size();
e_shoff = offset;
@@ -2237,8 +2242,8 @@ static int elf_core_dump(struct coredump_params *cprm)
goto end_coredump;
/* Write program headers for segments dump */
for (i = 0; i < cprm->vma_count; i++) {
struct core_vma_metadata *meta = cprm->vma_meta + i;
for (i = 0; i < vma_count; i++) {
struct core_vma_metadata *meta = vma_meta + i;
struct elf_phdr phdr;
phdr.p_type = PT_LOAD;
@@ -2275,8 +2280,8 @@ static int elf_core_dump(struct coredump_params *cprm)
if (!dump_skip(cprm, dataoff - cprm->pos))
goto end_coredump;
for (i = 0; i < cprm->vma_count; i++) {
struct core_vma_metadata *meta = cprm->vma_meta + i;
for (i = 0; i < vma_count; i++) {
struct core_vma_metadata *meta = vma_meta + i;
if (!dump_user_range(cprm, meta->start, meta->dump_size))
goto end_coredump;
@@ -2294,6 +2299,7 @@ static int elf_core_dump(struct coredump_params *cprm)
end_coredump:
free_note_info(&info);
kfree(shdr4extnum);
kvfree(vma_meta);
kfree(phdr4note);
return has_dumped;
}

View File

@@ -1479,7 +1479,7 @@ static bool elf_fdpic_dump_segments(struct coredump_params *cprm,
static int elf_fdpic_core_dump(struct coredump_params *cprm)
{
int has_dumped = 0;
int segs;
int vma_count, segs;
int i;
struct elfhdr *elf = NULL;
loff_t offset = 0, dataoff;
@@ -1494,6 +1494,8 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
elf_addr_t e_shoff;
struct core_thread *ct;
struct elf_thread_status *tmp;
struct core_vma_metadata *vma_meta = NULL;
size_t vma_data_size;
/* alloc memory for large data structures: too large to be on stack */
elf = kmalloc(sizeof(*elf), GFP_KERNEL);
@@ -1503,6 +1505,9 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
if (!psinfo)
goto end_coredump;
if (dump_vma_snapshot(cprm, &vma_count, &vma_meta, &vma_data_size))
goto end_coredump;
for (ct = current->mm->core_state->dumper.next;
ct; ct = ct->next) {
tmp = elf_dump_thread_status(cprm->siginfo->si_signo,
@@ -1522,7 +1527,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
tmp->next = thread_list;
thread_list = tmp;
segs = cprm->vma_count + elf_core_extra_phdrs();
segs = vma_count + elf_core_extra_phdrs();
/* for notes section */
segs++;
@@ -1567,7 +1572,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
/* Page-align dumped data */
dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
offset += cprm->vma_data_size;
offset += vma_data_size;
offset += elf_core_extra_data_size();
e_shoff = offset;
@@ -1587,8 +1592,8 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
goto end_coredump;
/* write program headers for segments dump */
for (i = 0; i < cprm->vma_count; i++) {
struct core_vma_metadata *meta = cprm->vma_meta + i;
for (i = 0; i < vma_count; i++) {
struct core_vma_metadata *meta = vma_meta + i;
struct elf_phdr phdr;
size_t sz;
@@ -1638,7 +1643,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
if (!dump_skip(cprm, dataoff - cprm->pos))
goto end_coredump;
if (!elf_fdpic_dump_segments(cprm, cprm->vma_meta, cprm->vma_count))
if (!elf_fdpic_dump_segments(cprm, vma_meta, vma_count))
goto end_coredump;
if (!elf_core_write_extra_data(cprm))
@@ -1662,6 +1667,7 @@ end_coredump:
thread_list = thread_list->next;
kfree(tmp);
}
kvfree(vma_meta);
kfree(phdr4note);
kfree(elf);
kfree(psinfo);

View File

@@ -53,8 +53,6 @@
#include <trace/events/sched.h>
static bool dump_vma_snapshot(struct coredump_params *cprm);
int core_uses_pid;
unsigned int core_pipe_limit;
char core_pattern[CORENAME_MAX_SIZE] = "core";
@@ -604,7 +602,6 @@ void do_coredump(const kernel_siginfo_t *siginfo)
* by any locks.
*/
.mm_flags = mm->flags,
.vma_meta = NULL,
};
audit_core_dumps(siginfo->si_signo);
@@ -810,13 +807,9 @@ void do_coredump(const kernel_siginfo_t *siginfo)
pr_info("Core dump to |%s disabled\n", cn.corename);
goto close_fail;
}
if (!dump_vma_snapshot(&cprm))
goto close_fail;
file_start_write(cprm.file);
core_dumped = binfmt->core_dump(&cprm);
file_end_write(cprm.file);
kvfree(cprm.vma_meta);
}
if (ispipe && core_pipe_limit)
wait_for_dump_helpers(cprm.file);
@@ -1092,11 +1085,14 @@ static struct vm_area_struct *next_vma(struct vm_area_struct *this_vma,
* Under the mmap_lock, take a snapshot of relevant information about the task's
* VMAs.
*/
static bool dump_vma_snapshot(struct coredump_params *cprm)
int dump_vma_snapshot(struct coredump_params *cprm, int *vma_count,
struct core_vma_metadata **vma_meta,
size_t *vma_data_size_ptr)
{
struct vm_area_struct *vma, *gate_vma;
struct mm_struct *mm = current->mm;
int i;
size_t vma_data_size = 0;
/*
* Once the stack expansion code is fixed to not change VMA bounds
@@ -1104,21 +1100,20 @@ static bool dump_vma_snapshot(struct coredump_params *cprm)
* mmap_lock in read mode.
*/
if (mmap_write_lock_killable(mm))
return false;
return -EINTR;
cprm->vma_data_size = 0;
gate_vma = get_gate_vma(mm);
cprm->vma_count = mm->map_count + (gate_vma ? 1 : 0);
*vma_count = mm->map_count + (gate_vma ? 1 : 0);
cprm->vma_meta = kvmalloc_array(cprm->vma_count, sizeof(*cprm->vma_meta), GFP_KERNEL);
if (!cprm->vma_meta) {
*vma_meta = kvmalloc_array(*vma_count, sizeof(**vma_meta), GFP_KERNEL);
if (!*vma_meta) {
mmap_write_unlock(mm);
return false;
return -ENOMEM;
}
for (i = 0, vma = first_vma(current, gate_vma); vma != NULL;
vma = next_vma(vma, gate_vma), i++) {
struct core_vma_metadata *m = cprm->vma_meta + i;
struct core_vma_metadata *m = (*vma_meta) + i;
m->start = vma->vm_start;
m->end = vma->vm_end;
@@ -1128,14 +1123,13 @@ static bool dump_vma_snapshot(struct coredump_params *cprm)
mmap_write_unlock(mm);
if (WARN_ON(i != cprm->vma_count)) {
kvfree(cprm->vma_meta);
return false;
if (WARN_ON(i != *vma_count)) {
kvfree(*vma_meta);
return -EFAULT;
}
for (i = 0; i < cprm->vma_count; i++) {
struct core_vma_metadata *m = cprm->vma_meta + i;
for (i = 0; i < *vma_count; i++) {
struct core_vma_metadata *m = (*vma_meta) + i;
if (m->dump_size == DUMP_SIZE_MAYBE_ELFHDR_PLACEHOLDER) {
char elfmag[SELFMAG];
@@ -1148,8 +1142,9 @@ static bool dump_vma_snapshot(struct coredump_params *cprm)
}
}
cprm->vma_data_size += m->dump_size;
vma_data_size += m->dump_size;
}
return true;
*vma_data_size_ptr = vma_data_size;
return 0;
}

View File

@@ -82,9 +82,6 @@ struct coredump_params {
unsigned long mm_flags;
loff_t written;
loff_t pos;
int vma_count;
size_t vma_data_size;
struct core_vma_metadata *vma_meta;
};
/*

View File

@@ -24,6 +24,9 @@ extern int dump_align(struct coredump_params *cprm, int align);
extern void dump_truncate(struct coredump_params *cprm);
int dump_user_range(struct coredump_params *cprm, unsigned long start,
unsigned long len);
int dump_vma_snapshot(struct coredump_params *cprm, int *vma_count,
struct core_vma_metadata **vma_meta,
size_t *vma_data_size_ptr);
#ifdef CONFIG_COREDUMP
extern void do_coredump(const kernel_siginfo_t *siginfo);
#else