Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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)