From f310ce376ea1c8deb542b0746344f27251f7eadc Mon Sep 17 00:00:00 2001 From: John Reiser Date: Wed, 10 Jan 2024 11:20:47 -0800 Subject: [PATCH] Beware fuzzer setting compressed size too small https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65519 https://github.com/upx/upx/issues/761 modified: p_unix.cpp --- src/p_unix.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_unix.cpp b/src/p_unix.cpp index bb472cdc..bbc30b0b 100644 --- a/src/p_unix.cpp +++ b/src/p_unix.cpp @@ -597,6 +597,8 @@ int PackUnix::find_overlay_offset(MemBuffer const &buf) // See notes there. **************************************************************************/ +static unsigned umax(unsigned a, unsigned b) {return (a < b) ? b : a;} + void PackUnix::unpack(OutputFile *fo) { b_info bhdr; @@ -658,7 +660,11 @@ void PackUnix::unpack(OutputFile *fo) if (sz_cpr > sz_unc || sz_unc > blocksize) throwCompressedDataViolation(); - i = blocksize + OVERHEAD - sz_cpr; + // Compressed output has control bytes such as the 32-bit + // first flag bits of NRV_d32, the 5-byte info of LZMA, etc. + // Fuzzers may try sz_cpr shorter than possible. + // Use some OVERHEAD for safety. + i = blocksize + OVERHEAD - umax(12, sz_cpr); if (i < 0) throwCantUnpack("corrupt b_info"); fi->readx(buf+i, sz_cpr);