Skip to content

Security: Unmarshaller accepts attacker-controlled message length without max-size cap, enabling memory exhaustion DoS #641

@bluetoothbot

Description

@bluetoothbot

Problem

_read_header reads _body_len and _header_len as untrusted uint32 values directly from the wire (lines 772-790), then computes self._msg_len = self._header_len + (-self._header_len & 7) + self._body_len. _read_body then calls self._read_to_pos(HEADER_SIGNATURE_SIZE + self._msg_len) (line 800), which feeds an attacker-controlled missing_bytes (up to ~8 GiB) into socket.recvmsg(missing_bytes, ...) in _read_sock_with_fds (line 379), or grows self._buf until it reaches that size in _read_sock_without_fds/_read_stream. The TODO at message.py:324 ("maximum message size is 134217728 (128 MiB)") confirms the spec-mandated 128 MiB cap is not enforced. Anyone able to send messages to a victim's connection (and on a shared system bus, any unprivileged peer can broadcast signals to subscribers) can deliver a single 28-byte forged header claiming body_len=0xFFFFFFFF and force the victim to attempt to buffer ~4 GiB before any validation.

Why This Matters

Remote DoS against any dbus-fast consumer — including privileged daemons that subscribe to signals on the system bus (BlueZ-adjacent services, NetworkManager clients, etc.). A single hostile message kills the process or freezes the host via OOM.

Suggested Fix

Enforce the D-Bus spec limits immediately after reading the header in _read_header:

MAX_BODY_LEN = 134_217_728     # 128 MiB
MAX_HEADER_LEN = 134_217_728   # spec: array length <= 64 MiB; 128 MiB is a safe ceiling
if self._body_len > MAX_BODY_LEN or self._header_len > MAX_HEADER_LEN:
    raise InvalidMessageError(
        f"message size exceeds maximum: header={self._header_len}, body={self._body_len}"
    )

Place this before computing _msg_len so no allocation/recv is ever attempted with attacker-chosen sizes.

Details

Severity 🟠 High
Category dos
Location src/dbus_fast/_private/unmarshaller.py:751-800 (and 401-422, 369-399)
Effort ⚡ Quick fix

🤖 Created by Kōan from audit session

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions