Mitigate disk filling attacks by temporarily rate limiting LogPrintf(…)
.
A disk fill attack is an attack where an untrusted party (such as a peer) is able to cheaply make your node log to disk excessively. The excessive logging may fill your disk and thus make your node crash either cleanly (best case: if disk fill rate is relatively slow) or uncleanly (worst case: if disk fill rate is relatively fast).
The hourly logging quota is set per source location. Every single source location (say net_processing.cpp:418
) gets a quota of 1 MB of logging per hour.
Notes:
- Only logging to disk is rate limited. Logging to console is not rate limited.
- Only
LogPrintf(…)
is rate limited.LogPrint(category, …)
(-debug
) is not rate limited. UpdateTip: new best=[…]
is logged usingLogPrintfWithoutRateLimiting(…)
to avoid rate limiting. High log volume is expected for that source location during IBD.
Live demo:
0$ git diff
1diff --git a/src/init.cpp b/src/init.cpp
2index 023aa9aba..56a250876 100644
3--- a/src/init.cpp
4+++ b/src/init.cpp
5@@ -1232,6 +1232,13 @@ bool AppInitInterfaces(NodeContext& node)
6 return true;
7 }
8
9+void SimulateDiskFillingAttack() {
10+ uint64_t n = 0;
11+ while (true) {
12+ LogPrintf("Chancellor on brink of %d:th bailout for banks. LogPrintf on brink of first disk fill for node.\n", ++n);
13+ }
14+}
15+
16 bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
17 {
18 const ArgsManager& args = *Assert(node.args);
19@@ -1845,6 +1852,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA
20 }
21 #endif
22
23+ std::thread{SimulateDiskFillingAttack}.detach();
24+
25 std::vector<fs::path> vImportFiles;
26 for (const std::string& strFile : args.GetArgs("-loadblock")) {
27 vImportFiles.push_back(strFile);
28$ make -C src/ bitcoind
29$ src/bitcoind
30$ tail debug.log
312020-09-22T16:11:36Z Chancellor on brink of 8813:th bailout for banks. LogPrintf on brink of first disk fill for node.
322020-09-22T16:11:36Z Chancellor on brink of 8814:th bailout for banks. LogPrintf on brink of first disk fill for node.
332020-09-22T16:11:36Z Chancellor on brink of 8815:th bailout for banks. LogPrintf on brink of first disk fill for node.
342020-09-22T16:11:36Z Chancellor on brink of 8816:th bailout for banks. LogPrintf on brink of first disk fill for node.
352020-09-22T16:11:36Z Chancellor on brink of 8817:th bailout for banks. LogPrintf on brink of first disk fill for node.
362020-09-22T16:11:36Z Chancellor on brink of 8818:th bailout for banks. LogPrintf on brink of first disk fill for node.
372020-09-22T16:11:36Z Chancellor on brink of 8819:th bailout for banks. LogPrintf on brink of first disk fill for node.
382020-09-22T16:11:36Z Chancellor on brink of 8820:th bailout for banks. LogPrintf on brink of first disk fill for node.
392020-09-22T16:11:36Z Excessive logging detected from init.cpp:1238 (SimulateDiskFillingAttack): >1 MiB logged during the last hour. Suppressing logging to disk from this source location for up to one hour. Console logging unaffected. Last log entry: 2020-09-22T16:11:36Z Chancellor on brink of 8821:th bailout for banks. LogPrintf on brink of first disk fill for node.
402020-09-22T16:12:37Z Adding fixed seed nodes as DNS doesn't seem to be available.
41$ ls -hl debug.log
42–rw------- 1 1.1M Sep 22 16:12 debug.log