-
Type:
Task
-
Resolution: Unresolved
-
Priority:
Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
AgentGymLeader has created PR #2872: PYTHON-XXXX Add remaining-buffer bound check in _array_of_documents_to_buffer in mongo-python-driver
Issue Text:
-
- What
Adds a single upper-bound check on the per-element embedded-document length
(`value_length`) in `_cbson_array_of_documents_to_buffer` (in
`bson/_cbsonmodule.c`), immediately before the `pymongo_buffer_write` /
`memcpy` call that copies the element into the output buffer.
```c
if (value_length > (uint32_t)(size - position)) {
PyObject* InvalidBSON = _error("InvalidBSON");
if (InvalidBSON)
goto fail;
}
```
-
- Why
`_cbson_array_of_documents_to_buffer` is the C fast-path used by
`Collection.find_raw_batches()` and `aggregate_raw_batches()` to convert a
raw BSON array (from a server `firstBatch`/`nextBatch`) into a flat stream
of BSON documents.
The function reads a per-element length `value_length` from the raw bytes and
then passes it directly to `pymongo_buffer_write(buffer, string + position,
value_length)`. Before this patch it only checked the lower bound:
```c
if (value_length < BSON_MIN_SIZE)
```
There was no corresponding upper-bound check that `value_length` does not
exceed the bytes remaining in the array document (`size - position`). A
crafted raw-batch reply — from a malicious or compromised server — with an
inner `value_length` larger than the remaining buffer causes
`pymongo_buffer_write` → `memcpy` to read past the end of the heap allocation,
constituting an out-of-bounds read.
The pure-Python counterpart `get_object_size` in `bson/init_.py` already
enforces this invariant. The C fast-path dropped it.
The loop already guarantees `position < size` and
`(size - position) >= BSON_MIN_SIZE` via the prior guard (line ~3221), so the
subtraction `size - position` cannot underflow (both variables are `uint32_t`
and `position < size` is assured).
This belongs to the same bug class as *CVE-2024-5629* (out-of-bounds read in
the bson C extension, fixed in 4.6.3) but affects a different function
(`_cbson_array_of_documents_to_buffer` vs the one patched in 4.6.3).
-
- Change scope
- *One file changed*: `bson/_cbsonmodule.c`
- *Nine lines added*: the guard block + one blank separator line
- No reformatting, no other logic changes