aboutsummaryrefslogtreecommitdiffhomepage
path: root/projects/libzmq
diff options
context:
space:
mode:
authorGravatar Luca Boccassi <luca.boccassi@gmail.com>2020-04-26 04:27:48 +0100
committerGravatar GitHub <noreply@github.com>2020-04-25 20:27:48 -0700
commite003502f26fab3cd9083b583ecd6b5a43f7e6c21 (patch)
treed9389966cef1b17b3a0f37bd1f67d15ff6d300e1 /projects/libzmq
parent24cb3468e1d7954848546a7baeccea0bf0ca5dcc (diff)
libzmq: update maintainers, add network tests (#3710)
* libzmq: add alternative mail address and other maintainer's address * libzmq: adjust zmq_z85_decode test The output buffer is not fixed in size, it depends on input size and the caller allocates it * libzmq: add tests for handshake engine on connect/bind Create localhost ipv4 TCP sockets to exercise libzmq's processing of data over the network. This connections should be rejected in the first part of the handshake (greeting) only, so more tests should be added to further mock the greeting and exercise deeper parts of the engine. https://rfc.zeromq.org/spec/37/ * libzmq: fix coverage build The combination of clang, coverage and automake is not happy at the moment, and binaries fail to link. We don't need to build any of the tools for these tests, so simply disable them. Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=21872
Diffstat (limited to 'projects/libzmq')
-rwxr-xr-xprojects/libzmq/build.sh4
-rw-r--r--projects/libzmq/decode_fuzzer.cc9
-rw-r--r--projects/libzmq/project.yaml3
-rw-r--r--projects/libzmq/socket_bind_fuzzer.cc74
-rw-r--r--projects/libzmq/socket_connect_fuzzer.cc77
5 files changed, 164 insertions, 3 deletions
diff --git a/projects/libzmq/build.sh b/projects/libzmq/build.sh
index be98e338..db574888 100755
--- a/projects/libzmq/build.sh
+++ b/projects/libzmq/build.sh
@@ -17,8 +17,8 @@
# build project
cd $SRC/libzmq
-./autogen.sh --disable-shared
-./configure
+./autogen.sh
+./configure --disable-shared --disable-perf --disable-curve-keygen
make -j$(nproc) V=1
# build fuzzers
diff --git a/projects/libzmq/decode_fuzzer.cc b/projects/libzmq/decode_fuzzer.cc
index cedf8ee6..ef3f86a6 100644
--- a/projects/libzmq/decode_fuzzer.cc
+++ b/projects/libzmq/decode_fuzzer.cc
@@ -21,8 +21,15 @@
#include "include/zmq.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- uint8_t secret_key[32];
+ uint8_t *secret_key;
+ // As per API definition, input must be divisible by 5, so truncate it if it's not
+ size -= size % 5;
+ // As per API definition, the destination must be at least 0.8 times the input data
+ secret_key = (uint8_t *)malloc(size * 4 / 5);
+ if (!secret_key)
+ return -1;
std::string z85_secret_key(reinterpret_cast<const char *>(data), size);
zmq_z85_decode(secret_key, z85_secret_key.c_str());
+ free(secret_key);
return 0;
}
diff --git a/projects/libzmq/project.yaml b/projects/libzmq/project.yaml
index 42dad7fb..59b178c3 100644
--- a/projects/libzmq/project.yaml
+++ b/projects/libzmq/project.yaml
@@ -1,6 +1,9 @@
homepage: "https://github.com/zeromq/libzmq"
language: c++
primary_contact: "bluca@debian.org"
+auto_ccs:
+ - "luca.boccassi@gmail.com"
+ - "somdoron@gmail.com"
sanitizers:
- address
- memory
diff --git a/projects/libzmq/socket_bind_fuzzer.cc b/projects/libzmq/socket_bind_fuzzer.cc
new file mode 100644
index 00000000..c47ba17d
--- /dev/null
+++ b/projects/libzmq/socket_bind_fuzzer.cc
@@ -0,0 +1,74 @@
+// Copyright 2020 Luca Boccassi <bluca@debian.org>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+#include "include/zmq.h"
+
+// Test that the ZMTP engine handles invalid handshake when binding
+// https://rfc.zeromq.org/spec/37/
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ void *server, *ctx;
+ struct sockaddr_in ip4addr;
+ char endpoint[32];
+ size_t endpoint_len = 32, sent_bytes;
+ unsigned short port;
+ int client, rc, linger = 0;
+
+ ctx = zmq_ctx_new ();
+ assert(ctx);
+ server = zmq_socket(ctx, ZMQ_PUB);
+ assert(server);
+ rc = zmq_setsockopt (server, ZMQ_LINGER, &linger, sizeof(linger));
+ assert(rc == 0);
+ rc = zmq_bind(server, "tcp://127.0.0.1:*");
+ assert(rc == 0);
+ rc = zmq_getsockopt(server, ZMQ_LAST_ENDPOINT, endpoint, &endpoint_len);
+ assert(rc == 0);
+ rc = sscanf(endpoint, "tcp://127.0.0.1:%hu", &port);
+ assert(rc == 1);
+
+ ip4addr.sin_family = AF_INET;
+ ip4addr.sin_port = htons(port);
+ inet_pton(AF_INET, "127.0.0.1", &ip4addr.sin_addr);
+ client = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert(client >= 0);
+ rc = connect(client, reinterpret_cast<struct sockaddr *> (&ip4addr), sizeof(ip4addr));
+ assert(rc >= 0);
+
+ // Send as many bytes as possible, and then let the background I/O thread
+ // have some time to handle them.
+ // We should at least be able to send 33 bytes, which is the very first
+ // part of the ZMTP 3.x handshake. Otherwise something is not quite right
+ // in the localhost connection we set up.
+ sent_bytes = write(client, (const char *)data, size);
+ assert(size < 33 || sent_bytes >= 33);
+ usleep (static_cast<useconds_t> (250) * 1000);
+
+ close(client);
+
+ rc = zmq_close(server);
+ assert(rc == 0);
+ rc = zmq_ctx_term(ctx);
+ assert(rc == 0);
+
+ return 0;
+}
diff --git a/projects/libzmq/socket_connect_fuzzer.cc b/projects/libzmq/socket_connect_fuzzer.cc
new file mode 100644
index 00000000..ee586fb3
--- /dev/null
+++ b/projects/libzmq/socket_connect_fuzzer.cc
@@ -0,0 +1,77 @@
+// Copyright 2020 Luca Boccassi <bluca@debian.org>
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <fuzzer/FuzzedDataProvider.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+#include <assert.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include "include/zmq.h"
+
+// Test that the ZMTP engine handles invalid handshake when connecting
+// https://rfc.zeromq.org/spec/37/
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+ void *client, *ctx;
+ struct sockaddr_in ip4addr;
+ socklen_t ip4addr_len = sizeof(ip4addr);
+ char endpoint[32];
+ size_t sent_bytes;
+ int server, server_accept, rc;
+
+ ip4addr.sin_family = AF_INET;
+ ip4addr.sin_port = 0;
+ inet_pton(AF_INET, "127.0.0.1", &ip4addr.sin_addr);
+ server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ assert(server >= 0);
+ rc = bind(server, reinterpret_cast<struct sockaddr *> (&ip4addr), sizeof(ip4addr));
+ assert(rc >= 0);
+ rc = listen (server, SOMAXCONN);
+ assert(rc == 0);
+ rc = getsockname (server, (struct sockaddr *) &ip4addr, &ip4addr_len);
+ assert(rc == 0);
+ sprintf(endpoint, "tcp://127.0.0.1:%u", ntohs(ip4addr.sin_port));
+
+ ctx = zmq_ctx_new ();
+ assert(ctx);
+ client = zmq_socket(ctx, ZMQ_SUB);
+ assert(client);
+ rc = zmq_connect(client, endpoint);
+ assert(rc == 0);
+
+ // Send as many bytes as possible, and then let the background I/O thread
+ // have some time to handle them.
+ // We should at least be able to send 33 bytes, which is the very first
+ // part of the ZMTP 3.x handshake. Otherwise something is not quite right
+ // in the localhost connection we set up.
+ server_accept = accept(server, NULL, NULL);
+ sent_bytes = write(server_accept, (const char *)data, size);
+ assert(size < 33 || sent_bytes >= 33);
+ usleep (static_cast<useconds_t> (250) * 1000);
+
+ close(server_accept);
+ close(server);
+
+ rc = zmq_close(client);
+ assert(rc == 0);
+ rc = zmq_ctx_term(ctx);
+ assert(rc == 0);
+
+ return 0;
+}