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