zdump/dfo_elf: Include vmcoreinfo note size in ELF header allocation

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 <zaslonko@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Mikhail Zaslonko
2026-07-01 09:59:29 +02:00
committed by Jan Höppner
parent 405b2da3f3
commit 44821d0586

View File

@@ -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);