Skip to content

Heap overflow when receiving malformed ZMTP v1 packets (CURVE disabled)

Moderate
bluca published GHSA-fc3w-qxf5-7hp6 Sep 7, 2020

Package

libzmq

Affected versions

>= 4.2, <= 4.3.2

Patched versions

4.3.3

Description

Impact

Users with listening TCP endpoints who do NOT use CURVE/ZAP for authentication

Patches

Fixed in latest master by #3902 which will be v4.3.3

Workarounds

Enable CURVE/ZAP in public endpoints

References

Found thanks to Google's oss-fuzz project:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=21984

For more information

The static allocator was implemented to shrink its recorded size similarly to the shared allocator. But it does not need to, and it should not, because unlike the shared one the static allocator always uses a static buffer, with a size defined by the ZMQ_IN_BATCH_SIZE socket option (default 8192), so changing the size opens the library to heap overflows. The static allocator is used only with ZMTP v1 peers.
By crafting a packet which is not valid ZMTP v2/v3, and which has two messages larger than 8192 bytes, the decoder can be tricked into changing the recorded size of the 8192 bytes static buffer, which then gets overflown by the next message. The content that gets written in the overflown memory is entirely decided by the sender.

When using CURVE/ZAP for authentication, ZMTP v1 peers are immediately rejected before any content is processed, and thus this problem is completely avoided.

A very minimal test case can be reproduced by setting ZMQ_IN_BATCH_SIZE to 4 and then by sending the following (hex encoded, to be converted to binary) over a plain TCP socket to a libzmq peer:

ff000000000000000800000000000000000000000000

I will add a testcase after we publish this advisory. I'll probably request a CVE, but I want to go through all the oss-fuzz crashes as I imagine there will be more...

Severity

Moderate

CVE ID

No known CVE

Weaknesses

No CWEs