From 706d0421ae23119382bbe41bf38570b1b4cb6edf Mon Sep 17 00:00:00 2001 From: Heikki Linnakangas Date: Thu, 4 Dec 2025 15:31:39 +0200 Subject: [PATCH v28 6/6] Add runtime checks for bogus multixact offsets These are not directly related to 64 bit offsets, but makes sense I think --- src/backend/access/transam/multixact.c | 33 ++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c index dffa0c8e7d4..dc9c4257a98 100644 --- a/src/backend/access/transam/multixact.c +++ b/src/backend/access/transam/multixact.c @@ -1154,6 +1154,7 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, int slotno; MultiXactOffset *offptr; MultiXactOffset offset; + MultiXactOffset nextMXOffset; int length; MultiXactId oldestMXact; MultiXactId nextMXact; @@ -1245,12 +1246,14 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, offptr += entryno; offset = *offptr; - Assert(offset != 0); + if (offset == 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("MultiXact %u has invalid offset", multi))); /* read next multi's offset */ { MultiXactId tmpMXact; - MultiXactOffset nextMXOffset; /* handle wraparound if needed */ tmpMXact = multi + 1; @@ -1284,21 +1287,27 @@ GetMultiXactIdMembers(MultiXactId multi, MultiXactMember **members, offptr = (MultiXactOffset *) MultiXactOffsetCtl->shared->page_buffer[slotno]; offptr += entryno; nextMXOffset = *offptr; - - if (nextMXOffset == 0) - ereport(ERROR, - (errcode(ERRCODE_DATA_CORRUPTED), - errmsg("MultiXact %u has invalid next offset", - multi))); - - length = nextMXOffset - offset; } LWLockRelease(lock); lock = NULL; - /* A multixid with zero members should not happen */ - Assert(length > 0); + /* Sanity check the next offset */ + if (nextMXOffset == 0) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("MultiXact %u has invalid next offset", multi))); + if (nextMXOffset < offset) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("MultiXact %u has offset (%" PRIu64") greater than its next offset (%" PRIu64")", + multi, offset, nextMXOffset))); + if (nextMXOffset - offset > INT32_MAX) + ereport(ERROR, + (errcode(ERRCODE_DATA_CORRUPTED), + errmsg("MultiXact %u has too many members (%" PRIu64 ")", + multi, nextMXOffset - offset))); + length = nextMXOffset - offset; /* read the members */ ptr = (MultiXactMember *) palloc(length * sizeof(MultiXactMember)); -- 2.47.3