fuzz: set the output argument of FuzzedSock::Accept()

`FuzzedSock::Accept()` properly returns a new socket, but it forgot to
set the output argument `addr`, like `accept(2)` is expected to.

This could lead to reading uninitialized data during testing when we
read it, e.g. from `CService::SetSockAddr()` which reads the `sa_family`
member.

Set `addr` to a fuzzed IPv4 or IPv6 address.
This commit is contained in:
Vasil Dimov 2024-11-15 15:06:39 +01:00
parent ccc2d3abcd
commit 83199523c9
No known key found for this signature in database
GPG key ID: 54DF06F64B55CBBF

View file

@ -304,6 +304,33 @@ std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) co
SetFuzzedErrNo(m_fuzzed_data_provider, accept_errnos);
return std::unique_ptr<FuzzedSock>();
}
if (addr != nullptr) {
// Set a fuzzed address in the output argument addr.
memset(addr, 0x00, *addr_len);
if (m_fuzzed_data_provider.ConsumeBool()) {
// IPv4
const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in));
if (*addr_len >= write_len) {
*addr_len = write_len;
auto addr4 = reinterpret_cast<sockaddr_in*>(addr);
addr4->sin_family = AF_INET;
const auto sin_addr_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(sizeof(addr4->sin_addr));
memcpy(&addr4->sin_addr, sin_addr_bytes.data(), sin_addr_bytes.size());
addr4->sin_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);
}
} else {
// IPv6
const socklen_t write_len = static_cast<socklen_t>(sizeof(sockaddr_in6));
if (*addr_len >= write_len) {
*addr_len = write_len;
auto addr6 = reinterpret_cast<sockaddr_in6*>(addr);
addr6->sin6_family = AF_INET6;
const auto sin_addr_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(sizeof(addr6->sin6_addr));
memcpy(&addr6->sin6_addr, sin_addr_bytes.data(), sin_addr_bytes.size());
addr6->sin6_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);
}
}
}
return std::make_unique<FuzzedSock>(m_fuzzed_data_provider);
}