From 40a50c1adabbc97b49f1d3d9aea59f3db653ae79 Mon Sep 17 00:00:00 2001 From: Alex Myers Date: Thu, 25 May 2023 14:36:22 -0500 Subject: [PATCH] gossipd: don't fail on gossip deletion Reported in #6270, there was an attempt to delete gossip overrunning the end of the gossip_store. This logs the gossip type that was attempted to be deleted and avoids an immediate crash (tombstones would be fine to skip over at least.) Changelog-None --- gossipd/gossip_store.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 51051c842..194837b3e 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -598,15 +598,27 @@ static u32 delete_by_index(struct gossip_store *gs, u32 index, int type) /* Should never try to overwrite version */ assert(index); -#if DEVELOPER - const u8 *msg = gossip_store_get(tmpctx, gs, index); - assert(fromwire_peektype(msg) == type); -#endif + /* FIXME: debugging a gs->len overrun issue reported in #6270 */ + if (pread(gs->fd, &hdr, sizeof(hdr), index) != sizeof(hdr)) { + status_broken("gossip_store overrun during delete @%u type: %i" + " gs->len: %"PRIu64, index, type, gs->len); + return index; + } + if (index + sizeof(struct gossip_hdr) + + be16_to_cpu(hdr.belen) > gs->len) { + status_broken("gossip_store overrun during delete @%u type: %i" + " gs->len: %"PRIu64, index, type, gs->len); + return index; + } - if (pread(gs->fd, &hdr, sizeof(hdr), index) != sizeof(hdr)) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Failed reading flags & len to delete @%u: %s", - index, strerror(errno)); + const u8 *msg = gossip_store_get(tmpctx, gs, index); + if(fromwire_peektype(msg) != type) { + status_broken("asked to delete type %i @%u but store contains " + "%i (gs->len=%"PRIu64"): %s", + type, index, fromwire_peektype(msg), + gs->len, tal_hex(tmpctx, msg)); + return index; + } assert((be16_to_cpu(hdr.beflags) & GOSSIP_STORE_DELETED_BIT) == 0); hdr.beflags |= cpu_to_be16(GOSSIP_STORE_DELETED_BIT);