Security: Unbounded wire sizes enable OOM denial of service #156
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
receive_data()andreceive_str()read an 8-byte (orsizeof(size_t)) length field from the peer and thenmalloc()that many bytes without any upper bound or sanity check. A malicious client or server can send a very large length value and cause the peer to allocate an enormous amount of memory, leading to denial of service.Affected functions:
src/shared/protocol.c:176-189—receive_data()readsunsigned long long sizeand doesmalloc((size_t)size).src/shared/protocol.c:150-164—receive_str()readssize_t sizeand doesmalloc(size + 1).src/shared/file.c:521-529—receive_manifest()reads anint countfrom the network and loopscounttimes, receiving strings; a huge value can exhaust memory or spin forever.src/shared/chunk.c:98-109and:149-160—chunk_deserialize()readspath_lenandfile_data_sizeassize_tfrom the wire and allocates them directly.On 32-bit platforms, the
unsigned long longtosize_tcast inreceive_data()can also silently truncate a huge value, causing a small buffer to be allocated for a large receive.Reproduction scenario
A peer sends a
receive_dataheader wheresizeis0xFFFFFFFFFFFFFFFF. The target callsmalloc((size_t)-1)and either fails or consumes all available memory.Suggested fix
MAX_WIRE_SIZE, possibly derived from available memory or a sensible cap like 1 GB).receive_data()andreceive_str(), reject lengths greater thanMAX_WIRE_SIZEbefore allocating.receive_manifest(), bound the count to a reasonable number of files per transfer.chunk_deserialize(), validatepath_lenandfile_data_sizeagainst the remaining chunk bytes and the global cap.Severity
High
Category
security
This issue was automatically generated by the issue-creator agent.