From 730ba66f010cbc6ba2ef2d176a994fbfb0d0234c Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 1 Mar 2014 10:11:08 +0000 Subject: [PATCH] Hardening against bad RLP. --- libethereum/BlockInfo.cpp | 2 +- libethereum/Common.h | 2 +- libethereum/Exceptions.h | 4 ++++ libethereum/RLP.cpp | 16 ++++++++++++++++ libethereum/RLP.h | 3 +-- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libethereum/BlockInfo.cpp b/libethereum/BlockInfo.cpp index cd2323cfa..9e9ca48c8 100644 --- a/libethereum/BlockInfo.cpp +++ b/libethereum/BlockInfo.cpp @@ -101,7 +101,7 @@ void BlockInfo::populateFromHeader(RLP const& _header) extraData = _header[field = 7].toBytes(); nonce = _header[field = 8].toHash(); } - catch (RLP::BadCast) + catch (RLPException const&) { throw InvalidBlockHeaderFormat(field, _header[field].data()); } diff --git a/libethereum/Common.h b/libethereum/Common.h index a92b4034c..608ebc7e5 100644 --- a/libethereum/Common.h +++ b/libethereum/Common.h @@ -24,7 +24,7 @@ #pragma once // define version -#define ETH_VERSION 0.3.8 +#define ETH_VERSION 0.3.9 // way to many uint to size_t warnings in 32 bit build #ifdef _M_IX86 diff --git a/libethereum/Exceptions.h b/libethereum/Exceptions.h index 7bee4699f..2857102c9 100644 --- a/libethereum/Exceptions.h +++ b/libethereum/Exceptions.h @@ -16,6 +16,10 @@ public: class BadHexCharacter: public Exception {}; class NotEnoughCash: public Exception {}; +class RLPException: public Exception {}; +class BadCast: public RLPException {}; +class BadRLP: public RLPException {}; + class VMException: public Exception {}; class StepsDone: public VMException {}; class BreakPointHit: public VMException {}; diff --git a/libethereum/RLP.cpp b/libethereum/RLP.cpp index d9842b447..e8647e8de 100644 --- a/libethereum/RLP.cpp +++ b/libethereum/RLP.cpp @@ -102,9 +102,17 @@ bool RLP::isInt() const else if (n == c_rlpDataImmLenStart) return true; else if (n <= c_rlpDataIndLenZero) + { + if (m_data.size() <= 1) + throw BadRLP(); return m_data[1] != 0; + } else if (n < c_rlpListStart) + { + if ((int)m_data.size() <= 1 + n - c_rlpDataIndLenZero) + throw BadRLP(); return m_data[1 + n - c_rlpDataIndLenZero] != 0; + } else return false; return false; @@ -121,13 +129,21 @@ eth::uint RLP::length() const else if (n <= c_rlpDataIndLenZero) return n - c_rlpDataImmLenStart; else if (n < c_rlpListStart) + { + if ((int)m_data.size() <= n - c_rlpDataIndLenZero) + throw BadRLP(); for (int i = 0; i < n - c_rlpDataIndLenZero; ++i) ret = (ret << 8) | m_data[i + 1]; + } else if (n <= c_rlpListIndLenZero) return n - c_rlpListStart; else + { + if ((int)m_data.size() <= n - c_rlpListIndLenZero) + throw BadRLP(); for (int i = 0; i < n - c_rlpListIndLenZero; ++i) ret = (ret << 8) | m_data[i + 1]; + } return ret; } diff --git a/libethereum/RLP.h b/libethereum/RLP.h index 8c0248f61..9a4448524 100644 --- a/libethereum/RLP.h +++ b/libethereum/RLP.h @@ -30,6 +30,7 @@ #include #include "vector_ref.h" #include "Common.h" +#include "Exceptions.h" namespace eth { @@ -60,8 +61,6 @@ static const byte c_rlpListIndLenZero = c_rlpListStart + c_rlpListImmLenCount - class RLP { public: - class BadCast: public std::exception {}; - /// Construct a null node. RLP() {}