Skip to content

Commit 7f31121

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 4461a9b commit 7f31121

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
@@ -2015,34 +2015,37 @@ EstimateSnapshotSpace(Snapshot snap)
20152015
void
20162016
SerializeSnapshot(Snapshot snapshot, char *start_address)
20172017
{
2018-
SerializedSnapshotData *serialized_snapshot;
2018+
SerializedSnapshotData serialized_snapshot;
20192019

20202020
Assert(snapshot->subxcnt >= 0);
20212021

2022-
serialized_snapshot = (SerializedSnapshotData *) start_address;
2023-
20242022
/* Copy all required fields */
2025-
serialized_snapshot->xmin = snapshot->xmin;
2026-
serialized_snapshot->xmax = snapshot->xmax;
2027-
serialized_snapshot->xcnt = snapshot->xcnt;
2028-
serialized_snapshot->subxcnt = snapshot->subxcnt;
2029-
serialized_snapshot->suboverflowed = snapshot->suboverflowed;
2030-
serialized_snapshot->takenDuringRecovery = snapshot->takenDuringRecovery;
2031-
serialized_snapshot->curcid = snapshot->curcid;
2032-
serialized_snapshot->whenTaken = snapshot->whenTaken;
2033-
serialized_snapshot->lsn = snapshot->lsn;
2023+
serialized_snapshot.xmin = snapshot->xmin;
2024+
serialized_snapshot.xmax = snapshot->xmax;
2025+
serialized_snapshot.xcnt = snapshot->xcnt;
2026+
serialized_snapshot.subxcnt = snapshot->subxcnt;
2027+
serialized_snapshot.suboverflowed = snapshot->suboverflowed;
2028+
serialized_snapshot.takenDuringRecovery = snapshot->takenDuringRecovery;
2029+
serialized_snapshot.curcid = snapshot->curcid;
2030+
serialized_snapshot.whenTaken = snapshot->whenTaken;
2031+
serialized_snapshot.lsn = snapshot->lsn;
20342032

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

20432045
/* Copy XID array */
20442046
if (snapshot->xcnt > 0)
2045-
memcpy((TransactionId *) (serialized_snapshot + 1),
2047+
memcpy((TransactionId *) (start_address +
2048+
sizeof(SerializedSnapshotData)),
20462049
snapshot->xip, snapshot->xcnt * sizeof(TransactionId));
20472050

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

2059-
memcpy((TransactionId *) ((char *) serialized_snapshot + subxipoff),
2062+
memcpy((TransactionId *) (start_address + subxipoff),
20602063
snapshot->subxip, snapshot->subxcnt * sizeof(TransactionId));
20612064
}
20622065
}
@@ -2071,50 +2074,51 @@ SerializeSnapshot(Snapshot snapshot, char *start_address)
20712074
Snapshot
20722075
RestoreSnapshot(char *start_address)
20732076
{
2074-
SerializedSnapshotData *serialized_snapshot;
2077+
SerializedSnapshotData serialized_snapshot;
20752078
Size size;
20762079
Snapshot snapshot;
20772080
TransactionId *serialized_xids;
20782081

2079-
serialized_snapshot = (SerializedSnapshotData *) start_address;
2082+
memcpy(&serialized_snapshot, start_address,
2083+
sizeof(SerializedSnapshotData));
20802084
serialized_xids = (TransactionId *)
20812085
(start_address + sizeof(SerializedSnapshotData));
20822086

20832087
/* We allocate any XID arrays needed in the same palloc block. */
20842088
size = sizeof(SnapshotData)
2085-
+ serialized_snapshot->xcnt * sizeof(TransactionId)
2086-
+ serialized_snapshot->subxcnt * sizeof(TransactionId);
2089+
+ serialized_snapshot.xcnt * sizeof(TransactionId)
2090+
+ serialized_snapshot.subxcnt * sizeof(TransactionId);
20872091

20882092
/* Copy all required fields */
20892093
snapshot = (Snapshot) MemoryContextAlloc(TopTransactionContext, size);
20902094
snapshot->satisfies = HeapTupleSatisfiesMVCC;
2091-
snapshot->xmin = serialized_snapshot->xmin;
2092-
snapshot->xmax = serialized_snapshot->xmax;
2095+
snapshot->xmin = serialized_snapshot.xmin;
2096+
snapshot->xmax = serialized_snapshot.xmax;
20932097
snapshot->xip = NULL;
2094-
snapshot->xcnt = serialized_snapshot->xcnt;
2098+
snapshot->xcnt = serialized_snapshot.xcnt;
20952099
snapshot->subxip = NULL;
2096-
snapshot->subxcnt = serialized_snapshot->subxcnt;
2097-
snapshot->suboverflowed = serialized_snapshot->suboverflowed;
2098-
snapshot->takenDuringRecovery = serialized_snapshot->takenDuringRecovery;
2099-
snapshot->curcid = serialized_snapshot->curcid;
2100-
snapshot->whenTaken = serialized_snapshot->whenTaken;
2101-
snapshot->lsn = serialized_snapshot->lsn;
2100+
snapshot->subxcnt = serialized_snapshot.subxcnt;
2101+
snapshot->suboverflowed = serialized_snapshot.suboverflowed;
2102+
snapshot->takenDuringRecovery = serialized_snapshot.takenDuringRecovery;
2103+
snapshot->curcid = serialized_snapshot.curcid;
2104+
snapshot->whenTaken = serialized_snapshot.whenTaken;
2105+
snapshot->lsn = serialized_snapshot.lsn;
21022106

21032107
/* Copy XIDs, if present. */
2104-
if (serialized_snapshot->xcnt > 0)
2108+
if (serialized_snapshot.xcnt > 0)
21052109
{
21062110
snapshot->xip = (TransactionId *) (snapshot + 1);
21072111
memcpy(snapshot->xip, serialized_xids,
2108-
serialized_snapshot->xcnt * sizeof(TransactionId));
2112+
serialized_snapshot.xcnt * sizeof(TransactionId));
21092113
}
21102114

21112115
/* Copy SubXIDs, if present. */
2112-
if (serialized_snapshot->subxcnt > 0)
2116+
if (serialized_snapshot.subxcnt > 0)
21132117
{
21142118
snapshot->subxip = ((TransactionId *) (snapshot + 1)) +
2115-
serialized_snapshot->xcnt;
2116-
memcpy(snapshot->subxip, serialized_xids + serialized_snapshot->xcnt,
2117-
serialized_snapshot->subxcnt * sizeof(TransactionId));
2119+
serialized_snapshot.xcnt;
2120+
memcpy(snapshot->subxip, serialized_xids + serialized_snapshot.xcnt,
2121+
serialized_snapshot.subxcnt * sizeof(TransactionId));
21182122
}
21192123

21202124
/* 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