From 2d45e334fb5cfb9e5361099609ef8570b37f2fb5 Mon Sep 17 00:00:00 2001 From: Cole Munz Date: Fri, 10 Jul 2026 21:02:47 -0500 Subject: [PATCH] Fix heap out-of-bounds read in hf iclass view on short dump files --- CHANGELOG.md | 1 + client/src/cmdhficlass.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9417b1e0..eafac106c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac ## [unreleased][unreleased] +- Fixed `hf iclass view` reading past the end of dump files smaller than a picopass header, causing a heap out-of-bounds read and garbage/leaked heap data being printed as tag content (@munzzyy) - Fixed `wiegand decode` returning facility code 16777339 instead of the encoded value for the IR56 (Inner Range 56-bit) format by masking the header sentinel bit off the facility code (@munzzyy) - Fixed `lf em 4x05 dump` writing byte-swapped (corrupted) block data to the saved dump file (@munzzyy) - Added `hf 14b dump` support for Standard ISO14443-B tags (@thisiscamk) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 2c21e0bc9..ba9a750d8 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -5306,7 +5306,10 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e endblock = maxmemcount; // remember endblock needs to relate to zero-index arrays. - if (endblock > filemaxblock - 1) + // filemaxblock is 0 when filesize < 8, so filemaxblock - 1 would underflow. + if (filemaxblock == 0) + endblock = 0; + else if (endblock > filemaxblock - 1) endblock = filemaxblock - 1; /* @@ -5515,6 +5518,12 @@ static int CmdHFiClassView(const char *Cmd) { return res; } + if (bytes_read < sizeof(picopass_hdr_t)) { + PrintAndLogEx(FAILED, "Error, dump file is too small to be a valid iCLASS dump - bytes: %zu, expected at least: %zu", bytes_read, sizeof(picopass_hdr_t)); + free(dump); + return PM3_EFILE; + } + if (verbose) { PrintAndLogEx(INFO, "File size %zu bytes, file blocks %d (0x%x)", bytes_read, (uint16_t)(bytes_read >> 3), (uint16_t)(bytes_read >> 3)); PrintAndLogEx(INFO, "Printing blocks from: " _YELLOW_("%02d") " to: " _YELLOW_("%02d"), (startblock == 0) ? 6 : startblock, endblock);