aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormerge-script <fanquake@gmail.com>2024-06-04 14:56:47 +0100
committermerge-script <fanquake@gmail.com>2024-06-04 14:56:47 +0100
commitd39f15a8a5b06d68070a3434a81c6840d4f87715 (patch)
tree09590780f38c14add72e783dc7d6bdd2609e879f /src
parent9efc2af3be5817972d9899893c343fc4deab7df5 (diff)
parent22d0f1a27ef7733b51b3c2138a8d01713df8f248 (diff)
downloadbitcoin-d39f15a8a5b06d68070a3434a81c6840d4f87715.tar.xz
Merge bitcoin/bitcoin#30211: fuzz: Make FuzzedSock fuzz friendlier
22d0f1a27ef7733b51b3c2138a8d01713df8f248 [fuzz] Avoid endless waiting in FuzzedSock::{Wait,WaitMany} (marcofleon) a7fceda68bb62fe3d9060fcf52e33b2f64a2acf9 [fuzz] Make peeking through FuzzedSock::Recv fuzzer friendly (dergoegge) 865cdf3692590bc6b1121524fe1bee188788b791 [fuzz] Use fuzzer friendly ConsumeRandomLengthByteVector in FuzzedSock::Recv (dergoegge) Pull request description: `FuzzedSock` has a few issues that block a fuzzer from making progress. See commit messages for details. ACKs for top commit: marcofleon: Tested ACK 22d0f1a27ef7733b51b3c2138a8d01713df8f248 brunoerg: utACK 22d0f1a27ef7733b51b3c2138a8d01713df8f248 Tree-SHA512: 2d66fc94ba58b6652ae234bd1dcd33b7d685b5054fe83e0cd624b053dd51519c23148f43a865ab8c8bc5fc2dc25e701952831b99159687474978a90348faa4c5
Diffstat (limited to 'src')
-rw-r--r--src/test/fuzz/util/net.cpp27
-rw-r--r--src/test/fuzz/util/net.h2
2 files changed, 19 insertions, 10 deletions
diff --git a/src/test/fuzz/util/net.cpp b/src/test/fuzz/util/net.cpp
index 99151bb84d..5e7aae670e 100644
--- a/src/test/fuzz/util/net.cpp
+++ b/src/test/fuzz/util/net.cpp
@@ -193,21 +193,20 @@ ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool()};
if (m_peek_data.has_value()) {
// `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`.
- random_bytes.assign({m_peek_data.value()});
+ random_bytes = m_peek_data.value();
if ((flags & MSG_PEEK) == 0) {
m_peek_data.reset();
}
pad_to_len_bytes = false;
} else if ((flags & MSG_PEEK) != 0) {
// New call with `MSG_PEEK`.
- random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(1);
+ random_bytes = ConsumeRandomLengthByteVector(m_fuzzed_data_provider, len);
if (!random_bytes.empty()) {
- m_peek_data = random_bytes[0];
+ m_peek_data = random_bytes;
pad_to_len_bytes = false;
}
} else {
- random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(
- m_fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, len));
+ random_bytes = ConsumeRandomLengthByteVector(m_fuzzed_data_provider, len);
}
if (random_bytes.empty()) {
const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
@@ -216,7 +215,11 @@ ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
}
return r;
}
- std::memcpy(buf, random_bytes.data(), random_bytes.size());
+ // `random_bytes` might exceed the size of `buf` if e.g. Recv is called with
+ // len=N and MSG_PEEK first and afterwards called with len=M (M < N) and
+ // without MSG_PEEK.
+ size_t recv_len{std::min(random_bytes.size(), len)};
+ std::memcpy(buf, random_bytes.data(), recv_len);
if (pad_to_len_bytes) {
if (len > random_bytes.size()) {
std::memset((char*)buf + random_bytes.size(), 0, len - random_bytes.size());
@@ -226,7 +229,7 @@ ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) {
std::this_thread::sleep_for(std::chrono::milliseconds{2});
}
- return random_bytes.size();
+ return recv_len;
}
int FuzzedSock::Connect(const sockaddr*, socklen_t) const
@@ -380,7 +383,10 @@ bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event*
return false;
}
if (occurred != nullptr) {
- *occurred = m_fuzzed_data_provider.ConsumeBool() ? requested : 0;
+ // We simulate the requested event as occured when ConsumeBool()
+ // returns false. This avoids simulating endless waiting if the
+ // FuzzedDataProvider runs out of data.
+ *occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : requested;
}
return true;
}
@@ -389,7 +395,10 @@ bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& even
{
for (auto& [sock, events] : events_per_sock) {
(void)sock;
- events.occurred = m_fuzzed_data_provider.ConsumeBool() ? events.requested : 0;
+ // We simulate the requested event as occured when ConsumeBool()
+ // returns false. This avoids simulating endless waiting if the
+ // FuzzedDataProvider runs out of data.
+ events.occurred = m_fuzzed_data_provider.ConsumeBool() ? 0 : events.requested;
}
return true;
}
diff --git a/src/test/fuzz/util/net.h b/src/test/fuzz/util/net.h
index a6c9e23f2e..ed02680676 100644
--- a/src/test/fuzz/util/net.h
+++ b/src/test/fuzz/util/net.h
@@ -43,7 +43,7 @@ class FuzzedSock : public Sock
* If `MSG_PEEK` is used, then our `Recv()` returns some random data as usual, but on the next
* `Recv()` call we must return the same data, thus we remember it here.
*/
- mutable std::optional<uint8_t> m_peek_data;
+ mutable std::optional<std::vector<uint8_t>> m_peek_data;
/**
* Whether to pretend that the socket is select(2)-able. This is randomly set in the