![]() |
|
Message-ID: <CAEBMHm5Fbiz7hXMU=rvV09_GWZ2SVCS_GXj46oJt5VuhgJ5hjw@mail.gmail.com>
Date: Fri, 18 Jul 2025 13:15:37 +0200
From: Jaras <jarlob@...il.com>
To: oss-security@...ts.openwall.com
Subject: CVE-2025-53816: Memory corruption in 7-Zip before 25.00
## Summary
Zeroes written outside the heap buffer in RAR5 handler may lead to
memory corruption.
## Tested Version
[7-Zip 24.09](https://sourceforge.net/p/sevenzip/discussion/45797/thread/b95432c7ac/)
## Details
### Multi byte write heap buffer overflow in `NCompress::NRar5::CDecoder`
RAR5 decoder attempts to fix corrupted items by filling them with
zeroes. However a miscalculation [2] of the `rem` value in
`My_ZeroMemory(_window + _winPos, (size_t)rem);` [1] call leads to
zeroes written past the allocated buffer.
```cpp
Z7_COM7F_IMF(CDecoder::Code(ISequentialInStream *inStream,
ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 *outSize,
ICompressProgressInfo *progress))
{
...
#define Z7_RAR_RECOVER_SOLID_LIMIT (1 << 20)
...
{
const UInt64 lzSize = _lzSize + _winPos;
...
#if Z7_RAR_RECOVER_SOLID_LIMIT != 0
else if (lzSize < _lzEnd)
{
...
// we can report that recovering was made:
// _lzError = LZ_ERROR_TYPE_HEADER;
// We write zeros to area after corruption:
if (_window)
{
UInt64 rem = _lzEnd - lzSize; // <------- 2
const size_t ws = _winSize;
if (rem >= ws)
{
My_ZeroMemory(_window, ws);
_lzSize = ws;
_winPos = 0;
}
else
{
const size_t cur = ws - _winPos;
if (cur <= rem)
{
rem -= cur;
My_ZeroMemory(_window + _winPos, cur);
_lzSize += _winPos;
_winPos = 0;
}
My_ZeroMemory(_window + _winPos, (size_t)rem); // <-------- 1
_winPos += (size_t)rem;
}
}
...
}
#endif
}
...
_unpackSize = 0;
_unpackSize_Defined = (outSize != NULL);
if (_unpackSize_Defined)
_unpackSize = *outSize;
if ((Int64)_unpackSize >= 0)
_lzEnd += _unpackSize; // known end after current file //
<------------- 3
else
_lzEnd = 0; // unknown end
...
}
```
A PoC triggers heap buffer write overflow when `7zz` is compiled with
ASAN and extracted, for example as `7zz e -so rar-crash.rar5`:
```
==2188082==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x7fc75fbcc844 at pc 0x5567af835070 bp 0x7fff7f71ce30 sp
0x7fff7f71c600
WRITE of size 9469 at 0x7fc75fbcc844 thread T0
#0 0x5567af83506f in __asan_memset
/src/llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:67:3
#1 0x5567b0167b0c in My_ZeroMemory(void*, unsigned long)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../Compress/Rar5Decoder.cpp:63:5
#2 0x5567b017c257 in
NCompress::NRar5::CDecoder::Code(ISequentialInStream*,
ISequentialOutStream*, unsigned long const*, unsigned long const*,
ICompressProgressInfo*)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../Compress/Rar5Decoder.cpp:1905:11
#3 0x5567aff075c0 in
NArchive::NRar5::CUnpacker::Code(NArchive::NRar5::CItem const&,
NArchive::NRar5::CItem const&, unsigned long, ISequentialInStream*,
ISequentialOutStream*, ICompressProgressInfo*, bool&)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../Archive/Rar/Rar5Handler.cpp:1165:24
#4 0x5567aff24721 in NArchive::NRar5::CHandler::Extract(unsigned
int const*, unsigned int, int, IArchiveExtractCallback*)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../Archive/Rar/Rar5Handler.cpp:3293:25
#5 0x5567b0244c0b in DecompressArchive(CCodecs*, CArchiveLink
const&, unsigned long, NWildcard::CCensorNode const&, CExtractOptions
const&, bool, IExtractCallbackUI*, IFolderArchiveExtractCallback*,
CArchiveExtractCallback*, UString&, unsigned long&)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../UI/Common/Extract.cpp:235:23
#6 0x5567b023fe41 in Extract(CCodecs*, CObjectVector<COpenType>
const&, CRecordVector<int> const&, CObjectVector<UString>&,
CObjectVector<UString>&, NWildcard::CCensorNode const&,
CExtractOptions const&, IOpenCallbackUI*, IExtractCallbackUI*,
IFolderArchiveExtractCallback*, IHashCalc*, UString&,
CDecompressStat&)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../UI/Common/Extract.cpp:542:5
#7 0x5567b02f9d8a in Main2(int, char**)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../UI/Console/Main.cpp:1378:21
#8 0x5567b0305b34 in main
/src/7-zip/CPP/7zip/Bundles/Alone2/../../UI/Console/MainAr.cpp:162:11
```
On Windows the same PoC was tested to crash the official 7-Zip build
even without ASAN.
#### Impact
The bytes past the allocated heap buffer are always overwritten with
zeroes: `My_ZeroMemory(_window + _winPos, (size_t)rem)` [1], but `rem`
is calculated as `UInt64 rem = _lzEnd - lzSize;` [2] where `_lzEnd`
depends on the size of the previous item in archive which is attacker
controlled: `_lzEnd += _unpackSize` [3]. Thus the attacker may
control how many bytes to overwrite.
It is unlikely it could lead to arbitrary code execution, but it may
lead to denial of service because of the memory corruption.
## Credit
This issue was discovered and reported by GHSL team member [@JarLob
(Jaroslav Lobačevski)](https://github.com/JarLob).
## Coordinated Disclosure Timeline
- 2025-04-24: Reported as a private issue
- 2025-04-29: Report acknowledged
- 2025-07-05: Fixed in v25.00
Content of type "text/html" skipped
Powered by blists - more mailing lists
Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.