From fab02f799194c75af7def3a2ab45c443b75de230 Mon Sep 17 00:00:00 2001 From: MarcoFalke Date: Fri, 28 Jan 2022 15:29:44 +0100 Subject: streams: Fix read-past-the-end and integer overflows --- src/streams.h | 25 +++++++++++-------------- src/util/overflow.h | 1 + 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 #include #include +#include #include #include @@ -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(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(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 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 +#include #include template -- cgit v1.2.3