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