Compression module may truncate decompressed size on 32-bit platforms #65

Closed
opened 2026-07-20 17:14:08 +02:00 by TapTap · 0 comments
Owner

Description

In src/shared/compression.c lines 48-49:

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;

ZSTD_getFrameContentSize() returns unsigned long long, but it is assigned to size_t on 32-bit platforms, where size_t is 32 bits. If a compressed frame has a decompressed size larger than 4GB, the value will be truncated.

Additionally, the decompression loop grows the buffer by doubling (line 83: buf_size *= 2), which can quickly exhaust memory on 32-bit systems.

Location

src/shared/compression.c:48-63

Suggested Fix

Validate that dst_size fits in size_t before using it:

unsigned long long dst_size_raw =
    ZSTD_getFrameContentSize(compressed_data->data, compressed_data->size);
if (!ZSTD_isError(dst_size_raw) && dst_size_raw > 0) {
    if (dst_size_raw > SIZE_MAX) {
        log_message(LOG_LEVEL_ERROR, "Decompressed size exceeds address space");
        return NULL;
    }
    buf_size = (size_t)dst_size_raw;
}

Severity

Low

Category

Bug

## Description In `src/shared/compression.c` lines 48-49: ```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; ``` `ZSTD_getFrameContentSize()` returns `unsigned long long`, but it is assigned to `size_t` on 32-bit platforms, where `size_t` is 32 bits. If a compressed frame has a decompressed size larger than 4GB, the value will be truncated. Additionally, the decompression loop grows the buffer by doubling (line 83: `buf_size *= 2`), which can quickly exhaust memory on 32-bit systems. ## Location `src/shared/compression.c:48-63` ## Suggested Fix Validate that `dst_size` fits in `size_t` before using it: ```c unsigned long long dst_size_raw = ZSTD_getFrameContentSize(compressed_data->data, compressed_data->size); if (!ZSTD_isError(dst_size_raw) && dst_size_raw > 0) { if (dst_size_raw > SIZE_MAX) { log_message(LOG_LEVEL_ERROR, "Decompressed size exceeds address space"); return NULL; } buf_size = (size_t)dst_size_raw; } ``` ## Severity Low ## Category Bug
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: TapTap/FastSync#65