Skip to content

Reject a packet_buffer_size of 0 instead of accepting it - #3734

Open
afonsojanu wants to merge 1 commit into
eclipse-mosquitto:masterfrom
afonsojanu:fix/reject-zero-packet-buffer-size
Open

afonsojanu wants to merge 1 commit into
eclipse-mosquitto:masterfrom
afonsojanu:fix/reject-zero-packet-buffer-size

Conversation

@afonsojanu

Copy link
Copy Markdown

The websockets_headers_size/packet_buffer_size config option let through a value of 0, which the http__read() path in http_serv.c then treats as an already-allocated, NUL-terminated header buffer: it calls strlen() on it right away and later writes a terminator at packet_buffer[packet_buffer_size - 1]. Neither of those makes sense for a zero-byte buffer, and both read and write past the tiny allocation mosquitto_calloc(1, 0) actually returns.

A remote client can trigger this just by connecting to a builtin WebSocket listener configured this way and sending an ordinary HTTP Upgrade request, no MQTT logic involved. I confirmed it under AddressSanitizer: a real network request to a broker started with packet_buffer_size 0 produces a deterministic heap-buffer-overflow in strlen() at http_serv.c:85, aborting the broker. The stack trace points straight at the strlen call reading past the 1-byte allocation.

The buffer needs at least one byte to ever hold that terminator, so the fix just tightens the config parser to reject 0 the same way it already rejects anything above UINT16_MAX. Added a regression test alongside the existing packet_buffer_size/websockets_headers_size range checks in 16-config-parse-errors-without-tls.py, and updated the wording of the two existing out-of-range tests since the error message text changed slightly (0 to 1 as the floor).

Ran the full config-parse-errors test file locally, verified the new test fails on unpatched master (reverted just conf.c, kept the test) and passes with the fix restored.

I noticed the CONTRIBUTING guide asks for branches off develop/fixes, but this repo only has master now, so I branched from there.

The websockets_headers_size/packet_buffer_size config option let
through a value of 0, which the http__read() path in http_serv.c then
treats as an already-allocated, NUL-terminated header buffer: it calls
strlen() on it right away and later writes a terminator at
packet_buffer[packet_buffer_size - 1]. Neither of those makes sense for
a zero-byte buffer, and both read and write past the tiny allocation
mosquitto_calloc(1, 0) actually returns.

A remote client can trigger this just by connecting to a builtin
WebSocket listener configured this way and sending an ordinary HTTP
Upgrade request, no MQTT logic involved. Confirmed under AddressSanitizer:
a real network request to a broker started with packet_buffer_size 0
produces a deterministic heap-buffer-overflow in strlen() at
http_serv.c:85, aborting the broker.

The buffer needs at least one byte to ever hold that terminator, so
the config parser now rejects 0 the same way it already rejects
anything above UINT16_MAX. Added a regression test alongside the
existing packet_buffer_size/websockets_headers_size range checks in
16-config-parse-errors-without-tls.py, and updated the wording of the
two existing out-of-range tests to match the new message.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant