## Summary

7-Zip supports extracting from [Compound
Documents](https://en.wikipedia.org/wiki/Compound_document). Null
pointer dereference in the Compound handler may lead to denial of
service.

## Tested Version

[7-Zip 
24.09](https://sourceforge.net/p/sevenzip/discussion/45797/thread/b95432c7ac/)

## Details

### Null pointer array write attempt in `NArchive::NCom::CHandler::GetStream`

When `item.Size` is a certain large number `(item.Size + clusterSize -
1) >> bsLog` at [1] may overflow and `numClusters64` becomes zero.
Note that `if (numClusters64 >= ((UInt32)1 << 31))` check at [2]
doesn't prevent the unsigned integer overflow. Then the vector call
`ClearAndReserve` at [3] doesn't allocate any memory and the internal
vector pointer stays `null`. This leads to a null pointer write
attempt at [4].

```cpp
Z7_COM7F_IMF(CHandler::GetStream(UInt32 index, ISequentialInStream **stream))
{
...
  const UInt64 numClusters64 = (item.Size + clusterSize - 1) >> bsLog;
// <----- 1
  if (numClusters64 >= ((UInt32)1 << 31))
// <----- 2
    return E_NOTIMPL;
  streamSpec->Vector.ClearAndReserve((unsigned)numClusters64);
// <----- 3
  UInt32 sid = item.Sid;
  UInt64 size = item.Size;

  if (size != 0)
  {
    for (;; size -= clusterSize)
    {
      if (isLargeStream)
      {
        if (sid >= _db.FatSize)
          return S_FALSE;
        streamSpec->Vector.AddInReserved(sid + 1); // <----- 4
```

A PoC triggers null pointer write dereference when `7zz` is compiled
with ASAN and extracted, for example as `7zz e -so
compound-crash.poc`:
```
==2387581==ERROR: AddressSanitizer: SEGV on unknown address
0x000000000000 (pc 0x5615317c0993 bp 0x7ffcb31a1350 sp 0x7ffcb31a1300
T0)
==2387581==The signal is caused by a WRITE memory access.
==2387581==Hint: address points to the zero page.
    #0 0x5615317c0993 in CRecordVector<unsigned
int>::AddInReserved(unsigned int)
../../Archive/../../Common/MyVector.h:249:18
    #1 0x5615317bfe66 in NArchive::NCom::CHandler::GetStream(unsigned
int, ISequentialInStream**)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../Archive/ComHandler.cpp:866:28
    #2 0x5615317bea3d in NArchive::NCom::CHandler::Extract(unsigned
int const*, unsigned int, int, IArchiveExtractCallback*)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../Archive/ComHandler.cpp:806:20
    #3 0x561531e94bbb 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
    #4 0x561531e8fdf1 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
    #5 0x561531f49d3a in Main2(int, char**)
/src/7-zip/CPP/7zip/Bundles/Alone2/../../UI/Console/Main.cpp:1378:21
    #6 0x561531f55ae4 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

This issue may lead to denial of service.

## 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

Reply via email to