Mitigate disk filling attacks by rate limiting Log writing by tomt1664 · Pull Request #1514 · ElementsProject/elements
and others added 2 commits
November 24, 2025 12:33e11cdc9 logging: Add log severity level to net.cpp (klementtan) a829064 logging: Add severity level to logs. (klementtan) Pull request description: **Overview**: This PR introduces a new macro, `LogPrintLevel`, that allows developers to add logs with the severity level. Additionally, it will also print the log category if it is specified. Sample log: ``` 2022-03-04T16:41:15Z [opencon] [net:debug] trying connection XX.XX.XXX.XXX:YYYYY lastseen=2.7hrs ``` **Motivation**: This feature was suggested in #20576 and I believe that it will bring the following benefits: * Allow for easier filtering of logs in `debug.log` * Can be extended to allow users to select the minimum level of logs they would like to view (not in the scope of this PR) **Details**: * New log format. `... [category:level]...`. ie: * Do not print category if `category == NONE` * Do not print level if `level == NONE` * If `category == NONE` and `level == NONE`, do not print any fields (current behaviour) * Previous logging functions: * `LogPrintf`: no changes in log as it calls `LogPrintf_` with `category = NONE` and `level = NONE` * `LogPrint`: prints additional `[category]` field as it calls `LogPrintf_` with `category = category` and `level = NONE` * `net.cpp`: As a proof of concept, updated logs with obvious severity (ie prefixed with `Warning/Error:..`) to use the new logging with severity. **Testing**: * Compiling and running `bitcoind` with this PR should instantly display logs with the category name (ie `net/tor/...`) * Grepping for `net:debug` in `debug.log` should display the updated logs with severity level: <details> <summary>Code</summary> ``` $ grep "net:debug" debug.log 2022-03-04T16:41:15Z [opencon] [net:debug] trying connection XXX:YYY lastseen=2.7hrs 2022-03-04T16:41:16Z [opencon] [net:debug] trying connection XXX:YYY lastseen=16.9hrs 2022-03-04T16:41:17Z [opencon] [net:debug] trying connection XXX:YYY lastseen=93.2hrs 2022-03-04T16:41:18Z [opencon] [net:debug] trying connection XXX:YYY lastseen=2.7hrs ``` </details> ACKs for top commit: laanwj: Code review and lightly tested ACK e11cdc9 Tree-SHA512: 89a8c86667ccc0688e5acfdbd399aac1f5bec9f978a160e40b0210b0d9b8fdc338479583fc5bd2e2bc785821363f174f578d52136d228e8f638a20abbf0a568f
The LogRatelimiter class implements a fixed window rate limiter. The rate limiter allows a fixed amount of bytes to be consumed within a fixed time window. [log] Introduce source location type The SourceLocation type stores the filename and line of a source code location. In a later commit we use this type as the key type in an unordered map and set to keep track of rate limters for each location. [config] Add -ratelimitlogging config option The -ratelimitlogging can be used to enable/disable the rate limiting to disk. Rate limiting is enabled by default. [log] Add two new categories for unconditional logging We create two new categories `UNCONDITIONAL_ALWAYS` and `UNCONDITIONAL_RATE_LIMITED` that are always enabled by default. LogPrintf now logs using the `UNCONDITIONAL_RATE_LIMITED` category which will start to apply rate limiting in a later commit. For some log locations it might be safe to allow more frequent logging without rate limiting. These locations should use the `UNCONDITIONAL_ALWAYS` category. [validation] Exempt UpdateTipLog from rate limiting UpdateTipLog logs everytime a new tip is activated. This occurs at an increased frequency during IBD and should therefore be exempt from rate limiting. [log] Add rate limiting to LogPrintf To mitigate disk filling attacks caused by unsafe usages of LogPrintf, we rate limit LogPrintf by using the fixed window rate limiter (BCLog::LogRatelimiter) introduced in an earlier commit. The rate limiting logic is applied per source location instead of globally. A source location is allowed to log up to 1 MiB per hour. Source locations that violate the limit will have their logs supressed for up to one hour. [test util] Mark ~DebugLogHelper as noexcept(false) We mark ~DebugLogHelper as noexcept(false) to be able to catch the exception it throws. This lets us use it in test in combination with BOOST_CHECK_THROW and BOOST_CHECK_NO_THROW to check that certain log messages are (not) logged. [test] Check for expected log rate limiting messages [test] Test for expected file size changes when rate limiting is enabled [test] Check that log rate limiting is disabled for exempt source locations [test] Check that rate limiting can be disabled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters