data_decompress() in src/shared/compression.c:46-103 uses ZSTD_getFrameContentSize() to determine the decompression buffer size. This function can return ZSTD_CONTENTSIZE_UNKNOWN (0xFFFFFFFFFFFFFFFF) for frames that do not store the original size. The code only checks ZSTD_isError() and then immediately casts the result to size_t for malloc():
If dst_size is ZSTD_CONTENTSIZE_UNKNOWN, the condition is true (dst_size > 0 and not an error), causing an allocation of SIZE_MAX bytes and an immediate OOM.
Reproduction scenario
Craft a valid zstd frame with the content-size flag unset and send it to the server. The decompressor will attempt to allocate a buffer of SIZE_MAX.
Suggested fix
Explicitly check for ZSTD_CONTENTSIZE_UNKNOWN and ZSTD_CONTENTSIZE_ERROR and fall back to streaming growth with a small initial buffer.
Use a bounded streaming decompression loop so that the buffer grows incrementally up to a configurable maximum.
Severity
High
Category
security
This issue was automatically generated by the issue-creator agent.
## Description
`data_decompress()` in `src/shared/compression.c:46-103` uses `ZSTD_getFrameContentSize()` to determine the decompression buffer size. This function can return `ZSTD_CONTENTSIZE_UNKNOWN` (`0xFFFFFFFFFFFFFFFF`) for frames that do not store the original size. The code only checks `ZSTD_isError()` and then immediately casts the result to `size_t` for `malloc()`:
```c
unsigned long long dst_size =
ZSTD_getFrameContentSize(compressed_data->data, compressed_data->size);
...
size_t buf_size =
(!ZSTD_isError(dst_size) && dst_size > 0) ? (size_t)dst_size : INITIAL_DECOMPRESS_BUF_SIZE;
```
If `dst_size` is `ZSTD_CONTENTSIZE_UNKNOWN`, the condition is true (`dst_size > 0` and not an error), causing an allocation of `SIZE_MAX` bytes and an immediate OOM.
## Reproduction scenario
Craft a valid zstd frame with the content-size flag unset and send it to the server. The decompressor will attempt to allocate a buffer of `SIZE_MAX`.
## Suggested fix
1. Explicitly check for `ZSTD_CONTENTSIZE_UNKNOWN` and `ZSTD_CONTENTSIZE_ERROR` and fall back to streaming growth with a small initial buffer.
2. Use a bounded streaming decompression loop so that the buffer grows incrementally up to a configurable maximum.
## Severity
High
## Category
security
---
_This issue was automatically generated by the issue-creator agent._
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Description
data_decompress()insrc/shared/compression.c:46-103usesZSTD_getFrameContentSize()to determine the decompression buffer size. This function can returnZSTD_CONTENTSIZE_UNKNOWN(0xFFFFFFFFFFFFFFFF) for frames that do not store the original size. The code only checksZSTD_isError()and then immediately casts the result tosize_tformalloc():If
dst_sizeisZSTD_CONTENTSIZE_UNKNOWN, the condition is true (dst_size > 0and not an error), causing an allocation ofSIZE_MAXbytes and an immediate OOM.Reproduction scenario
Craft a valid zstd frame with the content-size flag unset and send it to the server. The decompressor will attempt to allocate a buffer of
SIZE_MAX.Suggested fix
ZSTD_CONTENTSIZE_UNKNOWNandZSTD_CONTENTSIZE_ERRORand fall back to streaming growth with a small initial buffer.Severity
High
Category
security
This issue was automatically generated by the issue-creator agent.