From dafe99b19ba5f4206335c1b2bfd215508690e03d Mon Sep 17 00:00:00 2001 From: Rodrigo Batista de Moraes Date: Fri, 4 Sep 2026 16:50:50 -0300 Subject: [PATCH] Fix hierarchy packed length read past section Problem: a doubly LZ4 packed hierarchy section reads a varint from a buffer sized to the section. An unterminated varint can therefore read past the end of the buffer. Solution: add a null byte at the end of the buffer so an unterminated varint terminates within the allocation, and check if that has happened. --- src/fstapi.c | 5 ++++- .../hierarchy_lz4duo_shorter_than_its_varint.fst | Bin 0 -> 451 bytes tests/meson.build | 1 + tests/reader_malformed_files.c | 5 +++++ 4 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/data/malformed/hierarchy_lz4duo_shorter_than_its_varint.fst diff --git a/src/fstapi.c b/src/fstapi.c index 15440f0..b5ba3e9 100644 --- a/src/fstapi.c +++ b/src/fstapi.c @@ -3788,7 +3788,8 @@ static int fstReaderRecreateHierFile(struct fstReaderContext *xc) } gzclose(zhandle); } else if (htyp == FST_BL_HIER_LZ4DUO) { - unsigned char *lz4_cmem = (unsigned char *)malloc(clen); + /* extra null byte to catch any unterminated varint */ + unsigned char *lz4_cmem = (unsigned char *)calloc(1, (uint64_t)clen + 1); unsigned char *lz4_ucmem = (unsigned char *)malloc(uclen); unsigned char *lz4_ucmem2; uint64_t uclen2; @@ -3797,8 +3798,10 @@ static int fstReaderRecreateHierFile(struct fstReaderContext *xc) fstFread(lz4_cmem, clen, 1, xc->f); uclen2 = fstGetVarint64(lz4_cmem, &skiplen2); + lz4_ucmem2 = (unsigned char *)malloc(uclen2); pass_status = + (skiplen2 <= (int)clen) && (uclen2 == (uint64_t)LZ4_decompress_safe_partial((char *)lz4_cmem + skiplen2, (char *)lz4_ucmem2, clen - skiplen2, diff --git a/tests/data/malformed/hierarchy_lz4duo_shorter_than_its_varint.fst b/tests/data/malformed/hierarchy_lz4duo_shorter_than_its_varint.fst new file mode 100644 index 0000000000000000000000000000000000000000..4af215ba31a969bb92279c1a11d8db2a9138996b GIT binary patch literal 451 zcmZQz00Tx(2n{D0Gs8u?x%RU