diff --git a/source/common/network/addr_family_aware_socket_option_impl.cc b/source/common/network/addr_family_aware_socket_option_impl.cc index 7fbce801960db..c5c4acbdcaba7 100644 --- a/source/common/network/addr_family_aware_socket_option_impl.cc +++ b/source/common/network/addr_family_aware_socket_option_impl.cc @@ -11,6 +11,13 @@ namespace Envoy { namespace Network { namespace { +Address::IpVersion getVersionFromAddress(Address::InstanceConstSharedPtr addr) { + if (addr->ip() != nullptr) { + return addr->ip()->version(); + } + throw EnvoyException("Unable to set socket option on non-IP sockets"); +} + absl::optional getVersionFromSocket(const Socket& socket) { try { // We have local address when the socket is used in a listener but have to @@ -18,10 +25,10 @@ absl::optional getVersionFromSocket(const Socket& socket) { // TODO(htuch): Figure out a way to obtain a consistent interface for IP // version from socket. if (socket.localAddress()) { - return absl::optional(socket.localAddress()->ip()->version()); + return absl::optional(getVersionFromAddress(socket.localAddress())); } else { return absl::optional( - Address::addressFromFd(socket.ioHandle().fd())->ip()->version()); + getVersionFromAddress(Address::addressFromFd(socket.ioHandle().fd()))); } } catch (const EnvoyException&) { // Ignore, we get here because we failed in getsockname(). diff --git a/test/common/network/addr_family_aware_socket_option_impl_test.cc b/test/common/network/addr_family_aware_socket_option_impl_test.cc index 2780f788546d9..442c68ae108c5 100644 --- a/test/common/network/addr_family_aware_socket_option_impl_test.cc +++ b/test/common/network/addr_family_aware_socket_option_impl_test.cc @@ -19,6 +19,15 @@ TEST_F(AddrFamilyAwareSocketOptionImplTest, SetOptionFailure) { EXPECT_LOG_CONTAINS("warning", "Failed to set IP socket option on non-IP socket", EXPECT_FALSE(socket_option.setOption( socket_, envoy::api::v2::core::SocketOption::STATE_PREBIND))); + + Address::InstanceConstSharedPtr pipe_address = + std::make_shared("/foo"); + { + EXPECT_CALL(socket_, localAddress).WillRepeatedly(testing::ReturnRef(pipe_address)); + EXPECT_LOG_CONTAINS("warning", "Failed to set IP socket option on non-IP socket", + EXPECT_FALSE(socket_option.setOption( + socket_, envoy::api::v2::core::SocketOption::STATE_PREBIND))); + } } // If a platform supports IPv4 socket option variant for an IPv4 address, it works diff --git a/test/server/server_corpus/clusterfuzz-testcase-server_fuzz_test-5755877701713920 b/test/server/server_corpus/clusterfuzz-testcase-server_fuzz_test-5755877701713920 new file mode 100644 index 0000000000000..f0ac04d436ee3 --- /dev/null +++ b/test/server/server_corpus/clusterfuzz-testcase-server_fuzz_test-5755877701713920 @@ -0,0 +1,12 @@ +static_resources { + listeners { + address { + pipe { + } + } + filter_chains { + } + freebind { + } + } +}