diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index b33e4250..ff1d7503 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -89,12 +89,3 @@ jobs: shell: cmd working-directory: build_libzmq run: ctest -C "%Configuration%" - Fuzzing: - runs-on: ubuntu-latest - steps: - - name: Build Fuzzers - id: build - uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master - with: - oss-fuzz-project-name: 'libzmq' - dry-run: false diff --git a/.github/workflows/Fuzzers.yaml b/.github/workflows/Fuzzers.yaml new file mode 100644 index 00000000..8ef88070 --- /dev/null +++ b/.github/workflows/Fuzzers.yaml @@ -0,0 +1,13 @@ +name: Fuzzers +on: [pull_request] + +jobs: + Fuzzing: + runs-on: ubuntu-latest + steps: + - name: Build Fuzzers + id: build + uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master + with: + oss-fuzz-project-name: 'libzmq' + dry-run: false diff --git a/tests/fuzzer_corpora/test_bind_curve_fuzzer.txt b/tests/fuzzer_corpora/test_bind_curve_fuzzer.txt index aec6bc1f..cd9b2993 100644 --- a/tests/fuzzer_corpora/test_bind_curve_fuzzer.txt +++ b/tests/fuzzer_corpora/test_bind_curve_fuzzer.txt @@ -1 +1 @@ -ff00000000000000017f03014355525645000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c80548454c4c4f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a5af606a040b3eb749b38aad3c43ea22f18b1659de5c3db1996b6f880d48e30e000000000000000108706d93931262db2e66acd402ecbe67b85aba0e696fe5d5ada13b14d2ab50917301acbb09f29f85b24c470915951d1ce2973288aca89cda8c484389bba97271a0ded05860f152a5c757b7bdd5849fa206000000000000011408494e495449415445e3d3dd23298ecbdc31d3b471a56f9235701b35296117c8f798a4013f1d3a11d4c4c254b1785ad9cc6f3e01b9387f95468fabe11bd45d73704a9653165e045c2a2baa48130e8d9d9745975fc7600c23679cc044b396a4a7f91c946acf744d072a00000000000000020e56c8aebfb1f9f33f989e76c2cebbe45e0fef500717436e64b53da90ac7d2af3ca8ebd5edbdfb896ed18126d2a4c2836861a935e089503cc5efbfc166b94e504a0cfff64c0410689fd669aa4c1b041cadb21910fe7af4323258461960d969d8c481b47959430732bdb6126d62ddf801b3db7d32c146e5b10bc83cd503fd75badad67e6370c7adb2996a3242b0210e82ef1947ab563a5333a60aaeae9fc7c968c6264a002b074d4553534147450000000000000003cc90b40b5bc78bcb00f8ad69dc162c4b387cf8b9ab2d334455b3a9 +ff00000000000000017f03014355525645000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004c80548454c4c4f010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029ce356a87e7861b3ac340f8a76785982e7684627cc279564b05548b3425a66c00000000000000012ae574af7907bb06a481251c90df3d15f995a53ce358f904c834217a0d7cb021fbbd630f847cd261e1dcf9786f995fde297792bd0b521c827e41e841ae8d643e7757f98a6d8959ca7258cf1a09b6a10306000000000000012408494e49544941544573a40c9d42d89d69e7bee1124a13b8ad85749e2300e1e10f5c833529360f964a82761a463c1a85332e5fadd161d2ba391952c1d875a159d326786330b462fda30a4a6f4d28817a5726950a185a3cd9abf122c99b95fbb3b77b77702e7b57e7b600000000000000029d559274e0c937e8ecf25725b81caae149205ec686718e97f48b3788588280de18405bbd139f1a530b87f1ab4f139ef99ba711d45c55aae6001204fa986f342bac01f90b28fd69a3d9f3fdf5aaff5b7934a0a1f1a70c9fce70720e7f6c25773882d4f1a85460a79cf8da6972efb1571b48fe0d03d09c522523f32796eb635c44210a6bcedd8c3ca66c7bf62016ee08d80ccd4d64a7f2fdec8eb06fe3dfc91a9fc31c4a8c559b4a245de2ff344ab27da7725bd90041074d4553534147450000000000000003d5ce709afb2455b7402a18f01eb61cb7a65d227bb6de4c9714c2a027ba9f2481e43ed60ecbb615fa00b948fa34469f553f0041074d4553534147450000000000000004f08579612e848d6ad69131eba369cdc2634967eb5d223481cc6838e6c355a33edc948e4b6d9ca2b2796c458327a2872de2 diff --git a/tests/fuzzer_corpora/test_connect_curve_fuzzer.txt b/tests/fuzzer_corpora/test_connect_curve_fuzzer.txt index c6af8787..1ef32c23 100644 --- a/tests/fuzzer_corpora/test_connect_curve_fuzzer.txt +++ b/tests/fuzzer_corpora/test_connect_curve_fuzzer.txt @@ -1 +1 @@ -ff00000000000000017f03014355525645000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a80757454c434f4d45b82e58be6c89e876fd91e236488b8d4bb37846d2cd38e739264ea8ff66ca06f5930d70920b8429505844f064be5d8c977078b8dd135e340cd8c7f276293ebf9c45bd6b240c0d9c15b8fde2defb11f4f49c864695f07c3456e855dd7eef6ee371dbda86b05f3db853781ce741ecacffcc50a7a8176ec8ebd3c2692beb79977b143f90c77a13eee6ed5282ee27ad45f36fd08a31ecd205dfa9e7b6887fe2ea1ccc0432055245414459000000000000000171f53d3270589095cd304baeedfe0a326ed8488d0173dded2dca5b996d0d31e6469d5f4e0026074d4553534147450000000000000002fbb1f34c99e8d2f5a2cb37dfb01b0a74f2d1c0439f5c0026074d455353414745000000000000000388166e23cf25cda98b8b3f635039b468bb222cbfec30 +ff00000000000000067f03014355525645000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004a80757454c434f4d4574535c9301c7695f2db73109ce0c78ab4ea9012648001fb41f846af73271f30f92d967c988286958f93f795ba211178500a0ea3b8396f5a580868d1fb26f8d4cfac3473c37da8cb825864c61f96c805140e9885e349652bf4cf9b0623e4c6a6de41e2f3db58bed2d152dac0ba6a8c83a222aac67bea733e97815e9c4ebc3ff5968869a42116a9530ee6eba37820c87f382e7ec057c38dc2c337a8dd9b0bc9bcd044605524541445900000000000000012bf9ffd6aadcc15e02e02a9b6e63490b004cb446038b8d1d6e224f507c25c4be0dfd9f30c41a24bff8d277dcad0b83daf292c32bd7792e610041074d45535341474500000000000000028c302f949ffbd09aaf559bd228aeeda6c69c677910edc29642976632bec514afa1a2df7eb5abcfd91f94d9b9e4a61097910041074d4553534147450000000000000003300b7856f1d04647531b04fd46322d34a6ad1f6cf05cc5dfd032cc3ec1c4870a3fdfcbf0e8d6d8a7bbc64c1304c37b5854 diff --git a/tests/test_bind_curve_fuzzer.cpp b/tests/test_bind_curve_fuzzer.cpp index e2e1bd49..1993dd26 100644 --- a/tests/test_bind_curve_fuzzer.cpp +++ b/tests/test_bind_curve_fuzzer.cpp @@ -31,6 +31,8 @@ #include #endif +#include + #include "testutil.hpp" #include "testutil_security.hpp" @@ -38,6 +40,10 @@ // https://rfc.zeromq.org/spec/37/ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) { + const char *fixed_client_public = + "{{k*81)yMWEF{/BxdMd[5RL^qRFxBgoL<8m.D^KD"; + const char *fixed_server_secret = + "T}t5GLq%&Qm1)y3ywu-}pY3KEA//{^Ut!M1ut+B4"; void *handler; void *zap_thread; void *server; @@ -45,26 +51,35 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) char my_endpoint[MAX_SOCKET_STRING]; setup_test_context (); - setup_testutil_security_curve (); - setup_context_and_server_side (&handler, &zap_thread, &server, &server_mon, - my_endpoint); + memcpy (valid_client_public, fixed_client_public, 41); + setup_context_and_server_side ( + &handler, &zap_thread, &server, &server_mon, my_endpoint, &zap_handler, + &socket_config_curve_server, (void *) fixed_server_secret); fd_t client = connect_socket (my_endpoint); // If there is not enough data for a full greeting, just send what we can // Otherwise send greeting first, as expected by the protocol - uint8_t buf[64]; + uint8_t buf[512]; if (size >= 64) { send (client, (void *) data, 64, MSG_NOSIGNAL); data += 64; size -= 64; } recv (client, buf, 64, 0); + // Then send HELLO and expect WELCOME if there's enough data if (size >= 202) { send (client, (void *) data, 202, MSG_NOSIGNAL); data += 202; size -= 202; + recv (client, buf, 170, 0); + } + // Then send READY and expect INITIATE if there's enough data + if (size >= 301) { + send (client, (void *) data, 301, MSG_NOSIGNAL); + data += 301; + size -= 301; + recv (client, buf, 512, 0); } - recv (client, buf, 64, MSG_DONTWAIT); msleep (250); for (ssize_t sent = 0; size > 0 && (sent != -1 || errno == EINTR); size -= sent > 0 ? sent : 0, data += sent > 0 ? sent : 0) diff --git a/tests/test_connect_curve_fuzzer.cpp b/tests/test_connect_curve_fuzzer.cpp index c6a83d77..cc3f77fa 100644 --- a/tests/test_connect_curve_fuzzer.cpp +++ b/tests/test_connect_curve_fuzzer.cpp @@ -36,15 +36,22 @@ // Test that the ZMTP engine handles invalid handshake when connecting // https://rfc.zeromq.org/spec/37/ +// https://rfc.zeromq.org/spec/26/ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) { + const char *fixed_client_public = + "{{k*81)yMWEF{/BxdMd[5RL^qRFxBgoL<8m.D^KD"; + const char *fixed_client_secret = + "N?Gmik8R[2ACw{b7*[-$S6[4}aO#?DB?#=C"; + setup_test_context (); - setup_testutil_security_curve (); char my_endpoint[MAX_SOCKET_STRING]; fd_t server = bind_socket_resolve_port ("127.0.0.1", "0", my_endpoint); curve_client_data_t curve_client_data = { - valid_server_public, valid_client_public, valid_client_secret}; + fixed_server_public, fixed_client_public, fixed_client_secret}; void *client_mon; void *client = create_and_connect_client ( my_endpoint, socket_config_curve_client, &curve_client_data, &client_mon); @@ -54,18 +61,32 @@ extern "C" int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size) // If there is not enough data for a full greeting, just send what we can // Otherwise send greeting first, as expected by the protocol - uint8_t buf[64]; + uint8_t buf[512]; if (size >= 64) { send (server_accept, (void *) data, 64, MSG_NOSIGNAL); data += 64; size -= 64; } recv (server_accept, buf, 64, 0); + // Then expect HELLO and send WELCOME if there's enough data + if (size >= 170) { + recv (server_accept, buf, 202, 0); + send (server_accept, (void *) data, 170, MSG_NOSIGNAL); + data += 170; + size -= 170; + } + // Then expect INITIATE and send READY if there's enough data + if (size >= 72) { + recv (server_accept, buf, 512, 0); + send (server_accept, (void *) data, 72, MSG_NOSIGNAL); + data += 72; + size -= 72; + } msleep (250); for (ssize_t sent = 0; size > 0 && (sent != -1 || errno == EINTR); size -= sent > 0 ? sent : 0, data += sent > 0 ? sent : 0) sent = send (server_accept, (const char *) data, size, MSG_NOSIGNAL); - recv (server_accept, buf, 64, MSG_DONTWAIT); + recv (server_accept, buf, 512, MSG_DONTWAIT); msleep (250); zmq_msg_t msg; diff --git a/tests/testutil.cpp b/tests/testutil.cpp index 5a2326aa..4c7e9e89 100644 --- a/tests/testutil.cpp +++ b/tests/testutil.cpp @@ -391,14 +391,11 @@ fd_t connect_socket (const char *endpoint_, const int af_, const int protocol_) } struct addrinfo *in, hint; + memset (&hint, 0, sizeof (struct addrinfo)); hint.ai_flags = AI_NUMERICSERV; hint.ai_family = af_; hint.ai_socktype = SOCK_STREAM; hint.ai_protocol = protocol_; - hint.ai_addrlen = 0; - hint.ai_canonname = NULL; - hint.ai_addr = NULL; - hint.ai_next = NULL; TEST_ASSERT_SUCCESS_RAW_ZERO_ERRNO ( getaddrinfo (address, port, &hint, &in)); @@ -444,14 +441,11 @@ fd_t bind_socket_resolve_port (const char *address_, int flag = 1; #endif struct addrinfo *in, hint; + memset (&hint, 0, sizeof (struct addrinfo)); hint.ai_flags = AI_NUMERICSERV; hint.ai_family = af_; hint.ai_socktype = protocol_ == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; hint.ai_protocol = protocol_; - hint.ai_addrlen = 0; - hint.ai_canonname = NULL; - hint.ai_addr = NULL; - hint.ai_next = NULL; TEST_ASSERT_SUCCESS_RAW_ERRNO ( setsockopt (s_pre, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof (int)));