Browse Source

Merge pull request #4655

216e9a4 Add a way to limit deserialized string lengths (Pieter Wuille)
0.10
Wladimir J. van der Laan 11 years ago
parent
commit
21e7a5690f
No known key found for this signature in database
GPG Key ID: 74810B012346C9A6
  1. 6
      src/alert.h
  2. 9
      src/main.cpp
  3. 39
      src/serialize.h
  4. 6
      src/wallet.h

6
src/alert.h

@ -60,9 +60,9 @@ public:
READWRITE(setSubVer); READWRITE(setSubVer);
READWRITE(nPriority); READWRITE(nPriority);
READWRITE(strComment); READWRITE(LIMITED_STRING(strComment, 65536));
READWRITE(strStatusBar); READWRITE(LIMITED_STRING(strStatusBar, 256));
READWRITE(strReserved); READWRITE(LIMITED_STRING(strReserved, 256));
) )
void SetNull(); void SetNull();

9
src/main.cpp

@ -3568,7 +3568,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (!vRecv.empty()) if (!vRecv.empty())
vRecv >> addrFrom >> nNonce; vRecv >> addrFrom >> nNonce;
if (!vRecv.empty()) { if (!vRecv.empty()) {
vRecv >> pfrom->strSubVer; vRecv >> LIMITED_STRING(pfrom->strSubVer, 256);
pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer);
} }
if (!vRecv.empty()) if (!vRecv.empty())
@ -4192,7 +4192,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
if (fDebug) if (fDebug)
{ {
string strMsg; unsigned char ccode; string strReason; string strMsg; unsigned char ccode; string strReason;
vRecv >> strMsg >> ccode >> strReason; vRecv >> LIMITED_STRING(strMsg, CMessageHeader::COMMAND_SIZE) >> ccode >> LIMITED_STRING(strReason, 111);
ostringstream ss; ostringstream ss;
ss << strMsg << " code " << itostr(ccode) << ": " << strReason; ss << strMsg << " code " << itostr(ccode) << ": " << strReason;
@ -4203,10 +4203,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv,
vRecv >> hash; vRecv >> hash;
ss << ": hash " << hash.ToString(); ss << ": hash " << hash.ToString();
} }
// Truncate to reasonable length and sanitize before printing: LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
string s = ss.str();
if (s.size() > 111) s.erase(111, string::npos);
LogPrint("net", "Reject %s\n", SanitizeString(s));
} }
} }

39
src/serialize.h

@ -334,8 +334,9 @@ I ReadVarInt(Stream& is)
} }
} }
#define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj))) #define FLATDATA(obj) REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
#define VARINT(obj) REF(WrapVarInt(REF(obj))) #define VARINT(obj) REF(WrapVarInt(REF(obj)))
#define LIMITED_STRING(obj,n) REF(LimitedString< n >(REF(obj)))
/** Wrapper for serializing arrays and POD. /** Wrapper for serializing arrays and POD.
*/ */
@ -398,6 +399,40 @@ public:
} }
}; };
template<size_t Limit>
class LimitedString
{
protected:
std::string& string;
public:
LimitedString(std::string& string) : string(string) {}
template<typename Stream>
void Unserialize(Stream& s, int, int=0)
{
size_t size = ReadCompactSize(s);
if (size > Limit) {
throw std::ios_base::failure("String length limit exceeded");
}
string.resize(size);
if (size != 0)
s.read((char*)&string[0], size);
}
template<typename Stream>
void Serialize(Stream& s, int, int=0) const
{
WriteCompactSize(s, string.size());
if (!string.empty())
s.write((char*)&string[0], string.size());
}
unsigned int GetSerializeSize(int, int=0) const
{
return GetSizeOfCompactSize(string.size()) + string.size();
}
};
template<typename I> template<typename I>
CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); } CVarInt<I> WrapVarInt(I& n) { return CVarInt<I>(n); }

6
src/wallet.h

@ -858,7 +858,7 @@ public:
READWRITE(vchPrivKey); READWRITE(vchPrivKey);
READWRITE(nTimeCreated); READWRITE(nTimeCreated);
READWRITE(nTimeExpires); READWRITE(nTimeExpires);
READWRITE(strComment); READWRITE(LIMITED_STRING(strComment, 65536));
) )
}; };
@ -933,7 +933,7 @@ public:
// Note: strAccount is serialized as part of the key, not here. // Note: strAccount is serialized as part of the key, not here.
READWRITE(nCreditDebit); READWRITE(nCreditDebit);
READWRITE(nTime); READWRITE(nTime);
READWRITE(strOtherAccount); READWRITE(LIMITED_STRING(strOtherAccount, 65536));
if (!fRead) if (!fRead)
{ {
@ -949,7 +949,7 @@ public:
} }
} }
READWRITE(strComment); READWRITE(LIMITED_STRING(strComment, 65536));
size_t nSepPos = strComment.find("\0", 0, 1); size_t nSepPos = strComment.find("\0", 0, 1);
if (fRead) if (fRead)

Loading…
Cancel
Save