Add remaining-buffer bound check in _array_of_documents_to_buffer

XMLWordPrintableJSON

    • Type: Task
    • Resolution: Done
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: None
    • None
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • 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:

        1. 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)

      { PyErr_SetString(InvalidBSON, "invalid array content"); Py_DECREF(InvalidBSON); }

      goto fail;
      }
      ```

        1. 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)

      { … goto fail; }

      ```

      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).

        1. Change scope
      • *One file changed*: `bson/_cbsonmodule.c`
      • *Nine lines added*: the guard block + one blank separator line
      • No reformatting, no other logic changes

            Assignee:
            Noah Stapp
            Reporter:
            TPM Jira Automations Bot
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: