gossmap: routine gossmap_disable_mmap() to force read() calls.
What changed, and why it matters
This commit adds a way for Core Lightning to deliberately stop using memory-mapped file access for its network gossip data and fall back to ordinary read() calls. The change itself is a routine helper function; it does not fix a crash or stop an attacker on its own. It appears to be infrastructure for a follow-up change, likely to work around a consistency problem between mmap and pwritev() on OpenBSD.
Treat as a non-security refactoring commit. If reviewing for security, check the caller(s) that invoke gossmap_disable_mmap() to see whether they are mitigating a concrete reliability or consistency issue, and verify that fallback read paths are exercised and correct.
Security signals we found
mmap/pwritev consistency concern mentioned in removed comments
OpenBSD-specific workaround removed in favor of runtime disable
No bounds-check, input-validation, or memory-safety fix visible in diff
Evidence from the diff
The patch introduces gossmap_disable_mmap() and gossmap_has_mmap() in common/gossmap.c/h. It also refactors load_gossip_store() and gossmap_refresh() so that mmap is attempted on all platforms (removing the compile-time OpenBSD skip) and so that a re-mmap in refresh only happens if mmap was already active. The new API lets callers force the gossmap into read()-only mode. There is no direct security bug being fixed in this diff; it is a plumbing change.
Changed components
common/gossmap.ccommon/gossmap.hgossip store loading and refresh pathInspect captured patch +22 / −9
diff --git a/common/gossmap.c b/common/gossmap.c
index 1fbd72f9..5e1ec960 100644
--- a/common/gossmap.c
+++ b/common/gossmap.c
@@ -779,12 +779,9 @@ static bool load_gossip_store(struct gossmap *map, bool must_be_clean)
map->local_announces = NULL;
map->local_updates = NULL;
- /* gossipd uses pwritev(), which is not consistent with mmap on OpenBSD! */
-#ifndef __OpenBSD__
/* If this fails, we fall back to read */
map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0);
if (map->mmap == MAP_FAILED)
-#endif /* __OpenBSD__ */
map->mmap = NULL;
/* We only support major version 0 */
@@ -1219,12 +1216,12 @@ bool gossmap_refresh(struct gossmap *map)
if (map->mmap)
munmap(map->mmap, map->map_size);
map->map_size = len;
- /* gossipd uses pwritev(), which is not consistent with mmap on OpenBSD! */
-#ifndef __OpenBSD__
- map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0);
- if (map->mmap == MAP_FAILED)
-#endif /* __OpenBSD__ */
- map->mmap = NULL;
+
+ if (map->mmap) {
+ map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0);
+ if (map->mmap == MAP_FAILED)
+ map->mmap = NULL;
+ }
map_catchup(map, false, &changed);
return changed;
@@ -1857,6 +1854,18 @@ int gossmap_fd(const struct gossmap *map)
return map->fd;
}
+bool gossmap_has_mmap(const struct gossmap *map)
+{
+ return map->mmap != NULL;
+}
+
+void gossmap_disable_mmap(struct gossmap *map)
+{
+ if (map->mmap)
+ munmap(map->mmap, map->map_size);
+ map->mmap = NULL;
+}
+
const u8 *gossmap_fetch_tail(const tal_t *ctx, const struct gossmap *map)
{
size_t len;
diff --git a/common/gossmap.h b/common/gossmap.h
index 14a17a04..a7c00586 100644
--- a/common/gossmap.h
+++ b/common/gossmap.h
@@ -70,6 +70,10 @@ struct gossmap *gossmap_load_(const tal_t *ctx,
...),
void *cb_arg);
+/* Disable mmap. Noop if already disabled. */
+void gossmap_disable_mmap(struct gossmap *map);
+bool gossmap_has_mmap(const struct gossmap *map);
+
/* Call this before using to ensure it's up-to-date. Returns true if something
* was updated. Note: this can scramble node and chan indexes! */
bool gossmap_refresh(struct gossmap *map);
Why this scored 17/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.