v2-0001-Zero-padding-bytes-of-standby-and-heap_inplace-re.patch

application/octet-stream

Filename: v2-0001-Zero-padding-bytes-of-standby-and-heap_inplace-re.patch
Type: application/octet-stream
Part: 0
Message: Re: Fix uninitialized xl_running_xacts padding

Patch

Format: format-patch
Series: patch v2-0001
Subject: Zero padding bytes of standby and heap_inplace records
File+
src/backend/access/heap/heapam.c 1 1
src/backend/storage/ipc/standby.c 2 3
src/backend/utils/cache/inval.c 5 6
From 23e9742332751db758d3c3a9af1964766a731058 Mon Sep 17 00:00:00 2001
From: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Date: Fri, 13 Feb 2026 09:22:45 +0100
Subject: Zero padding bytes of standby and heap_inplace records

xl_running_xacts has 3 padding bytes after subxid_overflow which are
currently uninitialized. When the struct is written, those uninitialized
bytes are also written in the WAL. xl_heap_inplace has a similar
padding.

The shared invalidation messages have a similar issue as they are
allocated with MemoryContextAlloc.

This patch ensures those padding bytes are zeroed. The struct
initialization is done using '{0}' as C11 guarantees any padding is
initialized to zero bits.
---
 src/backend/access/heap/heapam.c  |  2 +-
 src/backend/storage/ipc/standby.c |  5 ++---
 src/backend/utils/cache/inval.c   | 11 +++++------
 3 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 98d53caeea8..ab10ab95f28 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -6646,7 +6646,7 @@ heap_inplace_update_and_unlock(Relation relation,
 	/* XLOG stuff */
 	if (RelationNeedsWAL(relation))
 	{
-		xl_heap_inplace xlrec;
+		xl_heap_inplace xlrec = {0};
 		PGAlignedBlock copied_buffer;
 		char	   *origdata = (char *) BufferGetBlock(buffer);
 		Page		page = BufferGetPage(buffer);
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index d83afbfb9d6..9f8fb406297 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -1353,7 +1353,7 @@ LogStandbySnapshot(void)
 static XLogRecPtr
 LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
 {
-	xl_running_xacts xlrec;
+	xl_running_xacts xlrec = {0};
 	XLogRecPtr	recptr;
 
 	xlrec.xcnt = CurrRunningXacts->xcnt;
@@ -1471,10 +1471,9 @@ void
 LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs,
 						bool relcacheInitFileInval)
 {
-	xl_invalidations xlrec;
+	xl_invalidations xlrec = {0};
 
 	/* prepare record */
-	memset(&xlrec, 0, sizeof(xlrec));
 	xlrec.dbId = MyDatabaseId;
 	xlrec.tsId = MyDatabaseTableSpace;
 	xlrec.relcacheInitFileInval = relcacheInitFileInval;
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index bf465a295e3..e41697d75ea 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -331,8 +331,8 @@ AddInvalidationMessage(InvalidationMsgsGroup *group, int subgroup,
 			int			reqsize = 32;	/* arbitrary */
 
 			ima->msgs = (SharedInvalidationMessage *)
-				MemoryContextAlloc(TopTransactionContext,
-								   reqsize * sizeof(SharedInvalidationMessage));
+				MemoryContextAllocZero(TopTransactionContext,
+									   reqsize * sizeof(SharedInvalidationMessage));
 			ima->maxmsgs = reqsize;
 			Assert(nextindex == 0);
 		}
@@ -1046,8 +1046,8 @@ xactGetCommittedInvalidationMessages(SharedInvalidationMessage **msgs,
 		NumMessagesInGroup(&transInvalInfo->ii.CurrentCmdInvalidMsgs);
 
 	*msgs = msgarray = (SharedInvalidationMessage *)
-		MemoryContextAlloc(CurTransactionContext,
-						   nummsgs * sizeof(SharedInvalidationMessage));
+		MemoryContextAllocZero(CurTransactionContext,
+							   nummsgs * sizeof(SharedInvalidationMessage));
 
 	nmsgs = 0;
 	ProcessMessageSubGroupMulti(&transInvalInfo->PriorCmdInvalidMsgs,
@@ -1938,7 +1938,7 @@ CallRelSyncCallbacks(Oid relid)
 void
 LogLogicalInvalidations(void)
 {
-	xl_xact_invals xlrec;
+	xl_xact_invals xlrec = {0};
 	InvalidationMsgsGroup *group;
 	int			nmsgs;
 
@@ -1952,7 +1952,6 @@ LogLogicalInvalidations(void)
 	if (nmsgs > 0)
 	{
 		/* prepare record */
-		memset(&xlrec, 0, MinSizeOfXactInvals);
 		xlrec.nmsgs = nmsgs;
 
 		/* perform insertion */
-- 
2.52.0