Eliminate potential undefined behavior (RIPD-1685):

Under certain conditions, we could call `memcpy` or `memcmp` with a null
source pointer. Even when specifying 0 as the amount of data to copy this
could result in undefined behavior under the C and C++ standards.

Acknowledgements:
Ripple thanks Guido Vranken for responsibly disclosing these issues.

Bug Bounties and Responsible Disclosures:
We welcome reviews of the rippled code and urge researchers to responsibly
disclose any issues that they may find. For more on Ripple's Bug Bounty
program, please visit: https://ripple.com/bug-bounty
This commit is contained in:
Nik Bougalis
2018-11-07 11:55:24 -08:00
parent 753600a2a0
commit c71eb45240
3 changed files with 13 additions and 39 deletions

View File

@@ -221,9 +221,13 @@ public:
inline bool operator==(Buffer const& lhs, Buffer const& rhs) noexcept
{
if (lhs.size () != rhs.size ())
if (lhs.size() != rhs.size())
return false;
return !std::memcmp (lhs.data (), rhs.data (), lhs.size ());
if (lhs.size() == 0)
return true;
return std::memcmp(lhs.data(), rhs.data(), lhs.size()) == 0;
}
inline bool operator!=(Buffer const& lhs, Buffer const& rhs) noexcept

View File

@@ -23,6 +23,7 @@
#include <ripple/basics/Buffer.h>
#include <ripple/basics/Slice.h>
#include <ripple/protocol/STBase.h>
#include <cassert>
#include <cstring>
#include <memory>
@@ -42,18 +43,6 @@ public:
{
}
/** Construct with size and initializer.
Init will be called as:
void(void* data, std::size_t size)
*/
template <class Init>
STBlob (SField const& f, std::size_t size,
Init&& init)
: STBase(f), value_ (size)
{
init(value_.data(), value_.size());
}
STBlob (SField const& f,
void const* data, std::size_t size)
: STBase(f), value_ (data, size)
@@ -115,12 +104,6 @@ public:
s.addVL (value_.data (), value_.size ());
}
Buffer const&
peekValue () const
{
return value_;
}
STBlob&
operator= (Slice const& slice)
{
@@ -141,25 +124,12 @@ public:
return *this;
}
Buffer&
peekValue ()
{
return value_;
}
void
setValue (Buffer&& b)
{
value_ = std::move (b);
}
void
setValue (void const* data, std::size_t size)
{
value_.alloc (size);
std::memcpy(value_.data(), data, size);
}
bool
isEquivalent (const STBase& t) const override;

View File

@@ -49,14 +49,14 @@ public:
mData.reserve (n);
}
Serializer (void const* data,
std::size_t size)
Serializer (void const* data, std::size_t size)
{
assert(!data == !size);
mData.resize(size);
std::memcpy(mData.data(),
reinterpret_cast<
unsigned char const*>(
data), size);
if (size)
std::memcpy(mData.data(), data, size);
}
Slice slice() const noexcept