gossmap: disable mmap on any read error.
What changed, and why it matters
This change makes Core Lightning's network-map reader (gossmap) stop using memory-mapped file access whenever it hits a read error or bad checksum. On some filesystems like ZFS on Linux, mmap can return stale or partially written data, which makes the daemon think the gossip store is corrupt. The patch falls back to ordinary read calls, which should see the correct data. It is a robustness fix for a reliability problem rather than a clear-cut security vulnerability.
Treat as a reliability and defensive-hardening patch. Backport to stable branches if users report 'Bad checksum on gossmap record' or 'Truncated gossmap record' errors on ZFS or similar copy-on-write filesystems. No urgent security response is indicated by the diff alone.
Security signals we found
Defensive hardening against filesystem-specific mmap coherence issues
Bad checksum / truncated record handling now includes mmap fallback
No input validation bypass or cryptographic weakness introduced
No memory corruption, use-after-free, or overflow pattern visible in diff
Evidence from the diff
The gossmap subsystem maps the gossip_store file into memory and catches up on new records. Previously, when it encountered a truncated record or a CRC mismatch, it logged a BROKEN message and waited. The patch now also disables mmap in those same error paths by calling gossmap_disable_mmap(). The commit message notes this can happen on ZFS on Linux, where mmap may read stale pages while the file is being appended by another process. Disabling mmap forces subsequent reads through normal file I/O, which observes the updated file contents. The change is defensive and local to common/gossmap.c.
Changed components
common/gossmap.cconnectd (consumer of gossmap)gossip_store processingInspect captured patch +8 / −4
diff --git a/common/gossmap.c b/common/gossmap.c
index 5e1ec960..aed9852d 100644
--- a/common/gossmap.c
+++ b/common/gossmap.c
@@ -706,8 +706,10 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
map->logcb(map->cbarg,
LOG_BROKEN,
"Truncated gossmap record @%"PRIu64
- "/%"PRIu64" (len %zu): waiting",
- map->map_end, map->map_size, msglen);
+ "/%"PRIu64" (len %zu): waiting%s",
+ map->map_end, map->map_size, msglen,
+ gossmap_has_mmap(map) ? " and disabling mmap" : "");
+ gossmap_disable_mmap(map);
if (must_be_clean)
return false;
break;
@@ -725,10 +727,12 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
map->logcb(map->cbarg,
LOG_BROKEN,
"Bad checksum on gossmap record @%"PRIu64
- "/%"PRIu64" should be %u (%s): waiting",
+ "/%"PRIu64" should be %u (%s): waiting%s",
map->map_end, map->map_size,
be32_to_cpu(ghdr.crc),
- tal_hexstr(tmpctx, msgbuf, msglen));
+ tal_hexstr(tmpctx, msgbuf, msglen),
+ gossmap_has_mmap(map) ? " and disabling mmap" : "");
+ gossmap_disable_mmap(map);
if (must_be_clean)
return false;
break;
Why this scored 41/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.