Bitcoin Core  24.1.0
P2P Digital Currency
util.cpp
Go to the documentation of this file.
1 // Copyright (c) 2021 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <consensus/amount.h>
6 #include <net_processing.h>
7 #include <netmessagemaker.h>
8 #include <pubkey.h>
9 #include <test/fuzz/util.h>
10 #include <test/util/script.h>
11 #include <util/overflow.h>
12 #include <util/rbf.h>
13 #include <util/time.h>
14 #include <version.h>
15 
16 #include <memory>
17 
19  : m_fuzzed_data_provider{fuzzed_data_provider}
20 {
21  m_socket = fuzzed_data_provider.ConsumeIntegralInRange<SOCKET>(INVALID_SOCKET - 1, INVALID_SOCKET);
22 }
23 
25 {
26  // Sock::~Sock() will be called after FuzzedSock::~FuzzedSock() and it will call
27  // close(m_socket) if m_socket is not INVALID_SOCKET.
28  // Avoid closing an arbitrary file descriptor (m_socket is just a random very high number which
29  // theoretically may concide with a real opened file descriptor).
31 }
32 
34 {
35  assert(false && "Move of Sock into FuzzedSock not allowed.");
36  return *this;
37 }
38 
39 ssize_t FuzzedSock::Send(const void* data, size_t len, int flags) const
40 {
41  constexpr std::array send_errnos{
42  EACCES,
43  EAGAIN,
44  EALREADY,
45  EBADF,
46  ECONNRESET,
47  EDESTADDRREQ,
48  EFAULT,
49  EINTR,
50  EINVAL,
51  EISCONN,
52  EMSGSIZE,
53  ENOBUFS,
54  ENOMEM,
55  ENOTCONN,
56  ENOTSOCK,
57  EOPNOTSUPP,
58  EPIPE,
59  EWOULDBLOCK,
60  };
62  return len;
63  }
64  const ssize_t r = m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(-1, len);
65  if (r == -1) {
67  }
68  return r;
69 }
70 
71 ssize_t FuzzedSock::Recv(void* buf, size_t len, int flags) const
72 {
73  // Have a permanent error at recv_errnos[0] because when the fuzzed data is exhausted
74  // SetFuzzedErrNo() will always return the first element and we want to avoid Recv()
75  // returning -1 and setting errno to EAGAIN repeatedly.
76  constexpr std::array recv_errnos{
77  ECONNREFUSED,
78  EAGAIN,
79  EBADF,
80  EFAULT,
81  EINTR,
82  EINVAL,
83  ENOMEM,
84  ENOTCONN,
85  ENOTSOCK,
86  EWOULDBLOCK,
87  };
88  assert(buf != nullptr || len == 0);
89  if (len == 0 || m_fuzzed_data_provider.ConsumeBool()) {
90  const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
91  if (r == -1) {
93  }
94  return r;
95  }
96  std::vector<uint8_t> random_bytes;
97  bool pad_to_len_bytes{m_fuzzed_data_provider.ConsumeBool()};
98  if (m_peek_data.has_value()) {
99  // `MSG_PEEK` was used in the preceding `Recv()` call, return `m_peek_data`.
100  random_bytes.assign({m_peek_data.value()});
101  if ((flags & MSG_PEEK) == 0) {
102  m_peek_data.reset();
103  }
104  pad_to_len_bytes = false;
105  } else if ((flags & MSG_PEEK) != 0) {
106  // New call with `MSG_PEEK`.
107  random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(1);
108  if (!random_bytes.empty()) {
109  m_peek_data = random_bytes[0];
110  pad_to_len_bytes = false;
111  }
112  } else {
113  random_bytes = m_fuzzed_data_provider.ConsumeBytes<uint8_t>(
115  }
116  if (random_bytes.empty()) {
117  const ssize_t r = m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
118  if (r == -1) {
120  }
121  return r;
122  }
123  std::memcpy(buf, random_bytes.data(), random_bytes.size());
124  if (pad_to_len_bytes) {
125  if (len > random_bytes.size()) {
126  std::memset((char*)buf + random_bytes.size(), 0, len - random_bytes.size());
127  }
128  return len;
129  }
130  if (m_fuzzed_data_provider.ConsumeBool() && std::getenv("FUZZED_SOCKET_FAKE_LATENCY") != nullptr) {
131  std::this_thread::sleep_for(std::chrono::milliseconds{2});
132  }
133  return random_bytes.size();
134 }
135 
136 int FuzzedSock::Connect(const sockaddr*, socklen_t) const
137 {
138  // Have a permanent error at connect_errnos[0] because when the fuzzed data is exhausted
139  // SetFuzzedErrNo() will always return the first element and we want to avoid Connect()
140  // returning -1 and setting errno to EAGAIN repeatedly.
141  constexpr std::array connect_errnos{
142  ECONNREFUSED,
143  EAGAIN,
144  ECONNRESET,
145  EHOSTUNREACH,
146  EINPROGRESS,
147  EINTR,
148  ENETUNREACH,
149  ETIMEDOUT,
150  };
152  SetFuzzedErrNo(m_fuzzed_data_provider, connect_errnos);
153  return -1;
154  }
155  return 0;
156 }
157 
158 int FuzzedSock::Bind(const sockaddr*, socklen_t) const
159 {
160  // Have a permanent error at bind_errnos[0] because when the fuzzed data is exhausted
161  // SetFuzzedErrNo() will always set the global errno to bind_errnos[0]. We want to
162  // avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)
163  // repeatedly because proper code should retry on temporary errors, leading to an
164  // infinite loop.
165  constexpr std::array bind_errnos{
166  EACCES,
167  EADDRINUSE,
168  EADDRNOTAVAIL,
169  EAGAIN,
170  };
173  return -1;
174  }
175  return 0;
176 }
177 
178 int FuzzedSock::Listen(int) const
179 {
180  // Have a permanent error at listen_errnos[0] because when the fuzzed data is exhausted
181  // SetFuzzedErrNo() will always set the global errno to listen_errnos[0]. We want to
182  // avoid this method returning -1 and setting errno to a temporary error (like EAGAIN)
183  // repeatedly because proper code should retry on temporary errors, leading to an
184  // infinite loop.
185  constexpr std::array listen_errnos{
186  EADDRINUSE,
187  EINVAL,
188  EOPNOTSUPP,
189  };
191  SetFuzzedErrNo(m_fuzzed_data_provider, listen_errnos);
192  return -1;
193  }
194  return 0;
195 }
196 
197 std::unique_ptr<Sock> FuzzedSock::Accept(sockaddr* addr, socklen_t* addr_len) const
198 {
199  constexpr std::array accept_errnos{
200  ECONNABORTED,
201  EINTR,
202  ENOMEM,
203  };
205  SetFuzzedErrNo(m_fuzzed_data_provider, accept_errnos);
206  return std::unique_ptr<FuzzedSock>();
207  }
208  return std::make_unique<FuzzedSock>(m_fuzzed_data_provider);
209 }
210 
211 int FuzzedSock::GetSockOpt(int level, int opt_name, void* opt_val, socklen_t* opt_len) const
212 {
213  constexpr std::array getsockopt_errnos{
214  ENOMEM,
215  ENOBUFS,
216  };
218  SetFuzzedErrNo(m_fuzzed_data_provider, getsockopt_errnos);
219  return -1;
220  }
221  if (opt_val == nullptr) {
222  return 0;
223  }
224  std::memcpy(opt_val,
226  *opt_len);
227  return 0;
228 }
229 
230 int FuzzedSock::SetSockOpt(int, int, const void*, socklen_t) const
231 {
232  constexpr std::array setsockopt_errnos{
233  ENOMEM,
234  ENOBUFS,
235  };
237  SetFuzzedErrNo(m_fuzzed_data_provider, setsockopt_errnos);
238  return -1;
239  }
240  return 0;
241 }
242 
243 int FuzzedSock::GetSockName(sockaddr* name, socklen_t* name_len) const
244 {
245  constexpr std::array getsockname_errnos{
246  ECONNRESET,
247  ENOBUFS,
248  };
250  SetFuzzedErrNo(m_fuzzed_data_provider, getsockname_errnos);
251  return -1;
252  }
253  *name_len = m_fuzzed_data_provider.ConsumeData(name, *name_len);
254  return 0;
255 }
256 
257 bool FuzzedSock::Wait(std::chrono::milliseconds timeout, Event requested, Event* occurred) const
258 {
259  constexpr std::array wait_errnos{
260  EBADF,
261  EINTR,
262  EINVAL,
263  };
266  return false;
267  }
268  if (occurred != nullptr) {
269  *occurred = m_fuzzed_data_provider.ConsumeBool() ? requested : 0;
270  }
271  return true;
272 }
273 
274 bool FuzzedSock::WaitMany(std::chrono::milliseconds timeout, EventsPerSock& events_per_sock) const
275 {
276  for (auto& [sock, events] : events_per_sock) {
277  (void)sock;
278  events.occurred = m_fuzzed_data_provider.ConsumeBool() ? events.requested : 0;
279  }
280  return true;
281 }
282 
283 bool FuzzedSock::IsConnected(std::string& errmsg) const
284 {
286  return true;
287  }
288  errmsg = "disconnected at random by the fuzzer";
289  return false;
290 }
291 
292 void FillNode(FuzzedDataProvider& fuzzed_data_provider, ConnmanTestMsg& connman, CNode& node) noexcept
293 {
294  connman.Handshake(node,
295  /*successfully_connected=*/fuzzed_data_provider.ConsumeBool(),
296  /*remote_services=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS),
297  /*local_services=*/ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS),
298  /*version=*/fuzzed_data_provider.ConsumeIntegralInRange<int32_t>(MIN_PEER_PROTO_VERSION, std::numeric_limits<int32_t>::max()),
299  /*relay_txs=*/fuzzed_data_provider.ConsumeBool());
300 }
301 
302 CAmount ConsumeMoney(FuzzedDataProvider& fuzzed_data_provider, const std::optional<CAmount>& max) noexcept
303 {
304  return fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(0, max.value_or(MAX_MONEY));
305 }
306 
307 int64_t ConsumeTime(FuzzedDataProvider& fuzzed_data_provider, const std::optional<int64_t>& min, const std::optional<int64_t>& max) noexcept
308 {
309  // Avoid t=0 (1970-01-01T00:00:00Z) since SetMockTime(0) disables mocktime.
310  static const int64_t time_min{ParseISO8601DateTime("2000-01-01T00:00:01Z")};
311  static const int64_t time_max{ParseISO8601DateTime("2100-12-31T23:59:59Z")};
312  return fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(min.value_or(time_min), max.value_or(time_max));
313 }
314 
315 CMutableTransaction ConsumeTransaction(FuzzedDataProvider& fuzzed_data_provider, const std::optional<std::vector<uint256>>& prevout_txids, const int max_num_in, const int max_num_out) noexcept
316 {
317  CMutableTransaction tx_mut;
318  const auto p2wsh_op_true = fuzzed_data_provider.ConsumeBool();
319  tx_mut.nVersion = fuzzed_data_provider.ConsumeBool() ?
321  fuzzed_data_provider.ConsumeIntegral<int32_t>();
322  tx_mut.nLockTime = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
323  const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_in);
324  const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(0, max_num_out);
325  for (int i = 0; i < num_in; ++i) {
326  const auto& txid_prev = prevout_txids ?
327  PickValue(fuzzed_data_provider, *prevout_txids) :
328  ConsumeUInt256(fuzzed_data_provider);
329  const auto index_out = fuzzed_data_provider.ConsumeIntegralInRange<uint32_t>(0, max_num_out);
330  const auto sequence = ConsumeSequence(fuzzed_data_provider);
331  const auto script_sig = p2wsh_op_true ? CScript{} : ConsumeScript(fuzzed_data_provider);
332  CScriptWitness script_wit;
333  if (p2wsh_op_true) {
334  script_wit.stack = std::vector<std::vector<uint8_t>>{WITNESS_STACK_ELEM_OP_TRUE};
335  } else {
336  script_wit = ConsumeScriptWitness(fuzzed_data_provider);
337  }
338  CTxIn in;
339  in.prevout = COutPoint{txid_prev, index_out};
340  in.nSequence = sequence;
341  in.scriptSig = script_sig;
342  in.scriptWitness = script_wit;
343 
344  tx_mut.vin.push_back(in);
345  }
346  for (int i = 0; i < num_out; ++i) {
347  const auto amount = fuzzed_data_provider.ConsumeIntegralInRange<CAmount>(-10, 50 * COIN + 10);
348  const auto script_pk = p2wsh_op_true ?
349  P2WSH_OP_TRUE :
350  ConsumeScript(fuzzed_data_provider, /*maybe_p2wsh=*/true);
351  tx_mut.vout.emplace_back(amount, script_pk);
352  }
353  return tx_mut;
354 }
355 
356 CScriptWitness ConsumeScriptWitness(FuzzedDataProvider& fuzzed_data_provider, const size_t max_stack_elem_size) noexcept
357 {
359  const auto n_elements = fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0, max_stack_elem_size);
360  for (size_t i = 0; i < n_elements; ++i) {
361  ret.stack.push_back(ConsumeRandomLengthByteVector(fuzzed_data_provider));
362  }
363  return ret;
364 }
365 
366 CScript ConsumeScript(FuzzedDataProvider& fuzzed_data_provider, const bool maybe_p2wsh) noexcept
367 {
368  CScript r_script{};
369  {
370  // Keep a buffer of bytes to allow the fuzz engine to produce smaller
371  // inputs to generate CScripts with repeated data.
372  static constexpr unsigned MAX_BUFFER_SZ{128};
373  std::vector<uint8_t> buffer(MAX_BUFFER_SZ, uint8_t{'a'});
374  while (fuzzed_data_provider.ConsumeBool()) {
375  CallOneOf(
376  fuzzed_data_provider,
377  [&] {
378  // Insert byte vector directly to allow malformed or unparsable scripts
379  r_script.insert(r_script.end(), buffer.begin(), buffer.begin() + fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BUFFER_SZ));
380  },
381  [&] {
382  // Push a byte vector from the buffer
383  r_script << std::vector<uint8_t>{buffer.begin(), buffer.begin() + fuzzed_data_provider.ConsumeIntegralInRange(0U, MAX_BUFFER_SZ)};
384  },
385  [&] {
386  // Push multisig
387  // There is a special case for this to aid the fuzz engine
388  // navigate the highly structured multisig format.
389  r_script << fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 22);
390  int num_data{fuzzed_data_provider.ConsumeIntegralInRange(1, 22)};
391  std::vector<uint8_t> pubkey_comp{buffer.begin(), buffer.begin() + CPubKey::COMPRESSED_SIZE};
392  pubkey_comp.front() = fuzzed_data_provider.ConsumeIntegralInRange(2, 3); // Set first byte for GetLen() to pass
393  std::vector<uint8_t> pubkey_uncomp{buffer.begin(), buffer.begin() + CPubKey::SIZE};
394  pubkey_uncomp.front() = fuzzed_data_provider.ConsumeIntegralInRange(4, 7); // Set first byte for GetLen() to pass
395  while (num_data--) {
396  auto& pubkey{fuzzed_data_provider.ConsumeBool() ? pubkey_uncomp : pubkey_comp};
397  if (fuzzed_data_provider.ConsumeBool()) {
398  pubkey.back() = num_data; // Make each pubkey different
399  }
400  r_script << pubkey;
401  }
402  r_script << fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 22);
403  },
404  [&] {
405  // Mutate the buffer
406  const auto vec{ConsumeRandomLengthByteVector(fuzzed_data_provider, /*max_length=*/MAX_BUFFER_SZ)};
407  std::copy(vec.begin(), vec.end(), buffer.begin());
408  },
409  [&] {
410  // Push an integral
411  r_script << fuzzed_data_provider.ConsumeIntegral<int64_t>();
412  },
413  [&] {
414  // Push an opcode
415  r_script << ConsumeOpcodeType(fuzzed_data_provider);
416  },
417  [&] {
418  // Push a scriptnum
419  r_script << ConsumeScriptNum(fuzzed_data_provider);
420  });
421  }
422  }
423  if (maybe_p2wsh && fuzzed_data_provider.ConsumeBool()) {
424  uint256 script_hash;
425  CSHA256().Write(r_script.data(), r_script.size()).Finalize(script_hash.begin());
426  r_script.clear();
427  r_script << OP_0 << ToByteVector(script_hash);
428  }
429  return r_script;
430 }
431 
432 uint32_t ConsumeSequence(FuzzedDataProvider& fuzzed_data_provider) noexcept
433 {
434  return fuzzed_data_provider.ConsumeBool() ?
435  fuzzed_data_provider.PickValueInArray({
439  }) :
440  fuzzed_data_provider.ConsumeIntegral<uint32_t>();
441 }
442 
444 {
445  CTxDestination tx_destination;
446  const size_t call_size{CallOneOf(
447  fuzzed_data_provider,
448  [&] {
449  tx_destination = CNoDestination{};
450  },
451  [&] {
452  tx_destination = PKHash{ConsumeUInt160(fuzzed_data_provider)};
453  },
454  [&] {
455  tx_destination = ScriptHash{ConsumeUInt160(fuzzed_data_provider)};
456  },
457  [&] {
458  tx_destination = WitnessV0ScriptHash{ConsumeUInt256(fuzzed_data_provider)};
459  },
460  [&] {
461  tx_destination = WitnessV0KeyHash{ConsumeUInt160(fuzzed_data_provider)};
462  },
463  [&] {
464  tx_destination = WitnessV1Taproot{XOnlyPubKey{ConsumeUInt256(fuzzed_data_provider)}};
465  },
466  [&] {
467  WitnessUnknown witness_unknown{};
468  witness_unknown.version = fuzzed_data_provider.ConsumeIntegralInRange(2, 16);
469  std::vector<uint8_t> witness_unknown_program_1{fuzzed_data_provider.ConsumeBytes<uint8_t>(40)};
470  if (witness_unknown_program_1.size() < 2) {
471  witness_unknown_program_1 = {0, 0};
472  }
473  witness_unknown.length = witness_unknown_program_1.size();
474  std::copy(witness_unknown_program_1.begin(), witness_unknown_program_1.end(), witness_unknown.program);
475  tx_destination = witness_unknown;
476  })};
477  Assert(call_size == std::variant_size_v<CTxDestination>);
478  return tx_destination;
479 }
480 
481 CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider& fuzzed_data_provider, const CTransaction& tx) noexcept
482 {
483  // Avoid:
484  // policy/feerate.cpp:28:34: runtime error: signed integer overflow: 34873208148477500 * 1000 cannot be represented in type 'long'
485  //
486  // Reproduce using CFeeRate(348732081484775, 10).GetFeePerK()
487  const CAmount fee = std::min<CAmount>(ConsumeMoney(fuzzed_data_provider), std::numeric_limits<CAmount>::max() / static_cast<CAmount>(100000));
488  assert(MoneyRange(fee));
489  const int64_t time = fuzzed_data_provider.ConsumeIntegral<int64_t>();
490  const unsigned int entry_height = fuzzed_data_provider.ConsumeIntegral<unsigned int>();
491  const bool spends_coinbase = fuzzed_data_provider.ConsumeBool();
492  const unsigned int sig_op_cost = fuzzed_data_provider.ConsumeIntegralInRange<unsigned int>(0, MAX_BLOCK_SIGOPS_COST);
493  return CTxMemPoolEntry{MakeTransactionRef(tx), fee, time, entry_height, spends_coinbase, sig_op_cost, {}};
494 }
495 
496 bool ContainsSpentInput(const CTransaction& tx, const CCoinsViewCache& inputs) noexcept
497 {
498  for (const CTxIn& tx_in : tx.vin) {
499  const Coin& coin = inputs.AccessCoin(tx_in.prevout);
500  if (coin.IsSpent()) {
501  return true;
502  }
503  }
504  return false;
505 }
506 
507 CNetAddr ConsumeNetAddr(FuzzedDataProvider& fuzzed_data_provider) noexcept
508 {
509  const Network network = fuzzed_data_provider.PickValueInArray({Network::NET_IPV4, Network::NET_IPV6, Network::NET_INTERNAL, Network::NET_ONION});
510  CNetAddr net_addr;
511  if (network == Network::NET_IPV4) {
512  in_addr v4_addr = {};
513  v4_addr.s_addr = fuzzed_data_provider.ConsumeIntegral<uint32_t>();
514  net_addr = CNetAddr{v4_addr};
515  } else if (network == Network::NET_IPV6) {
516  if (fuzzed_data_provider.remaining_bytes() >= 16) {
517  in6_addr v6_addr = {};
518  memcpy(v6_addr.s6_addr, fuzzed_data_provider.ConsumeBytes<uint8_t>(16).data(), 16);
519  net_addr = CNetAddr{v6_addr, fuzzed_data_provider.ConsumeIntegral<uint32_t>()};
520  }
521  } else if (network == Network::NET_INTERNAL) {
522  net_addr.SetInternal(fuzzed_data_provider.ConsumeBytesAsString(32));
523  } else if (network == Network::NET_ONION) {
524  net_addr.SetSpecial(fuzzed_data_provider.ConsumeBytesAsString(32));
525  }
526  return net_addr;
527 }
528 
529 CAddress ConsumeAddress(FuzzedDataProvider& fuzzed_data_provider) noexcept
530 {
531  return {ConsumeService(fuzzed_data_provider), ConsumeWeakEnum(fuzzed_data_provider, ALL_SERVICE_FLAGS), NodeSeconds{std::chrono::seconds{fuzzed_data_provider.ConsumeIntegral<uint32_t>()}}};
532 }
533 
535 {
538  return nullptr;
539  }
540  std::string mode;
541  CallOneOf(
543  [&] {
544  mode = "r";
545  },
546  [&] {
547  mode = "r+";
548  },
549  [&] {
550  mode = "w";
551  },
552  [&] {
553  mode = "w+";
554  },
555  [&] {
556  mode = "a";
557  },
558  [&] {
559  mode = "a+";
560  });
561 #if defined _GNU_SOURCE && !defined __ANDROID__
562  const cookie_io_functions_t io_hooks = {
567  };
568  return fopencookie(this, mode.c_str(), io_hooks);
569 #else
570  (void)mode;
571  return nullptr;
572 #endif
573 }
574 
575 ssize_t FuzzedFileProvider::read(void* cookie, char* buf, size_t size)
576 {
577  FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
579  if (buf == nullptr || size == 0 || fuzzed_file->m_fuzzed_data_provider.ConsumeBool()) {
580  return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
581  }
582  const std::vector<uint8_t> random_bytes = fuzzed_file->m_fuzzed_data_provider.ConsumeBytes<uint8_t>(size);
583  if (random_bytes.empty()) {
584  return 0;
585  }
586  std::memcpy(buf, random_bytes.data(), random_bytes.size());
587  if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)random_bytes.size())) {
588  return fuzzed_file->m_fuzzed_data_provider.ConsumeBool() ? 0 : -1;
589  }
590  fuzzed_file->m_offset += random_bytes.size();
591  return random_bytes.size();
592 }
593 
594 ssize_t FuzzedFileProvider::write(void* cookie, const char* buf, size_t size)
595 {
596  FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
598  const ssize_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<ssize_t>(0, size);
599  if (AdditionOverflow(fuzzed_file->m_offset, (int64_t)n)) {
600  return 0;
601  }
602  fuzzed_file->m_offset += n;
603  return n;
604 }
605 
606 int FuzzedFileProvider::seek(void* cookie, int64_t* offset, int whence)
607 {
608  assert(whence == SEEK_SET || whence == SEEK_CUR || whence == SEEK_END);
609  FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
611  int64_t new_offset = 0;
612  if (whence == SEEK_SET) {
613  new_offset = *offset;
614  } else if (whence == SEEK_CUR) {
615  if (AdditionOverflow(fuzzed_file->m_offset, *offset)) {
616  return -1;
617  }
618  new_offset = fuzzed_file->m_offset + *offset;
619  } else if (whence == SEEK_END) {
620  const int64_t n = fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int64_t>(0, 4096);
621  if (AdditionOverflow(n, *offset)) {
622  return -1;
623  }
624  new_offset = n + *offset;
625  }
626  if (new_offset < 0) {
627  return -1;
628  }
629  fuzzed_file->m_offset = new_offset;
630  *offset = new_offset;
631  return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
632 }
633 
634 int FuzzedFileProvider::close(void* cookie)
635 {
636  FuzzedFileProvider* fuzzed_file = (FuzzedFileProvider*)cookie;
638  return fuzzed_file->m_fuzzed_data_provider.ConsumeIntegralInRange<int>(-1, 0);
639 }
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:681
bool IsSpent() const
Either this coin never existed (see e.g.
Definition: coins.h:79
std::vector< uint8_t > ConsumeFixedLengthByteVector(FuzzedDataProvider &fuzzed_data_provider, const size_t length) noexcept
Returns a byte vector of specified size regardless of the number of remaining bytes available from th...
Definition: util.h:268
int ret
static constexpr unsigned int SIZE
secp256k1:
Definition: pubkey.h:39
bool AdditionOverflow(const T i, const T j) noexcept
Definition: overflow.h:13
assert(!tx.IsCoinBase())
FuzzedSock & operator=(Sock &&other) override
Move assignment operator, grab the socket from another object and close ours (if set).
Definition: util.cpp:33
A set of addresses that represent the hash of a string or FQDN.
Definition: netaddress.h:65
static int seek(void *cookie, int64_t *offset, int whence)
Definition: util.cpp:606
A UTXO entry.
Definition: coins.h:30
int64_t m_offset
Definition: util.h:336
WeakEnumType ConsumeWeakEnum(FuzzedDataProvider &fuzzed_data_provider, const WeakEnumType(&all_types)[size]) noexcept
Definition: util.h:164
CTxMemPoolEntry ConsumeTxMemPoolEntry(FuzzedDataProvider &fuzzed_data_provider, const CTransaction &tx) noexcept
Definition: util.cpp:481
CService ConsumeService(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.h:285
IPv4.
Definition: netaddress.h:49
std::vector< CTxIn > vin
Definition: transaction.h:374
static const CScript P2WSH_OP_TRUE
Definition: script.h:12
CScriptWitness scriptWitness
Only serialized through CTransaction.
Definition: transaction.h:79
static const uint32_t SEQUENCE_FINAL
Setting nSequence to this value for every input in a transaction disables nLockTime/IsFinalTx().
Definition: transaction.h:88
opcodetype ConsumeOpcodeType(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.h:171
bool MoneyRange(const CAmount &nValue)
Definition: amount.h:27
CScriptWitness ConsumeScriptWitness(FuzzedDataProvider &fuzzed_data_provider, const size_t max_stack_elem_size) noexcept
Definition: util.cpp:356
CScript ConsumeScript(FuzzedDataProvider &fuzzed_data_provider, const bool maybe_p2wsh) noexcept
Definition: util.cpp:366
SOCKET m_socket
Contained socket.
Definition: sock.h:261
int SetSockOpt(int level, int opt_name, const void *opt_val, socklen_t opt_len) const override
setsockopt(2) wrapper.
Definition: util.cpp:230
FuzzedDataProvider & m_fuzzed_data_provider
Definition: util.h:335
std::vector< std::vector< unsigned char > > stack
Definition: script.h:566
bool SetSpecial(const std::string &addr)
Parse a Tor or I2P address and set this object to it.
Definition: netaddress.cpp:208
bool IsConnected(std::string &errmsg) const override
Check if still connected.
Definition: util.cpp:283
Definition: script.h:72
unsigned int version
Definition: standard.h:119
ssize_t Recv(void *buf, size_t len, int flags) const override
recv(2) wrapper.
Definition: util.cpp:71
#define INVALID_SOCKET
Definition: compat.h:54
std::optional< uint8_t > m_peek_data
Data to return when MSG_PEEK is used as a Recv() flag.
Definition: util.h:49
static const int64_t MAX_BLOCK_SIGOPS_COST
The maximum allowed number of signature check operations in a block (network rule) ...
Definition: consensus.h:17
unsigned char * begin()
Definition: uint256.h:61
int64_t ParseISO8601DateTime(const std::string &str)
Definition: time.cpp:145
CTxMemPoolEntry stores data about the corresponding transaction, as well as data about all in-mempool...
Definition: txmempool.h:88
ssize_t Send(const void *data, size_t len, int flags) const override
send(2) wrapper.
Definition: util.cpp:39
static int close(void *cookie)
Definition: util.cpp:634
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
Definition: time.h:25
constexpr ServiceFlags ALL_SERVICE_FLAGS[]
Definition: net.h:56
CAddress ConsumeAddress(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.cpp:529
static constexpr unsigned int COMPRESSED_SIZE
Definition: pubkey.h:40
static constexpr uint32_t MAX_BIP125_RBF_SEQUENCE
Definition: rbf.h:12
bool Wait(std::chrono::milliseconds timeout, Event requested, Event *occurred=nullptr) const override
Wait for readiness for input (recv) or output (send).
Definition: util.cpp:257
std::unordered_map< std::shared_ptr< const Sock >, Events, HashSharedPtrSock, EqualSharedPtrSock > EventsPerSock
On which socket to wait for what events in WaitMany().
Definition: sock.h:206
An input of a transaction.
Definition: transaction.h:73
CTxDestination subtype to encode any future Witness version.
Definition: standard.h:117
const char * name
Definition: rest.cpp:46
static const std::vector< uint8_t > WITNESS_STACK_ELEM_OP_TRUE
Definition: script.h:11
CNetAddr ConsumeNetAddr(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.cpp:507
A CService with information about it as peer.
Definition: protocol.h:354
bool ContainsSpentInput(const CTransaction &tx, const CCoinsViewCache &inputs) noexcept
Definition: util.cpp:496
std::vector< uint8_t > ConsumeRandomLengthByteVector(FuzzedDataProvider &fuzzed_data_provider, const std::optional< size_t > &max_length=std::nullopt) noexcept
Definition: util.h:110
Network
A network type.
Definition: netaddress.h:44
std::variant< CNoDestination, PKHash, ScriptHash, WitnessV0ScriptHash, WitnessV0KeyHash, WitnessV1Taproot, WitnessUnknown > CTxDestination
A txout script template with a specific destination.
Definition: standard.h:149
~FuzzedSock() override
Definition: util.cpp:24
int GetSockOpt(int level, int opt_name, void *opt_val, socklen_t *opt_len) const override
getsockopt(2) wrapper.
Definition: util.cpp:211
std::unique_ptr< Sock > Accept(sockaddr *addr, socklen_t *addr_len) const override
accept(2) wrapper.
Definition: util.cpp:197
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:34
size_t ConsumeData(void *destination, size_t num_bytes)
uint8_t Event
Definition: sock.h:136
std::vector< CTxOut > vout
Definition: transaction.h:375
int Connect(const sockaddr *, socklen_t) const override
connect(2) wrapper.
Definition: util.cpp:136
FILE * open()
Definition: util.cpp:534
unsigned int SOCKET
Definition: compat.h:44
static CTransactionRef MakeTransactionRef(Tx &&txIn)
Definition: transaction.h:415
FuzzedSock(FuzzedDataProvider &fuzzed_data_provider)
Definition: util.cpp:18
Definition: init.h:25
CScript scriptSig
Definition: transaction.h:77
std::vector< T > ConsumeBytes(size_t num_bytes)
int flags
Definition: bitcoin-tx.cpp:525
std::vector< unsigned char > ToByteVector(const T &in)
Definition: script.h:63
Network address.
Definition: netaddress.h:117
FuzzedDataProvider & m_fuzzed_data_provider
Definition: util.h:42
256-bit opaque blob.
Definition: uint256.h:119
static ssize_t write(void *cookie, const char *buf, size_t size)
Definition: util.cpp:594
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
Definition: util.cpp:307
static ssize_t read(void *cookie, char *buf, size_t size)
Definition: util.cpp:575
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:410
uint32_t nSequence
Definition: transaction.h:78
static const int MIN_PEER_PROTO_VERSION
disconnect from peers older than this proto version
Definition: version.h:18
bool WaitMany(std::chrono::milliseconds timeout, EventsPerSock &events_per_sock) const override
Same as Wait(), but wait on many sockets within the same timeout.
Definition: util.cpp:274
CScriptNum ConsumeScriptNum(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.h:188
CAmount ConsumeMoney(FuzzedDataProvider &fuzzed_data_provider, const std::optional< CAmount > &max) noexcept
Definition: util.cpp:302
IPv6.
Definition: netaddress.h:52
void FillNode(FuzzedDataProvider &fuzzed_data_provider, ConnmanTestMsg &connman, CNode &node) noexcept
Definition: util.cpp:292
TOR (v2 or v3)
Definition: netaddress.h:55
void SetFuzzedErrNo(FuzzedDataProvider &fuzzed_data_provider, const std::array< T, size > &errnos)
Sets errno to a value selected from the given std::array errnos.
Definition: util.h:249
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:26
A mutable version of CTransaction.
Definition: transaction.h:372
RAII helper class that manages a socket.
Definition: sock.h:27
static const uint32_t MAX_SEQUENCE_NONFINAL
This is the maximum sequence number that enables both nLockTime and OP_CHECKLOCKTIMEVERIFY (BIP 65)...
Definition: transaction.h:94
size_t CallOneOf(FuzzedDataProvider &fuzzed_data_provider, Callables... callables)
Definition: util.h:89
CMutableTransaction ConsumeTransaction(FuzzedDataProvider &fuzzed_data_provider, const std::optional< std::vector< uint256 >> &prevout_txids, const int max_num_in, const int max_num_out) noexcept
Definition: util.cpp:315
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
Definition: util.h:101
int GetSockName(sockaddr *name, socklen_t *name_len) const override
getsockname(2) wrapper.
Definition: util.cpp:243
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:287
static const int32_t CURRENT_VERSION
Definition: transaction.h:291
Information about a peer.
Definition: net.h:347
uint160 ConsumeUInt160(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.h:193
T ConsumeIntegralInRange(T min, T max)
CCoinsView that adds a memory cache for transactions to another CCoinsView.
Definition: coins.h:212
bool SetInternal(const std::string &name)
Create an "internal" address that represents a name or FQDN.
Definition: netaddress.cpp:169
uint256 ConsumeUInt256(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.h:202
A hasher class for SHA-256.
Definition: sha256.h:13
COutPoint prevout
Definition: transaction.h:76
int Bind(const sockaddr *, socklen_t) const override
bind(2) wrapper.
Definition: util.cpp:158
CTxDestination ConsumeTxDestination(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.cpp:443
int Listen(int backlog) const override
listen(2) wrapper.
Definition: util.cpp:178
#define Assert(val)
Identity function.
Definition: check.h:74
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
Definition: util.cpp:432
static constexpr CAmount COIN
The amount of satoshis in one BTC.
Definition: amount.h:15