Skip to content

Commit 0cc864b

Browse files
committed
Handle unaligned SerializeSnapshot() buffer.
Likewise in RestoreSnapshot(). Do so by copying between the user buffer and a stack buffer of known alignment. Back-patch to 9.6, where this last applies cleanly. In master, the select_parallel test dies with SIGBUS on "Oracle Solaris 10 1/13 s10s_u11wos_24a SPARC", building 32-bit with gcc 4.9.2. In 9.6 and 9.5, the buffers in question happen to be sufficiently-aligned, and this change is mere insurance against future 9.6 changes or extension code compromising that.
1 parent 3a1a422 commit 0cc864b

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

src/backend/utils/time/snapmgr.c

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,34 +2012,37 @@ EstimateSnapshotSpace(Snapshot snap)
20122012
void
20132013
SerializeSnapshot(Snapshot snapshot, char *start_address)
20142014
{
2015-
SerializedSnapshotData *serialized_snapshot;
2015+
SerializedSnapshotData serialized_snapshot;
20162016

20172017
Assert(snapshot->subxcnt >= 0);
20182018

2019-
serialized_snapshot = (SerializedSnapshotData *) start_address;
2020-
20212019
/* Copy all required fields */
2022-
serialized_snapshot->xmin = snapshot->xmin;
2023-
serialized_snapshot->xmax = snapshot->xmax;
2024-
serialized_snapshot->xcnt = snapshot->xcnt;
2025-
serialized_snapshot->subxcnt = snapshot->subxcnt;
2026-
serialized_snapshot->suboverflowed = snapshot->suboverflowed;
2027-
serialized_snapshot->takenDuringRecovery = snapshot->takenDuringRecovery;
2028-
serialized_snapshot->curcid = snapshot->curcid;
2029-
serialized_snapshot->whenTaken = snapshot->whenTaken;
2030-
serialized_snapshot->lsn = snapshot->lsn;
2020+
serialized_snapshot.xmin = snapshot->xmin;
2021+
serialized_snapshot.xmax = snapshot->xmax;
2022+
serialized_snapshot.xcnt = snapshot->xcnt;
2023+
serialized_snapshot.subxcnt = snapshot->subxcnt;
2024+
serialized_snapshot.suboverflowed = snapshot->suboverflowed;
2025+
serialized_snapshot.takenDuringRecovery = snapshot->takenDuringRecovery;
2026+
serialized_snapshot.curcid = snapshot->curcid;
2027+
serialized_snapshot.whenTaken = snapshot->whenTaken;
2028+
serialized_snapshot.lsn = snapshot->lsn;
20312029

20322030
/*
20332031
* Ignore the SubXID array if it has overflowed, unless the snapshot was
20342032
* taken during recovey - in that case, top-level XIDs are in subxip as
20352033
* well, and we mustn't lose them.
20362034
*/
2037-
if (serialized_snapshot->suboverflowed && !snapshot->takenDuringRecovery)
2038-
serialized_snapshot->subxcnt = 0;
2035+
if (serialized_snapshot.suboverflowed && !snapshot->takenDuringRecovery)
2036+
serialized_snapshot.subxcnt = 0;
2037+
2038+
/* Copy struct to possibly-unaligned buffer */
2039+
memcpy(start_address,
2040+
&serialized_snapshot, sizeof(SerializedSnapshotData));
20392041

20402042
/* Copy XID array */
20412043
if (snapshot->xcnt > 0)
2042-
memcpy((TransactionId *) (serialized_snapshot + 1),
2044+
memcpy((TransactionId *) (start_address +
2045+
sizeof(SerializedSnapshotData)),
20432046
snapshot->xip, snapshot->xcnt * sizeof(TransactionId));
20442047

20452048
/*
@@ -2048,12 +2051,12 @@ SerializeSnapshot(Snapshot snapshot, char *start_address)
20482051
* snapshot taken during recovery; all the top-level XIDs are in subxip as
20492052
* well in that case, so we mustn't lose them.
20502053
*/
2051-
if (serialized_snapshot->subxcnt > 0)
2054+
if (serialized_snapshot.subxcnt > 0)
20522055
{
20532056
Size subxipoff = sizeof(SerializedSnapshotData) +
20542057
snapshot->xcnt * sizeof(TransactionId);
20552058

2056-
memcpy((TransactionId *) ((char *) serialized_snapshot + subxipoff),
2059+
memcpy((TransactionId *) (start_address + subxipoff),
20572060
snapshot->subxip, snapshot->subxcnt * sizeof(TransactionId));
20582061
}
20592062
}
@@ -2068,50 +2071,51 @@ SerializeSnapshot(Snapshot snapshot, char *start_address)
20682071
Snapshot
20692072
RestoreSnapshot(char *start_address)
20702073
{
2071-
SerializedSnapshotData *serialized_snapshot;
2074+
SerializedSnapshotData serialized_snapshot;
20722075
Size size;
20732076
Snapshot snapshot;
20742077
TransactionId *serialized_xids;
20752078

2076-
serialized_snapshot = (SerializedSnapshotData *) start_address;
2079+
memcpy(&serialized_snapshot, start_address,
2080+
sizeof(SerializedSnapshotData));
20772081
serialized_xids = (TransactionId *)
20782082
(start_address + sizeof(SerializedSnapshotData));
20792083

20802084
/* We allocate any XID arrays needed in the same palloc block. */
20812085
size = sizeof(SnapshotData)
2082-
+ serialized_snapshot->xcnt * sizeof(TransactionId)
2083-
+ serialized_snapshot->subxcnt * sizeof(TransactionId);
2086+
+ serialized_snapshot.xcnt * sizeof(TransactionId)
2087+
+ serialized_snapshot.subxcnt * sizeof(TransactionId);
20842088

20852089
/* Copy all required fields */
20862090
snapshot = (Snapshot) MemoryContextAlloc(TopTransactionContext, size);
20872091
snapshot->satisfies = HeapTupleSatisfiesMVCC;
2088-
snapshot->xmin = serialized_snapshot->xmin;
2089-
snapshot->xmax = serialized_snapshot->xmax;
2092+
snapshot->xmin = serialized_snapshot.xmin;
2093+
snapshot->xmax = serialized_snapshot.xmax;
20902094
snapshot->xip = NULL;
2091-
snapshot->xcnt = serialized_snapshot->xcnt;
2095+
snapshot->xcnt = serialized_snapshot.xcnt;
20922096
snapshot->subxip = NULL;
2093-
snapshot->subxcnt = serialized_snapshot->subxcnt;
2094-
snapshot->suboverflowed = serialized_snapshot->suboverflowed;
2095-
snapshot->takenDuringRecovery = serialized_snapshot->takenDuringRecovery;
2096-
snapshot->curcid = serialized_snapshot->curcid;
2097-
snapshot->whenTaken = serialized_snapshot->whenTaken;
2098-
snapshot->lsn = serialized_snapshot->lsn;
2097+
snapshot->subxcnt = serialized_snapshot.subxcnt;
2098+
snapshot->suboverflowed = serialized_snapshot.suboverflowed;
2099+
snapshot->takenDuringRecovery = serialized_snapshot.takenDuringRecovery;
2100+
snapshot->curcid = serialized_snapshot.curcid;
2101+
snapshot->whenTaken = serialized_snapshot.whenTaken;
2102+
snapshot->lsn = serialized_snapshot.lsn;
20992103

21002104
/* Copy XIDs, if present. */
2101-
if (serialized_snapshot->xcnt > 0)
2105+
if (serialized_snapshot.xcnt > 0)
21022106
{
21032107
snapshot->xip = (TransactionId *) (snapshot + 1);
21042108
memcpy(snapshot->xip, serialized_xids,
2105-
serialized_snapshot->xcnt * sizeof(TransactionId));
2109+
serialized_snapshot.xcnt * sizeof(TransactionId));
21062110
}
21072111

21082112
/* Copy SubXIDs, if present. */
2109-
if (serialized_snapshot->subxcnt > 0)
2113+
if (serialized_snapshot.subxcnt > 0)
21102114
{
21112115
snapshot->subxip = ((TransactionId *) (snapshot + 1)) +
2112-
serialized_snapshot->xcnt;
2113-
memcpy(snapshot->subxip, serialized_xids + serialized_snapshot->xcnt,
2114-
serialized_snapshot->subxcnt * sizeof(TransactionId));
2116+
serialized_snapshot.xcnt;
2117+
memcpy(snapshot->subxip, serialized_xids + serialized_snapshot.xcnt,
2118+
serialized_snapshot.subxcnt * sizeof(TransactionId));
21152119
}
21162120

21172121
/* Set the copied flag so that the caller will set refcounts correctly. */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy