Skip to content

Commit

Permalink
coredump: Only sort VMAs when core_sort_vma sysctl is set
Browse files Browse the repository at this point in the history
The sorting of VMAs by size in commit 7d442a3 ("binfmt_elf: Dump
smaller VMAs first in ELF cores") breaks elfutils[1]. Instead, sort
based on the setting of the new sysctl, core_sort_vma, which defaults
to 0, no sorting.

Reported-by: Michael Stapelberg <michael@stapelberg.ch>
Closes: https://lore.kernel.org/all/20250218085407.61126-1-michael@stapelberg.de/ [1]
Fixes: 7d442a3 ("binfmt_elf: Dump smaller VMAs first in ELF cores")
Signed-off-by: Kees Cook <kees@kernel.org>
  • Loading branch information
Kees Cook committed Feb 24, 2025
1 parent a64dcfb commit 39ec9ea
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 2 deletions.
11 changes: 11 additions & 0 deletions Documentation/admin-guide/sysctl/kernel.rst
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,17 @@ pid>/``).
This value defaults to 0.

core_sort_vma
=============

The default coredump writes VMAs in address order. By setting
``core_sort_vma`` to 1, VMAs will be written from smallest size
to largest size. This is known to break at least elfutils, but
can be handy when dealing with very large (and truncated)
coredumps where the more useful debugging details are included
in the smaller VMAs.


core_uses_pid
=============

Expand Down
15 changes: 13 additions & 2 deletions fs/coredump.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ static void free_vma_snapshot(struct coredump_params *cprm);

static int core_uses_pid;
static unsigned int core_pipe_limit;
static unsigned int core_sort_vma;
static char core_pattern[CORENAME_MAX_SIZE] = "core";
static int core_name_size = CORENAME_MAX_SIZE;
unsigned int core_file_note_size_limit = CORE_FILE_NOTE_SIZE_DEFAULT;
Expand Down Expand Up @@ -1026,6 +1027,15 @@ static const struct ctl_table coredump_sysctls[] = {
.extra1 = (unsigned int *)&core_file_note_size_min,
.extra2 = (unsigned int *)&core_file_note_size_max,
},
{
.procname = "core_sort_vma",
.data = &core_sort_vma,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_douintvec_minmax,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE,
},
};

static int __init init_fs_coredump_sysctls(void)
Expand Down Expand Up @@ -1256,8 +1266,9 @@ static bool dump_vma_snapshot(struct coredump_params *cprm)
cprm->vma_data_size += m->dump_size;
}

sort(cprm->vma_meta, cprm->vma_count, sizeof(*cprm->vma_meta),
cmp_vma_size, NULL);
if (core_sort_vma)
sort(cprm->vma_meta, cprm->vma_count, sizeof(*cprm->vma_meta),
cmp_vma_size, NULL);

return true;
}

0 comments on commit 39ec9ea

Please sign in to comment.