From 2dec350f26179e88383c9a83f710f4114e25d53d Mon Sep 17 00:00:00 2001 From: davkor Date: Wed, 14 Apr 2021 16:30:39 +0100 Subject: [PATCH 1/9] test: common: network: add udp listener fuzzer. Signed-off-by: davkor --- test/common/network/BUILD | 24 +++++ test/common/network/udp_fuzz.cc | 185 ++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+) create mode 100644 test/common/network/udp_fuzz.cc diff --git a/test/common/network/BUILD b/test/common/network/BUILD index e5949d401931..e38391834b07 100644 --- a/test/common/network/BUILD +++ b/test/common/network/BUILD @@ -393,6 +393,30 @@ envoy_cc_test( ], ) +envoy_cc_fuzz_test( + name = "udp_fuzz", + srcs = ["udp_fuzz.cc"], + corpus = "udp_corpus", + deps = [ + "udp_listener_impl_test_base_lib", + "//source/common/event:dispatcher_lib", + "//source/common/network:address_lib", + "//source/common/network:listener_lib", + "//source/common/network:socket_option_lib", + "//source/common/network:udp_packet_writer_handler_lib", + "//source/common/network:utility_lib", + "//source/common/stats:stats_lib", + "//test/common/network:listener_impl_test_base_lib", + "//test/mocks/network:network_mocks", + "//test/mocks/server:server_mocks", + "//test/test_common:environment_lib", + "//test/test_common:network_utility_lib", + "//test/test_common:threadsafe_singleton_injector_lib", + "//test/test_common:utility_lib", + "@envoy_api//envoy/config/core/v3:pkg_cc_proto", + ], +) + envoy_cc_fuzz_test( name = "utility_fuzz_test", srcs = ["utility_fuzz_test.cc"], diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc new file mode 100644 index 000000000000..b1dda07248d1 --- /dev/null +++ b/test/common/network/udp_fuzz.cc @@ -0,0 +1,185 @@ +#include "test/fuzz/fuzz_runner.h" +#include "envoy/config/core/v3/base.pb.h" + +#include "common/api/os_sys_calls_impl.h" +#include "common/network/address_impl.h" +#include "common/network/socket_option_factory.h" +#include "common/network/socket_option_impl.h" +#include "common/network/udp_listener_impl.h" +#include "common/network/udp_packet_writer_handler_impl.h" +#include "common/network/utility.h" + +#include "test/common/network/udp_listener_impl_test_base.h" +#include "test/mocks/api/mocks.h" +#include "test/mocks/network/mocks.h" +#include "test/mocks/server/mocks.h" +#include "test/test_common/environment.h" +#include "test/test_common/network_utility.h" +#include "test/test_common/threadsafe_singleton_injector.h" +#include "test/test_common/utility.h" + +#include + +namespace Envoy { +// namespace Network { +namespace { + +class UdpFuzz; + +class fuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { + public: + fuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf(upf) {} + ~fuzzUdpListenerCallbacks() = default; + UdpFuzz* my_upf; + void onData(Network::UdpRecvData&& data) override; + void onReadReady() override; + void onWriteReady(const Network::Socket& socket) override; + void onReceiveError(Api::IoError::IoErrorCode error_code) override; + void onDataWorker(Network::UdpRecvData&& data) override; + void post(Network::UdpRecvData&& data) override; + void onDatagramsDropped(uint32_t dropped) override; + uint32_t workerIndex() const override; + Network::UdpPacketWriter& udpPacketWriter() override; +}; + +class UdpFuzz { + public: + UdpFuzz(const uint8_t* buf, size_t len) { + // Prepare environment + api_ = Api::createApiForTest(); + dispatcher_ = api_->allocateDispatcher("test_thread"); + ip_version_ = TestEnvironment::getIpVersionsForTest()[0]; + + server_socket_ = createServerSocket(true, ip_version_); + server_socket_->addOptions( + Network::SocketOptionFactory::buildIpPacketInfoOptions()); + server_socket_->addOptions( + Network::SocketOptionFactory::buildRxQueueOverFlowOptions()); + + // Create packet writer + udp_packet_writer_ = + std::make_unique(server_socket_->ioHandle()); + + // Set up callbacks + fuzzUdpListenerCallbacks fuzzCallbacks(this); + + // Create listener with default config + envoy::config::core::v3::UdpSocketConfig config; + std::unique_ptr listener_ = + std::make_unique( + dispatcherImpl(), server_socket_, fuzzCallbacks, + dispatcherImpl().timeSource(), config); + + Network::Address::Instance* send_to_addr_ = + new Network::Address::Ipv4Instance( + "127.0.0.1", + server_socket_->addressProvider().localAddress()->ip()->port()); + + // Now do all of the fuzzing + FuzzedDataProvider provider(buf, len); + total_packets = provider.ConsumeIntegralInRange(1, 15); + sent_packets = 0; + Network::Test::UdpSyncPeer client_(ip_version_); + // printf("Sending a total of %d\n", total_packets); + for (uint16_t i = 0; i < total_packets; i++) { + // printf("Sending \n"); + std::string packet_ = provider.ConsumeBytesAsString( + provider.ConsumeIntegralInRange(1, 3000)); + // printf("packet size: %lu\n", packet_.size()); + if (packet_.size() == 0) { + packet_ = "EMPTY_PACKET"; + } + client_.write(packet_, *send_to_addr_); + } + dispatcher_->run(Event::Dispatcher::RunType::Block); + + // cleanup + delete send_to_addr_; + } + + Event::DispatcherImpl& dispatcherImpl() { + // We need access to the concrete impl type in order to instantiate a + // Test[Udp]Listener, which instantiates a [Udp]ListenerImpl, which requires + // a DispatcherImpl to access DispatcherImpl::base_, which is not part of + // the Dispatcher API. + Event::DispatcherImpl* impl = + dynamic_cast(dispatcher_.get()); + // RELEASE_ASSERT(impl, "dispatcher dynamic-cast to DispatcherImpl failed"); + return *impl; + } + + Network::SocketSharedPtr createServerSocket( + bool bind, Network::Address::IpVersion version_) { + // Set IP_FREEBIND to allow sendmsg to send with non-local IPv6 source + // address. + return std::make_shared( + Network::Test::getCanonicalLoopbackAddress(version_), +#ifdef IP_FREEBIND + Network::SocketOptionFactory::buildIpFreebindOptions(), +#else + nullptr, +#endif + bind); + } + + Network::SocketSharedPtr server_socket_; + Event::DispatcherPtr dispatcher_; + Api::ApiPtr api_; + Network::UdpPacketWriterPtr udp_packet_writer_; + uint16_t sent_packets; + uint16_t total_packets; + Network::Address::IpVersion ip_version_; +}; + +void fuzzUdpListenerCallbacks::onData(Network::UdpRecvData&& data) { + my_upf->sent_packets++; + if (my_upf->sent_packets == my_upf->total_packets) { + my_upf->dispatcher_->exit(); + } + UNREFERENCED_PARAMETER(data); + return; +} + +void fuzzUdpListenerCallbacks::onReadReady() { return; } + +void fuzzUdpListenerCallbacks::onWriteReady(const Network::Socket& socket) { + UNREFERENCED_PARAMETER(socket); + return; +} + +void fuzzUdpListenerCallbacks::onReceiveError( + Api::IoError::IoErrorCode error_code) { + my_upf->sent_packets++; + if (my_upf->sent_packets == my_upf->total_packets) { + my_upf->dispatcher_->exit(); + } + UNREFERENCED_PARAMETER(error_code); + return; +} +Network::UdpPacketWriter& fuzzUdpListenerCallbacks::udpPacketWriter() { + return *my_upf->udp_packet_writer_; +} +uint32_t fuzzUdpListenerCallbacks::workerIndex() const { return 0; } +void fuzzUdpListenerCallbacks::onDataWorker(Network::UdpRecvData&& data) { + UNREFERENCED_PARAMETER(data); + return; +} +void fuzzUdpListenerCallbacks::post(Network::UdpRecvData&& data) { + UNREFERENCED_PARAMETER(data); + return; +} + +void fuzzUdpListenerCallbacks::onDatagramsDropped(uint32_t dropped) { + my_upf->sent_packets++; + if (my_upf->sent_packets == my_upf->total_packets) { + my_upf->dispatcher_->exit(); + } + UNREFERENCED_PARAMETER(dropped); +} + +DEFINE_FUZZER(const uint8_t* buf, size_t len) { + UdpFuzz udp_instance(buf, len); +} +} // namespace +//} // Network +} // Envoy From fd553b4d6c8cf08b8e96769fb038791a0fbd4645 Mon Sep 17 00:00:00 2001 From: davkor Date: Wed, 14 Apr 2021 16:47:25 +0100 Subject: [PATCH 2/9] Added an initial udp corpus. Signed-off-by: davkor --- test/common/network/udp_fuzz_corpus/seed1.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test/common/network/udp_fuzz_corpus/seed1.txt diff --git a/test/common/network/udp_fuzz_corpus/seed1.txt b/test/common/network/udp_fuzz_corpus/seed1.txt new file mode 100644 index 000000000000..5fb47689faf3 --- /dev/null +++ b/test/common/network/udp_fuzz_corpus/seed1.txt @@ -0,0 +1 @@ +udp-seed1 From e3f055aa56fa626641fc0e8208335f0eae67be2b Mon Sep 17 00:00:00 2001 From: davkor Date: Wed, 14 Apr 2021 16:59:52 +0100 Subject: [PATCH 3/9] Change the name of the corpus dir. Signed-off-by: davkor --- test/common/network/{udp_fuzz_corpus => udp_corpus}/seed1.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename test/common/network/{udp_fuzz_corpus => udp_corpus}/seed1.txt (100%) diff --git a/test/common/network/udp_fuzz_corpus/seed1.txt b/test/common/network/udp_corpus/seed1.txt similarity index 100% rename from test/common/network/udp_fuzz_corpus/seed1.txt rename to test/common/network/udp_corpus/seed1.txt From 7fad32fe7ec47678445c9a27dcdd1a9a7a52a8b8 Mon Sep 17 00:00:00 2001 From: davkor Date: Wed, 14 Apr 2021 22:21:49 +0100 Subject: [PATCH 4/9] tests: common: network: udp_fuzz fix styling. Signed-off-by: davkor --- test/common/network/udp_fuzz.cc | 51 +++++++++++++-------------------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc index b1dda07248d1..acf111bb18a7 100644 --- a/test/common/network/udp_fuzz.cc +++ b/test/common/network/udp_fuzz.cc @@ -1,4 +1,5 @@ -#include "test/fuzz/fuzz_runner.h" +#include + #include "envoy/config/core/v3/base.pb.h" #include "common/api/os_sys_calls_impl.h" @@ -10,6 +11,7 @@ #include "common/network/utility.h" #include "test/common/network/udp_listener_impl_test_base.h" +#include "test/fuzz/fuzz_runner.h" #include "test/mocks/api/mocks.h" #include "test/mocks/network/mocks.h" #include "test/mocks/server/mocks.h" @@ -18,8 +20,6 @@ #include "test/test_common/threadsafe_singleton_injector.h" #include "test/test_common/utility.h" -#include - namespace Envoy { // namespace Network { namespace { @@ -27,7 +27,7 @@ namespace { class UdpFuzz; class fuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { - public: +public: fuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf(upf) {} ~fuzzUdpListenerCallbacks() = default; UdpFuzz* my_upf; @@ -43,7 +43,7 @@ class fuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { }; class UdpFuzz { - public: +public: UdpFuzz(const uint8_t* buf, size_t len) { // Prepare environment api_ = Api::createApiForTest(); @@ -51,14 +51,11 @@ class UdpFuzz { ip_version_ = TestEnvironment::getIpVersionsForTest()[0]; server_socket_ = createServerSocket(true, ip_version_); - server_socket_->addOptions( - Network::SocketOptionFactory::buildIpPacketInfoOptions()); - server_socket_->addOptions( - Network::SocketOptionFactory::buildRxQueueOverFlowOptions()); + server_socket_->addOptions(Network::SocketOptionFactory::buildIpPacketInfoOptions()); + server_socket_->addOptions(Network::SocketOptionFactory::buildRxQueueOverFlowOptions()); // Create packet writer - udp_packet_writer_ = - std::make_unique(server_socket_->ioHandle()); + udp_packet_writer_ = std::make_unique(server_socket_->ioHandle()); // Set up callbacks fuzzUdpListenerCallbacks fuzzCallbacks(this); @@ -66,14 +63,11 @@ class UdpFuzz { // Create listener with default config envoy::config::core::v3::UdpSocketConfig config; std::unique_ptr listener_ = - std::make_unique( - dispatcherImpl(), server_socket_, fuzzCallbacks, - dispatcherImpl().timeSource(), config); + std::make_unique(dispatcherImpl(), server_socket_, fuzzCallbacks, + dispatcherImpl().timeSource(), config); - Network::Address::Instance* send_to_addr_ = - new Network::Address::Ipv4Instance( - "127.0.0.1", - server_socket_->addressProvider().localAddress()->ip()->port()); + Network::Address::Instance* send_to_addr_ = new Network::Address::Ipv4Instance( + "127.0.0.1", server_socket_->addressProvider().localAddress()->ip()->port()); // Now do all of the fuzzing FuzzedDataProvider provider(buf, len); @@ -83,8 +77,8 @@ class UdpFuzz { // printf("Sending a total of %d\n", total_packets); for (uint16_t i = 0; i < total_packets; i++) { // printf("Sending \n"); - std::string packet_ = provider.ConsumeBytesAsString( - provider.ConsumeIntegralInRange(1, 3000)); + std::string packet_ = + provider.ConsumeBytesAsString(provider.ConsumeIntegralInRange(1, 3000)); // printf("packet size: %lu\n", packet_.size()); if (packet_.size() == 0) { packet_ = "EMPTY_PACKET"; @@ -102,14 +96,12 @@ class UdpFuzz { // Test[Udp]Listener, which instantiates a [Udp]ListenerImpl, which requires // a DispatcherImpl to access DispatcherImpl::base_, which is not part of // the Dispatcher API. - Event::DispatcherImpl* impl = - dynamic_cast(dispatcher_.get()); + Event::DispatcherImpl* impl = dynamic_cast(dispatcher_.get()); // RELEASE_ASSERT(impl, "dispatcher dynamic-cast to DispatcherImpl failed"); return *impl; } - Network::SocketSharedPtr createServerSocket( - bool bind, Network::Address::IpVersion version_) { + Network::SocketSharedPtr createServerSocket(bool bind, Network::Address::IpVersion version_) { // Set IP_FREEBIND to allow sendmsg to send with non-local IPv6 source // address. return std::make_shared( @@ -147,8 +139,7 @@ void fuzzUdpListenerCallbacks::onWriteReady(const Network::Socket& socket) { return; } -void fuzzUdpListenerCallbacks::onReceiveError( - Api::IoError::IoErrorCode error_code) { +void fuzzUdpListenerCallbacks::onReceiveError(Api::IoError::IoErrorCode error_code) { my_upf->sent_packets++; if (my_upf->sent_packets == my_upf->total_packets) { my_upf->dispatcher_->exit(); @@ -177,9 +168,7 @@ void fuzzUdpListenerCallbacks::onDatagramsDropped(uint32_t dropped) { UNREFERENCED_PARAMETER(dropped); } -DEFINE_FUZZER(const uint8_t* buf, size_t len) { - UdpFuzz udp_instance(buf, len); -} -} // namespace +DEFINE_FUZZER(const uint8_t* buf, size_t len) { UdpFuzz udp_instance(buf, len); } +} // namespace //} // Network -} // Envoy +} // namespace Envoy From 1bdeee1d8075b6b1a064976c8251eafd8d1c8392 Mon Sep 17 00:00:00 2001 From: davkor Date: Wed, 14 Apr 2021 23:15:48 +0100 Subject: [PATCH 5/9] remove printf statements. Signed-off-by: davkor --- test/common/network/udp_fuzz.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc index acf111bb18a7..5787748d63be 100644 --- a/test/common/network/udp_fuzz.cc +++ b/test/common/network/udp_fuzz.cc @@ -74,12 +74,9 @@ class UdpFuzz { total_packets = provider.ConsumeIntegralInRange(1, 15); sent_packets = 0; Network::Test::UdpSyncPeer client_(ip_version_); - // printf("Sending a total of %d\n", total_packets); for (uint16_t i = 0; i < total_packets; i++) { - // printf("Sending \n"); std::string packet_ = provider.ConsumeBytesAsString(provider.ConsumeIntegralInRange(1, 3000)); - // printf("packet size: %lu\n", packet_.size()); if (packet_.size() == 0) { packet_ = "EMPTY_PACKET"; } From 67ab380e1bd2e6aecab9a12ab66d9cf9b121eaf3 Mon Sep 17 00:00:00 2001 From: davkor Date: Thu, 15 Apr 2021 13:44:04 +0100 Subject: [PATCH 6/9] fix CI. Signed-off-by: davkor --- test/common/network/udp_fuzz.cc | 37 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc index 5787748d63be..7d48f3f975ef 100644 --- a/test/common/network/udp_fuzz.cc +++ b/test/common/network/udp_fuzz.cc @@ -26,10 +26,10 @@ namespace { class UdpFuzz; -class fuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { +class FuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { public: - fuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf(upf) {} - ~fuzzUdpListenerCallbacks() = default; + FuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf(upf) {} + ~FuzzUdpListenerCallbacks() override = default; UdpFuzz* my_upf; void onData(Network::UdpRecvData&& data) override; void onReadReady() override; @@ -58,7 +58,7 @@ class UdpFuzz { udp_packet_writer_ = std::make_unique(server_socket_->ioHandle()); // Set up callbacks - fuzzUdpListenerCallbacks fuzzCallbacks(this); + FuzzUdpListenerCallbacks fuzzCallbacks(this); // Create listener with default config envoy::config::core::v3::UdpSocketConfig config; @@ -77,7 +77,7 @@ class UdpFuzz { for (uint16_t i = 0; i < total_packets; i++) { std::string packet_ = provider.ConsumeBytesAsString(provider.ConsumeIntegralInRange(1, 3000)); - if (packet_.size() == 0) { + if (packet_.empty()) { packet_ = "EMPTY_PACKET"; } client_.write(packet_, *send_to_addr_); @@ -98,11 +98,11 @@ class UdpFuzz { return *impl; } - Network::SocketSharedPtr createServerSocket(bool bind, Network::Address::IpVersion version_) { + Network::SocketSharedPtr createServerSocket(bool bind, Network::Address::IpVersion version) { // Set IP_FREEBIND to allow sendmsg to send with non-local IPv6 source // address. return std::make_shared( - Network::Test::getCanonicalLoopbackAddress(version_), + Network::Test::getCanonicalLoopbackAddress(version), #ifdef IP_FREEBIND Network::SocketOptionFactory::buildIpFreebindOptions(), #else @@ -120,44 +120,39 @@ class UdpFuzz { Network::Address::IpVersion ip_version_; }; -void fuzzUdpListenerCallbacks::onData(Network::UdpRecvData&& data) { +void FuzzUdpListenerCallbacks::onData(Network::UdpRecvData&& data) { my_upf->sent_packets++; if (my_upf->sent_packets == my_upf->total_packets) { my_upf->dispatcher_->exit(); } UNREFERENCED_PARAMETER(data); - return; } -void fuzzUdpListenerCallbacks::onReadReady() { return; } +void FuzzUdpListenerCallbacks::onReadReady() { } -void fuzzUdpListenerCallbacks::onWriteReady(const Network::Socket& socket) { +void FuzzUdpListenerCallbacks::onWriteReady(const Network::Socket& socket) { UNREFERENCED_PARAMETER(socket); - return; } -void fuzzUdpListenerCallbacks::onReceiveError(Api::IoError::IoErrorCode error_code) { +void FuzzUdpListenerCallbacks::onReceiveError(Api::IoError::IoErrorCode error_code) { my_upf->sent_packets++; if (my_upf->sent_packets == my_upf->total_packets) { my_upf->dispatcher_->exit(); } UNREFERENCED_PARAMETER(error_code); - return; } -Network::UdpPacketWriter& fuzzUdpListenerCallbacks::udpPacketWriter() { +Network::UdpPacketWriter& FuzzUdpListenerCallbacks::udpPacketWriter() { return *my_upf->udp_packet_writer_; } -uint32_t fuzzUdpListenerCallbacks::workerIndex() const { return 0; } -void fuzzUdpListenerCallbacks::onDataWorker(Network::UdpRecvData&& data) { +uint32_t FuzzUdpListenerCallbacks::workerIndex() const { return 0; } +void FuzzUdpListenerCallbacks::onDataWorker(Network::UdpRecvData&& data) { UNREFERENCED_PARAMETER(data); - return; } -void fuzzUdpListenerCallbacks::post(Network::UdpRecvData&& data) { +void FuzzUdpListenerCallbacks::post(Network::UdpRecvData&& data) { UNREFERENCED_PARAMETER(data); - return; } -void fuzzUdpListenerCallbacks::onDatagramsDropped(uint32_t dropped) { +void FuzzUdpListenerCallbacks::onDatagramsDropped(uint32_t dropped) { my_upf->sent_packets++; if (my_upf->sent_packets == my_upf->total_packets) { my_upf->dispatcher_->exit(); From d5843c21e92e26b9b228887856c3942d881d78ab Mon Sep 17 00:00:00 2001 From: davkor Date: Thu, 15 Apr 2021 14:55:20 +0100 Subject: [PATCH 7/9] fix styling and varnames. Signed-off-by: davkor --- test/common/network/udp_fuzz.cc | 41 +++++++++++++++------------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc index 7d48f3f975ef..f099da42c4c7 100644 --- a/test/common/network/udp_fuzz.cc +++ b/test/common/network/udp_fuzz.cc @@ -21,16 +21,15 @@ #include "test/test_common/utility.h" namespace Envoy { -// namespace Network { namespace { class UdpFuzz; class FuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { public: - FuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf(upf) {} + FuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf_(upf) {} ~FuzzUdpListenerCallbacks() override = default; - UdpFuzz* my_upf; + UdpFuzz* my_upf_; void onData(Network::UdpRecvData&& data) override; void onReadReady() override; void onWriteReady(const Network::Socket& socket) override; @@ -71,10 +70,9 @@ class UdpFuzz { // Now do all of the fuzzing FuzzedDataProvider provider(buf, len); - total_packets = provider.ConsumeIntegralInRange(1, 15); - sent_packets = 0; + total_packets_ = provider.ConsumeIntegralInRange(1, 15); Network::Test::UdpSyncPeer client_(ip_version_); - for (uint16_t i = 0; i < total_packets; i++) { + for (uint16_t i = 0; i < total_packets_; i++) { std::string packet_ = provider.ConsumeBytesAsString(provider.ConsumeIntegralInRange(1, 3000)); if (packet_.empty()) { @@ -115,52 +113,49 @@ class UdpFuzz { Event::DispatcherPtr dispatcher_; Api::ApiPtr api_; Network::UdpPacketWriterPtr udp_packet_writer_; - uint16_t sent_packets; - uint16_t total_packets; + uint16_t sent_packets_ = 0; + uint16_t total_packets_; Network::Address::IpVersion ip_version_; }; void FuzzUdpListenerCallbacks::onData(Network::UdpRecvData&& data) { - my_upf->sent_packets++; - if (my_upf->sent_packets == my_upf->total_packets) { - my_upf->dispatcher_->exit(); + my_upf_->sent_packets_++; + if (my_upf_->sent_packets_ == my_upf_->total_packets_) { + my_upf_->dispatcher_->exit(); } UNREFERENCED_PARAMETER(data); } -void FuzzUdpListenerCallbacks::onReadReady() { } +void FuzzUdpListenerCallbacks::onReadReady() {} void FuzzUdpListenerCallbacks::onWriteReady(const Network::Socket& socket) { UNREFERENCED_PARAMETER(socket); } void FuzzUdpListenerCallbacks::onReceiveError(Api::IoError::IoErrorCode error_code) { - my_upf->sent_packets++; - if (my_upf->sent_packets == my_upf->total_packets) { - my_upf->dispatcher_->exit(); + my_upf_->sent_packets_++; + if (my_upf_->sent_packets_ == my_upf_->total_packets_) { + my_upf_->dispatcher_->exit(); } UNREFERENCED_PARAMETER(error_code); } Network::UdpPacketWriter& FuzzUdpListenerCallbacks::udpPacketWriter() { - return *my_upf->udp_packet_writer_; + return *my_upf_->udp_packet_writer_; } uint32_t FuzzUdpListenerCallbacks::workerIndex() const { return 0; } void FuzzUdpListenerCallbacks::onDataWorker(Network::UdpRecvData&& data) { UNREFERENCED_PARAMETER(data); } -void FuzzUdpListenerCallbacks::post(Network::UdpRecvData&& data) { - UNREFERENCED_PARAMETER(data); -} +void FuzzUdpListenerCallbacks::post(Network::UdpRecvData&& data) { UNREFERENCED_PARAMETER(data); } void FuzzUdpListenerCallbacks::onDatagramsDropped(uint32_t dropped) { - my_upf->sent_packets++; - if (my_upf->sent_packets == my_upf->total_packets) { - my_upf->dispatcher_->exit(); + my_upf_->sent_packets_++; + if (my_upf_->sent_packets_ == my_upf_->total_packets_) { + my_upf_->dispatcher_->exit(); } UNREFERENCED_PARAMETER(dropped); } DEFINE_FUZZER(const uint8_t* buf, size_t len) { UdpFuzz udp_instance(buf, len); } } // namespace -//} // Network } // namespace Envoy From bebe1078d621f53c4e2a800d096c142566cd254b Mon Sep 17 00:00:00 2001 From: davkor Date: Thu, 15 Apr 2021 15:40:28 +0100 Subject: [PATCH 8/9] fix minor nits. Signed-off-by: davkor --- test/common/network/udp_fuzz.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc index f099da42c4c7..84cf1393d700 100644 --- a/test/common/network/udp_fuzz.cc +++ b/test/common/network/udp_fuzz.cc @@ -29,7 +29,6 @@ class FuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { public: FuzzUdpListenerCallbacks(UdpFuzz* upf) : my_upf_(upf) {} ~FuzzUdpListenerCallbacks() override = default; - UdpFuzz* my_upf_; void onData(Network::UdpRecvData&& data) override; void onReadReady() override; void onWriteReady(const Network::Socket& socket) override; @@ -39,6 +38,9 @@ class FuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { void onDatagramsDropped(uint32_t dropped) override; uint32_t workerIndex() const override; Network::UdpPacketWriter& udpPacketWriter() override; + +private: + UdpFuzz* my_upf_; }; class UdpFuzz { @@ -70,7 +72,8 @@ class UdpFuzz { // Now do all of the fuzzing FuzzedDataProvider provider(buf, len); - total_packets_ = provider.ConsumeIntegralInRange(1, 15); + static const int MaxPackets = 15; + total_packets_ = provider.ConsumeIntegralInRange(1, MaxPackets); Network::Test::UdpSyncPeer client_(ip_version_); for (uint16_t i = 0; i < total_packets_; i++) { std::string packet_ = @@ -92,7 +95,6 @@ class UdpFuzz { // a DispatcherImpl to access DispatcherImpl::base_, which is not part of // the Dispatcher API. Event::DispatcherImpl* impl = dynamic_cast(dispatcher_.get()); - // RELEASE_ASSERT(impl, "dispatcher dynamic-cast to DispatcherImpl failed"); return *impl; } From 056fbe58506795b7c65c8fafdf6c1b71378c8b23 Mon Sep 17 00:00:00 2001 From: davkor Date: Mon, 19 Apr 2021 21:02:10 +0100 Subject: [PATCH 9/9] tests: common: network: udp_fuzzing: enable different sockets. Signed-off-by: davkor --- test/common/network/udp_fuzz.cc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/common/network/udp_fuzz.cc b/test/common/network/udp_fuzz.cc index 84cf1393d700..792f1f93286b 100644 --- a/test/common/network/udp_fuzz.cc +++ b/test/common/network/udp_fuzz.cc @@ -23,6 +23,12 @@ namespace Envoy { namespace { +class OverrideOsSysCallsImpl : public Api::OsSysCallsImpl { +public: + MOCK_METHOD(bool, supportsUdpGro, (), (const)); + MOCK_METHOD(bool, supportsMmsg, (), (const)); +}; + class UdpFuzz; class FuzzUdpListenerCallbacks : public Network::UdpListenerCallbacks { @@ -63,6 +69,19 @@ class UdpFuzz { // Create listener with default config envoy::config::core::v3::UdpSocketConfig config; + + FuzzedDataProvider provider(buf, len); + uint16_t SocketType = provider.ConsumeIntegralInRange(0, 2); + if (SocketType == 0) { + config.mutable_prefer_gro()->set_value(true); + ON_CALL(override_syscall_, supportsUdpGro()).WillByDefault(Return(true)); + } else if (SocketType == 1) { + ON_CALL(override_syscall_, supportsMmsg()).WillByDefault(Return(true)); + } else { + ON_CALL(override_syscall_, supportsMmsg()).WillByDefault(Return(false)); + ON_CALL(override_syscall_, supportsUdpGro()).WillByDefault(Return(false)); + } + std::unique_ptr listener_ = std::make_unique(dispatcherImpl(), server_socket_, fuzzCallbacks, dispatcherImpl().timeSource(), config); @@ -71,7 +90,6 @@ class UdpFuzz { "127.0.0.1", server_socket_->addressProvider().localAddress()->ip()->port()); // Now do all of the fuzzing - FuzzedDataProvider provider(buf, len); static const int MaxPackets = 15; total_packets_ = provider.ConsumeIntegralInRange(1, MaxPackets); Network::Test::UdpSyncPeer client_(ip_version_); @@ -118,6 +136,8 @@ class UdpFuzz { uint16_t sent_packets_ = 0; uint16_t total_packets_; Network::Address::IpVersion ip_version_; + NiceMock override_syscall_; + TestThreadsafeSingletonInjector os_calls{&override_syscall_}; }; void FuzzUdpListenerCallbacks::onData(Network::UdpRecvData&& data) {