aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcoFalke <falke.marco@gmail.com>2022-01-28 15:29:44 +0100
committerMarcoFalke <falke.marco@gmail.com>2022-02-09 17:20:22 +0100
commitfab02f799194c75af7def3a2ab45c443b75de230 (patch)
tree95fa221d48e3e8b917f14a8c09732724bb9b5941
parent5e8e0b3d7f6055e326bda61e60712b530e8920f0 (diff)
downloadbitcoin-fab02f799194c75af7def3a2ab45c443b75de230.tar.xz
streams: Fix read-past-the-end and integer overflows
-rw-r--r--src/streams.h25
-rw-r--r--src/util/overflow.h1
2 files changed, 12 insertions, 14 deletions
diff --git a/src/streams.h b/src/streams.h
index cf8b4eb96f..e485c09457 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -9,6 +9,7 @@
#include <serialize.h>
#include <span.h>
#include <support/allocators/zeroafterfree.h>
+#include <util/overflow.h>
#include <algorithm>
#include <assert.h>
@@ -281,36 +282,32 @@ public:
if (dst.size() == 0) return;
// Read from the beginning of the buffer
- unsigned int nReadPosNext = nReadPos + dst.size();
- if (nReadPosNext > vch.size()) {
+ auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, dst.size())};
+ if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
throw std::ios_base::failure("CDataStream::read(): end of data");
}
memcpy(dst.data(), &vch[nReadPos], dst.size());
- if (nReadPosNext == vch.size())
- {
+ if (next_read_pos.value() == vch.size()) {
nReadPos = 0;
vch.clear();
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
- if (nSize < 0) {
- throw std::ios_base::failure("CDataStream::ignore(): nSize negative");
+ auto next_read_pos{CheckedAdd<uint32_t>(nReadPos, num_ignore)};
+ if (!next_read_pos.has_value() || next_read_pos.value() > vch.size()) {
+ throw std::ios_base::failure("CDataStream::ignore(): end of data");
}
- unsigned int nReadPosNext = nReadPos + nSize;
- if (nReadPosNext >= vch.size())
- {
- if (nReadPosNext > vch.size())
- throw std::ios_base::failure("CDataStream::ignore(): end of data");
+ if (next_read_pos.value() == vch.size()) {
nReadPos = 0;
vch.clear();
return;
}
- nReadPos = nReadPosNext;
+ nReadPos = next_read_pos.value();
}
void write(Span<const value_type> src)
diff --git a/src/util/overflow.h b/src/util/overflow.h
index 5982af8d04..c70a8b663e 100644
--- a/src/util/overflow.h
+++ b/src/util/overflow.h
@@ -6,6 +6,7 @@
#define BITCOIN_UTIL_OVERFLOW_H
#include <limits>
+#include <optional>
#include <type_traits>
template <class T>