gossipd: put common size restrictions on all maps.
What changed, and why it matters
This change adds size caps to internal queues in the Lightning node's gossip subsystem, mirroring limits that already existed for some maps. It is a hardening/DoS-prevention patch: without limits, an attacker could potentially flood the node with gossip messages and consume unbounded memory. The patch also adds a CI_UNEXPECTED marker so the continuous-integration system flags unexpected flooding. There is no direct evidence in the commit of an active exploit or a specific vulnerability being fixed beyond resource-exhaustion risk.
Treat as a defensive hardening patch. Review whether 10,000 is an appropriate limit under adversarial load and ensure CI_UNEXPECTED alerts are monitored. No immediate emergency response is warranted absent evidence of an active exploit, but operators should upgrade in due course to reduce DoS surface.
Security signals we found
Resource-exhaustion/DoS hardening: unbounded queues now have a common size cap
Flooding detection: status_unusual_once warnings with CI_UNEXPECTED for unexpected queue overflow
Memory-management fix: tal_free_if_taken on dropped TAKES parameters to avoid leaks
Consistency: applies existing 10,000-entry limit pattern to additional maps
Evidence from the diff
The commit introduces a PENDING_LIMIT of 10,000 and applies it to pending_nannounces, pending_cupdates, and early_cupdates in gossipd/gossmap_manage.c, in addition to the existing pending_ann_map and early_ann_map limits. When a queue exceeds the limit, new node_announcements or channel_updates are dropped, a one-time status_unusual_once warning is emitted with CI_UNEXPECTED, and TAKEN parameters are freed. The change is defensive: it prevents unbounded growth of in-memory gossip queues from a peer flooding the node with valid or invalid gossip messages.
Changed components
gossipd/gossmap_manage.cpending_nannounces queuepending_cupdates queueearly_cupdates mappending_ann_map and early_ann_map (limit now centralized via PENDING_LIMIT)Inspect captured patch +36 / −4
diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c
index 67089e42..4cedf211 100644
--- a/gossipd/gossmap_manage.c
+++ b/gossipd/gossmap_manage.c
@@ -29,6 +29,7 @@
#include <sys/wait.h>
#include <unistd.h>
+#define PENDING_LIMIT 10000
#define GOSSIP_STORE_COMPACT_FILENAME "gossip_store.compact"
struct pending_cannounce {
@@ -133,9 +134,24 @@ static void enqueue_cupdate(struct pending_cupdate ***queue,
u32 fee_proportional_millionths,
u32 timestamp,
const u8 *update TAKES,
- const struct node_id *source_peer TAKES)
+ const struct node_id *source_peer)
{
- struct pending_cupdate *pcu = tal(*queue, struct pending_cupdate);
+ struct pending_cupdate *pcu;
+
+ if (tal_count(*queue) > PENDING_LIMIT) {
+ static bool warned = false;
+ status_unusual_once(&warned,
+ CI_UNEXPECTED
+ "channel_updates being flooded by %s: dropping some",
+ source_peer
+ ? fmt_node_id(tmpctx, source_peer)
+ : "unknown");
+ tal_free_if_taken(update);
+ tal_free_if_taken(source_peer);
+ return;
+ }
+
+ pcu = tal(*queue, struct pending_cupdate);
pcu->scid = scid;
pcu->signature = *signature;
@@ -159,7 +175,22 @@ static void enqueue_nannounce(struct pending_nannounce ***queue,
const u8 *nannounce TAKES,
const struct node_id *source_peer TAKES)
{
- struct pending_nannounce *pna = tal(*queue, struct pending_nannounce);
+ struct pending_nannounce *pna;
+
+ if (tal_count(*queue) > PENDING_LIMIT) {
+ static bool warned = false;
+ status_unusual_once(&warned,
+ CI_UNEXPECTED
+ "node_announcements being flooded by %s: dropping some",
+ source_peer
+ ? fmt_node_id(tmpctx, source_peer)
+ : "unknown");
+ tal_free_if_taken(nannounce);
+ tal_free_if_taken(source_peer);
+ return;
+ }
+
+ pna = tal(*queue, struct pending_nannounce);
pna->node_id = *node_id;
pna->timestamp = timestamp;
@@ -183,8 +214,9 @@ static bool map_add(struct cannounce_map *map,
struct pending_cannounce *pca)
{
/* More than 10000 pending things? Stop! */
- if (map->count > 10000) {
+ if (map->count > PENDING_LIMIT) {
status_unusual_once(&map->flood_reported,
+ CI_UNEXPECTED
"%s being flooded by %s: dropping some",
map->name,
pca->source_peer
Why this scored 50/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.