aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-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;
+}