0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-06 14:19:59 -05:00

streams: Fix read-past-the-end and integer overflows

This commit is contained in:
MarcoFalke 2022-01-28 15:29:44 +01:00
parent 5e8e0b3d7f
commit fab02f7991
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
2 changed files with 12 additions and 14 deletions

View file

@ -9,6 +9,7 @@
#include <serialize.h> #include <serialize.h>
#include <span.h> #include <span.h>
#include <support/allocators/zeroafterfree.h> #include <support/allocators/zeroafterfree.h>
#include <util/overflow.h>
#include <algorithm> #include <algorithm>
#include <assert.h> #include <assert.h>
@ -281,36 +282,32 @@ public:
if (dst.size() == 0) return; if (dst.size() == 0) return;
// Read from the beginning of the buffer // Read from the beginning of the buffer
unsigned int nReadPosNext = nReadPos + dst.size(); auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, dst.size())};
if (nReadPosNext > vch.size()) { if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
throw std::ios_base::failure("CDataStream::read(): end of data"); throw std::ios_base::failure("CDataStream::read(): end of data");
} }
memcpy(dst.data(), &vch[nReadPos], dst.size()); memcpy(dst.data(), &vch[nReadPos], dst.size());
if (nReadPosNext == vch.size()) if (next_read_pos.value() == vch.size()) {
{
nReadPos = 0; nReadPos = 0;
vch.clear(); vch.clear();
return; return;
} }
nReadPos = nReadPosNext; nReadPos = next_read_pos.value();
} }
void ignore(int nSize) void ignore(size_t num_ignore)
{ {
// Ignore from the beginning of the buffer // Ignore from the beginning of the buffer
if (nSize < 0) { auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, num_ignore)};
throw std::ios_base::failure("CDataStream::ignore(): nSize negative"); if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
}
unsigned int nReadPosNext = nReadPos + nSize;
if (nReadPosNext >= vch.size())
{
if (nReadPosNext > vch.size())
throw std::ios_base::failure("CDataStream::ignore(): end of data"); throw std::ios_base::failure("CDataStream::ignore(): end of data");
}
if (next_read_pos.value() == vch.size()) {
nReadPos = 0; nReadPos = 0;
vch.clear(); vch.clear();
return; return;
} }
nReadPos = nReadPosNext; nReadPos = next_read_pos.value();
} }
void write(Span<const value_type> src) void write(Span<const value_type> src)

View file

@ -6,6 +6,7 @@
#define BITCOIN_UTIL_OVERFLOW_H #define BITCOIN_UTIL_OVERFLOW_H
#include <limits> #include <limits>
#include <optional>
#include <type_traits> #include <type_traits>
template <class T> template <class T>