From 44821d05860198705db20d4e64d5614a590b15c7 Mon Sep 17 00:00:00 2001 From: Mikhail Zaslonko Date: Wed, 1 Jul 2026 09:59:29 +0200 Subject: [PATCH] zdump/dfo_elf: Include vmcoreinfo note size in ELF header allocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dfo_elf_init() allocates the output ELF header buffer based on HDR_BASE_SIZE, per-CPU note sizes, and per-memory-chunk overhead, but does not account for the vmcoreinfo note. notes_init() then writes the full vmcoreinfo string into the buffer via nt_vmcoreinfo(), overflowing the heap allocation for any dump with a vmcoreinfo blob larger than what fits in HDR_BASE_SIZE. The following ABORT check fires after the heap was already corrupted. Fix by extracting the allocation size calculation into a new hdr_alloc_size() function that explicitly accounts for all items written into the header buffer. Remove the opaque HDR_BASE_SIZE and HDR_PER_MEMC_SIZE macros. Signed-off-by: Mikhail Zaslonko Reviewed-by: Alexander Egorenkov Signed-off-by: Jan Höppner --- zdump/dfo_elf.c | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/zdump/dfo_elf.c b/zdump/dfo_elf.c index eab46135..34106aa6 100644 --- a/zdump/dfo_elf.c +++ b/zdump/dfo_elf.c @@ -23,9 +23,6 @@ #include "dfi_vmcoreinfo.h" #include "dfo.h" -#define HDR_PER_MEMC_SIZE 0x100 -#define HDR_BASE_SIZE 0x2000 - /* * Initialize ELF loads program headers */ @@ -112,6 +109,28 @@ static void dump_chunks_init(void *hdr, u64 hdr_size) } } +/* + * Calculate the size of the ELF header buffer. + * + * The buffer contains the following fixed-size items: + * - Elf64_Ehdr + * - PT_NOTE program header (1x Elf64_Phdr) + * - prpsinfo note + * Plus variable-size items: + * - PT_LOAD program headers (one Elf64_Phdr per memory chunk) + * - per-CPU notes + * - vmcoreinfo note (if present) + */ +static u32 hdr_alloc_size(const char *vmcoreinfo) +{ + return sizeof(Elf64_Ehdr) + + sizeof(Elf64_Phdr) + + ELF64_NOTE_SIZE(NOTE_NAME_CORE, sizeof(struct nt_prpsinfo_64)) + + dfi_mem_chunk_cnt() * sizeof(Elf64_Phdr) + + dfi_cpu_cnt() * get_max_note_size_per_cpu() + + (vmcoreinfo ? ELF64_NOTE_SIZE(NOTE_NAME_VMCOREINFO, strlen(vmcoreinfo)) : 0); +} + /* * Initialize ELF output dump format */ @@ -121,10 +140,10 @@ static void dfo_elf_init(void) u32 alloc_size; void *buf, *ptr; u64 hdr_off; + const char *vmcoreinfo = dfi_vmcoreinfo_get(); df_elf_ensure_s390x(); - alloc_size = HDR_BASE_SIZE + dfi_cpu_cnt() * get_max_note_size_per_cpu() + - dfi_mem_chunk_cnt() * HDR_PER_MEMC_SIZE; + alloc_size = hdr_alloc_size(vmcoreinfo); buf = zg_alloc(alloc_size); /* Init elf header */ ptr = ehdr_init(buf, dfi_mem_chunk_cnt() + 1);