Detect compressed length too short

https://github.com/upx/upx/issues/827
	modified:   p_unix.cpp
This commit is contained in:
John Reiser
2024-06-04 08:32:26 -07:00
parent 3495d1affd
commit c58246b43c
+9 -5
View File
@@ -660,10 +660,14 @@ void PackUnix::unpack(OutputFile *fo)
throwCompressedDataViolation(); throwCompressedDataViolation();
break; break;
} }
if (sz_unc <= 0 || sz_cpr <= 0) // Minimum compressed length: LZMA has 5-byte info header.
throwCompressedDataViolation(); // NRV_d8 has 1-byte initial 8 flag bits, plus end-of-block marker
if (sz_cpr > sz_unc || sz_unc > blocksize) // (32 bit look-back offset of all 1s: encoded as 24 pairs of bits
throwCompressedDataViolation(); // {not last, 1} then low 8-bits of 0xff; total: 8 + 2*24 + 8 bits
// ==> 8 bytes)
if (sz_unc <= 0 || sz_cpr <= 5u
|| sz_cpr > sz_unc || sz_unc > blocksize)
throwCantUnpack("corrupt b_info %#x %#x", sz_unc, sz_cpr);
// Compressed output has control bytes such as the 32-bit // Compressed output has control bytes such as the 32-bit
// first flag bits of NRV_d32, the 5-byte info of LZMA, etc. // first flag bits of NRV_d32, the 5-byte info of LZMA, etc.
@@ -671,7 +675,7 @@ void PackUnix::unpack(OutputFile *fo)
// Use some OVERHEAD for safety. // Use some OVERHEAD for safety.
i = blocksize + OVERHEAD - upx::umax(12u, sz_cpr); i = blocksize + OVERHEAD - upx::umax(12u, sz_cpr);
if (i < 0) if (i < 0)
throwCantUnpack("corrupt b_info"); throwCantUnpack("corrupt b_info %#x %#x", sz_cpr, blocksize);
fi->readx(buf+i, sz_cpr); fi->readx(buf+i, sz_cpr);
// update checksum of compressed data // update checksum of compressed data
c_adler = upx_adler32(buf + i, sz_cpr, c_adler); c_adler = upx_adler32(buf + i, sz_cpr, c_adler);