From 1878f3a7594f3df3f75cfbb5e9eaca06f3afab7d Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 13 Apr 2017 02:33:04 -0700 Subject: [PATCH 1/2] Fix some empty vector references streams.h has some methods that can be tricked into dereferencing null pointers or end() iterators. Fix this. --- src/streams.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/streams.h b/src/streams.h index 2fb6c7e01..624c0ce66 100644 --- a/src/streams.h +++ b/src/streams.h @@ -133,7 +133,8 @@ public: void insert(iterator it, std::vector::const_iterator first, std::vector::const_iterator last) { - assert(last - first >= 0); + if (last == first) return; + assert(last - first > 0); if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room @@ -147,7 +148,8 @@ public: #if !defined(_MSC_VER) || _MSC_VER >= 1300 void insert(iterator it, const char* first, const char* last) { - assert(last - first >= 0); + if (last == first) return; + assert(last - first > 0); if (it == vch.begin() + nReadPos && (unsigned int)(last - first) <= nReadPos) { // special case for inserting at the front when there's room @@ -226,6 +228,8 @@ public: void read(char* pch, size_t nSize) { + if (nSize == 0) return; + // Read from the beginning of the buffer unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) From 54a872f0fac2d99ccfbad5e298c08ba8ccbb7931 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 30 Apr 2018 16:41:02 -0700 Subject: [PATCH 2/2] Fix undefined behaviour, calling memcpy with NULL pointer. Identified as part of audit: Least Authority, Issue D. --- src/streams.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/streams.h b/src/streams.h index 624c0ce66..1623507d8 100644 --- a/src/streams.h +++ b/src/streams.h @@ -230,6 +230,10 @@ public: { if (nSize == 0) return; + if (pch == nullptr) { + throw std::ios_base::failure("CBaseDataStream::read(): cannot read from null pointer"); + } + // Read from the beginning of the buffer unsigned int nReadPosNext = nReadPos + nSize; if (nReadPosNext >= vch.size()) @@ -519,6 +523,12 @@ public: // read a number of bytes void read(char *pch, size_t nSize) { + if (nSize == 0) return; + + if (pch == nullptr) { + throw std::ios_base::failure("CBufferedFile::read(): cannot read from null pointer"); + } + if (nSize + nReadPos > nReadLimit) throw std::ios_base::failure("Read attempted past buffer limit"); if (nSize + nRewind > vchBuf.size())