From cdabf280ac3dbd997dc4b12a99e83b86dcb43eff Mon Sep 17 00:00:00 2001 From: Mikhail Zaslonko Date: Wed, 1 Jul 2026 13:59:00 +0200 Subject: [PATCH] zdump/dfi_lkcd: Validate LKCD page size before buffer read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit read_page_buf() uses the file-controlled pg_hdr->size directly as the byte count for zg_read() into fixed stack buffers of PAGE_SIZE. A crafted LKCD dump with pg_hdr->size > PAGE_SIZE overflows the buffer and smashes the stack frame. A size of 0 for a raw page silently produces uninitialised data. Enforce page header size constraints following crash-utility's logic: - Compressed or Raw pages with size > PAGE_SIZE are invalid; exit with an error. - Raw pages with size 0 contain no data in the file; fill the output buffer with zeros without reading. - Compressed pages with size 0 are caught by the uncompress() return code check. - Raw pages with size != PAGE_SIZE are invalid; exit with an error. Check the return code of uncompress() and exit with an error if decompression fails, rather than silently proceeding with an incomplete output buffer. Signed-off-by: Mikhail Zaslonko Reviewed-by: Alexander Egorenkov Signed-off-by: Jan Höppner --- zdump/dfi_lkcd.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/zdump/dfi_lkcd.c b/zdump/dfi_lkcd.c index 51090d09..f537b26f 100644 --- a/zdump/dfi_lkcd.c +++ b/zdump/dfi_lkcd.c @@ -43,15 +43,29 @@ static void read_page_buf(struct df_lkcd_pg_hdr *pg_hdr, void *buf) unsigned long size = PAGE_SIZE; unsigned char cbuf[PAGE_SIZE]; + if (pg_hdr->size > PAGE_SIZE) + ERR_EXIT("Dump file inconsistent, LKCD page size too large (%u)", + pg_hdr->size); switch (pg_hdr->flags) { case DF_LKCD_DH_RAW: - zg_read(g.fh, buf, pg_hdr->size, ZG_CHECK); + if (pg_hdr->size == 0) { + /* No data in file: treat as zero page */ + memset(buf, 0, PAGE_SIZE); + break; + } + if (pg_hdr->size == PAGE_SIZE) { + zg_read(g.fh, buf, pg_hdr->size, ZG_CHECK); + break; + } + ERR_EXIT("Dump file inconsistent, LKCD page size invalid: %u", pg_hdr->size); break; case DF_LKCD_DH_COMPRESSED: zg_read(g.fh, cbuf, pg_hdr->size, ZG_CHECK); - uncompress(buf, &size, cbuf, pg_hdr->size); + if (uncompress(buf, &size, cbuf, pg_hdr->size) != Z_OK) + ERR_EXIT("Dump file inconsistent, LKCD page decompression failed"); if (size != PAGE_SIZE) - ABORT("Invalid page size: %ld", size); + ERR_EXIT("Dump file inconsistent, LKCD decompressed page size invalid: %u", + size); break; default: ERR_EXIT("Unsupported page flags: %x at addr %Lx",