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
This commit is contained in:
Alex Myers 2023-05-25 14:36:22 -05:00 committed by Rusty Russell
parent 23088911f7
commit 40a50c1ada
1 changed files with 20 additions and 8 deletions

View File

@ -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);