fuzz: refactor memcpy to std::ranges::copy to work around ubsan warn
What changed, and why it matters
This is a minor cleanup change in Bitcoin Core's fuzz testing code (test-only, not production). It replaces a raw memory copy with a safer C++ standard library copy to silence a warning from the Undefined Behavior Sanitizer when the source data is empty. It does not fix a security vulnerability in live Bitcoin software.
No action required. Treat as a routine test-code refactoring. If tracking fuzzing hygiene, note it as a minor UBSan cleanup.
Security signals we found
Change is confined to fuzz test harness (src/test/fuzz/util/net.cpp)
Commit message explicitly frames change as a UBSan warning workaround, not a security fix
No production code paths are modified
No memory safety vulnerability is demonstrated in runtime code
Evidence from the diff
The commit modifies src/test/fuzz/util/net.cpp, a fuzz-test harness. It changes two memcpy calls to std::ranges::copy and switches the consumed byte type from uint8_t to std::byte. The stated purpose is to work around a UBSan warning triggered when ConsumeBytes returns an empty vector and memcpy is called with a null source pointer and size 0. This is a test-harness-only issue; the change is not in production networking code and does not alter runtime behavior in released Bitcoin Core.
Changed components
src/test/fuzz/util/net.cppInspect captured patch +6 / −5
diff --git a/src/test/fuzz/util/net.cpp b/src/test/fuzz/util/net.cpp
index e49c0433..ba17e4e9 100644
--- a/src/test/fuzz/util/net.cpp
+++ b/src/test/fuzz/util/net.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2009-2022 The Bitcoin Core developers
+// Copyright (c) 2009-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@@ -20,6 +20,7 @@
#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <ranges>
#include <thread>
#include <vector>
@@ -322,8 +323,8 @@ std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) co
*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());
+ const auto sin_addr_bytes{m_fuzzed_data_provider.ConsumeBytes<std::byte>(sizeof(addr4->sin_addr))};
+ std::ranges::copy(sin_addr_bytes, reinterpret_cast<std::byte*>(&addr4->sin_addr));
addr4->sin_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);
}
} else {
@@ -333,8 +334,8 @@ std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) co
*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());
+ const auto sin_addr_bytes{m_fuzzed_data_provider.ConsumeBytes<std::byte>(sizeof(addr6->sin6_addr))};
+ std::ranges::copy(sin_addr_bytes, reinterpret_cast<std::byte*>(&addr6->sin6_addr));
addr6->sin6_port = m_fuzzed_data_provider.ConsumeIntegralInRange<uint16_t>(1, 65535);
}
}
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.