mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdump/dfi_lkcd: Validate LKCD page size before buffer read
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 <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:
committed by
Jan Höppner
parent
33c75584cd
commit
cdabf280ac
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user