changeset 3394:046d274192e6 draft

Alert system DoS prevention This fixes two alert system vulnerabilities found by Sergio Lerner; you could send peers unlimited numbers of invalid alert message to try to either fill up their debug.log with messages and/or keep their CPU busy checking signatures. Fixed by disconnecting/banning peers if they send 10 or more bad (invalid/expired/cancelled) alerts.
author Gavin Andresen <gavinandresen@gmail.com>
date Sun, 26 Aug 2012 17:08:18 -0400
parents 38aad20ac721
children e0dd4cb42a5b
files src/main.cpp src/main.h
diffstat 2 files changed, 20 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2997,14 +2997,27 @@
         CAlert alert;
         vRecv >> alert;
 
-        if (alert.ProcessAlert())
+        uint256 alertHash = alert.GetHash();
+        if (pfrom->setKnown.count(alertHash) == 0)
         {
-            // Relay
-            pfrom->setKnown.insert(alert.GetHash());
+            if (alert.ProcessAlert())
             {
-                LOCK(cs_vNodes);
-                BOOST_FOREACH(CNode* pnode, vNodes)
-                    alert.RelayTo(pnode);
+                // Relay
+                pfrom->setKnown.insert(alertHash);
+                {
+                    LOCK(cs_vNodes);
+                    BOOST_FOREACH(CNode* pnode, vNodes)
+                        alert.RelayTo(pnode);
+                }
+            }
+            else {
+                // Small DoS penalty so peers that send us lots of
+                // duplicate/expired/invalid-signature/whatever alerts
+                // eventually get banned.
+                // This isn't a Misbehaving(100) (immediate ban) because the
+                // peer might be an older or different implementation with
+                // a different signature key, etc.
+                pfrom->Misbehaving(10);
             }
         }
     }
--- a/src/main.h
+++ b/src/main.h
@@ -1535,7 +1535,7 @@
 
     uint256 GetHash() const
     {
-        return SerializeHash(*this);
+        return Hash(this->vchMsg.begin(), this->vchMsg.end());
     }
 
     bool IsInEffect() const