Skip to content

Commit

Permalink
Revert "coredump: Snapshot the vmas in do_coredump"
Browse files Browse the repository at this point in the history
This reverts commit 936c8be.

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
  • Loading branch information
gregkh committed Apr 20, 2022
1 parent b7dbb1e commit 8f4bd2a
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 39 deletions.
20 changes: 13 additions & 7 deletions fs/binfmt_elf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2166,20 +2166,25 @@ 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 = { };
struct elf_phdr *phdr4note = NULL;
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++;
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
18 changes: 12 additions & 6 deletions fs/binfmt_elf_fdpic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand All @@ -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,
Expand All @@ -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++;
Expand Down Expand Up @@ -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;

Expand All @@ -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;

Expand Down Expand Up @@ -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))
Expand All @@ -1662,6 +1667,7 @@ static int elf_fdpic_core_dump(struct coredump_params *cprm)
thread_list = thread_list->next;
kfree(tmp);
}
kvfree(vma_meta);
kfree(phdr4note);
kfree(elf);
kfree(psinfo);
Expand Down
41 changes: 18 additions & 23 deletions fs/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1092,33 +1085,35 @@ 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
* under mmap_lock in read mode, this can be changed to take the
* 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;
Expand All @@ -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];
Expand All @@ -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;
}
3 changes: 0 additions & 3 deletions include/linux/binfmts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

/*
Expand Down
3 changes: 3 additions & 0 deletions include/linux/coredump.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8f4bd2a

Please sign in to comment.