From 886be97af5d4aba338b23a7b20b8560be8156231 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 12 Oct 2020 15:35:08 -0700 Subject: [PATCH] Ignore incorrectly-serialized banlist.dat entries --- src/banman.cpp | 2 +- src/netaddress.cpp | 11 +++++++++++ src/netaddress.h | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/banman.cpp b/src/banman.cpp index 8752185a60df2..995fef3d0768e 100644 --- a/src/banman.cpp +++ b/src/banman.cpp @@ -184,7 +184,7 @@ void BanMan::SweepBanned() while (it != m_banned.end()) { CSubNet sub_net = (*it).first; CBanEntry ban_entry = (*it).second; - if (now > ban_entry.nBanUntil) { + if (!sub_net.IsValid() || now > ban_entry.nBanUntil) { m_banned.erase(it++); m_is_dirty = true; notify_ui = true; diff --git a/src/netaddress.cpp b/src/netaddress.cpp index 147c775e617c0..4e100ff9ca97d 100644 --- a/src/netaddress.cpp +++ b/src/netaddress.cpp @@ -1109,6 +1109,17 @@ bool CSubNet::IsValid() const return valid; } +bool CSubNet::SanityCheck() const +{ + if (!(network.IsIPv4() || network.IsIPv6())) return false; + + for (size_t x = 0; x < network.m_addr.size(); ++x) { + if (network.m_addr[x] & ~netmask[x]) return false; + } + + return true; +} + bool operator==(const CSubNet& a, const CSubNet& b) { return a.valid == b.valid && a.network == b.network && !memcmp(a.netmask, b.netmask, 16); diff --git a/src/netaddress.h b/src/netaddress.h index aea0875511927..803b00481e004 100644 --- a/src/netaddress.h +++ b/src/netaddress.h @@ -451,6 +451,8 @@ class CSubNet /// Is this value valid? (only used to signal parse errors) bool valid; + bool SanityCheck() const; + public: CSubNet(); CSubNet(const CNetAddr& addr, uint8_t mask); @@ -482,6 +484,8 @@ class CSubNet READWRITE(obj.netmask); } READWRITE(obj.valid); + // Mark invalid if the result doesn't pass sanity checking. + SER_READ(obj, if (obj.valid) obj.valid = obj.SanityCheck()); } };