v28-0006-Add-runtime-checks-for-bogus-multixact-offsets.patch
text/x-patch
Filename: v28-0006-Add-runtime-checks-for-bogus-multixact-offsets.patch
Type: text/x-patch
Part: 5
Message:
Re: POC: make mxidoff 64 bits
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v28-0006
Subject: Add runtime checks for bogus multixact offsets
| File | + | − |
|---|---|---|
| src/backend/access/transam/multixact.c | 21 | 12 |
From 706d0421ae23119382bbe41bf38570b1b4cb6edf Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
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