gossmap: use gossmap_disable_mmap() on corruption.
What changed, and why it matters
This change makes Core Lightning's gossip map (the data structure tracking network routing announcements) fall back to non-memory-mapped file access when it detects internal inconsistencies. Previously the code just forced the gossip store file to disk with fsync and then crashed if the map still looked wrong. Now it disables memory mapping first and refreshes the view, only crashing if the mismatch persists. This is a robustness improvement that may avoid unnecessary node failures and could prevent or mask a class of crashes/undefined behavior caused by stale mmap views of the gossip store.
Treat as a hardening/robustness patch. Review whether the underlying mmap inconsistency has a security root cause (e.g., untrusted gossip input causing invalid map state). Monitor for related follow-up commits or disclosures. No immediate emergency action is indicated from this diff alone.
Security signals we found
Changes failure handling for a shared memory-mapped data structure
Disables mmap on detected corruption/inconsistency rather than forcing fsync and crashing
Adds a recovery attempt before terminating the daemon
May mitigate denial-of-service from malformed or race-triggered gossip store states
Evidence from the diff
In gossipd/gossmap_manage.c, the function gossmap_manage_get_gossmap() checks that the in-memory gossmap length matches the amount of data written to the gossip_store. The old path logged a broken status, called gossip_store_fsync(), refreshed the mmap, and then status_failed() if the map still didn’t consume everything. The new path records whether mmap was active, calls gossmap_disable_mmap() on mismatch, refreshes, and only fails if map_used still doesn’t equal map_size. A similar disable-and-refresh is added before the final failure path. This shifts the failure mode from ‘crash on mmap inconsistency’ to ‘retry without mmap, crash only if truly inconsistent’.
Changed components
gossipd/gossmap_manage.cgossmap memory-mapped store handlinggossip_store consistency checksInspect captured patch +19 / −6
diff --git a/gossipd/gossmap_manage.c b/gossipd/gossmap_manage.c
index ed24fe9a..25ea55ad 100644
--- a/gossipd/gossmap_manage.c
+++ b/gossipd/gossmap_manage.c
@@ -1411,6 +1411,7 @@ static const u8 *fetch_tail_fd(const tal_t *ctx,
struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm)
{
u64 map_used, map_size, written_len;
+ bool has_mmap = gossmap_has_mmap(gm->raw_gossmap);
gossmap_refresh(gm->raw_gossmap);
@@ -1419,10 +1420,12 @@ struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm)
written_len = gossip_store_len_written(gm->gs);
if (map_size != written_len) {
- status_broken("gossmap size %"PRIu64" != written size %"PRIu64,
- map_size, written_len);
- /* Push harder! */
- gossip_store_fsync(gm->gs);
+ status_broken("gossmap size %"PRIu64" != written size %"PRIu64
+ ": %s mmap!",
+ map_size, written_len,
+ has_mmap
+ ? "disabling": "ALREADY DISABLED");
+ gossmap_disable_mmap(gm->raw_gossmap);
gossmap_refresh(gm->raw_gossmap);
/* Sanity check that we see everything we wrote. */
@@ -1439,11 +1442,21 @@ struct gossmap *gossmap_manage_get_gossmap(struct gossmap_manage *gm)
remainder_fd = fetch_tail_fd(tmpctx,
gossmap_fd(gm->raw_gossmap),
map_used, map_size);
- status_failed(STATUS_FAIL_INTERNAL_ERROR,
- "Gossmap failed to process entire gossip_store: "
+ status_broken("Gossmap failed to process entire gossip_store, %s mmap: "
"at %"PRIu64" of %"PRIu64" remaining_fd=%s",
+ has_mmap
+ ? "disabling": "ALREADY DISABLED",
map_used, map_size,
tal_hex(tmpctx, remainder_fd));
+ gossmap_disable_mmap(gm->raw_gossmap);
+ gossmap_refresh(gm->raw_gossmap);
+
+ map_used = gossmap_lengths(gm->raw_gossmap, &map_size);
+ if (map_size != map_used) {
+ status_failed(STATUS_FAIL_INTERNAL_ERROR,
+ "Gossmap map_used %"PRIu64" of %"PRIu64" with %"PRIu64" written",
+ map_used, map_size, written_len);
+ }
}
return gm->raw_gossmap;
Why this scored 45/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.