Skip to content

Commit b296e55

Browse files
committed
Avoid integer overflow while testing wal_skip_threshold condition.
smgrDoPendingSyncs had two distinct risks of integer overflow while deciding which way to ensure durability of a newly-created relation. First, it accumulated the total size of all forks in a variable of type BlockNumber (uint32). While we restrict an individual fork's size to fit in that, I don't believe there's such a restriction on all of them added together. Second, it proceeded to multiply the sum by BLCKSZ, which most certainly could overflow a uint32. (The exact expression is total_blocks * BLCKSZ / 1024. The compiler might choose to optimize that to total_blocks * 8, which is not at quite as much risk of overflow as a literal reading would be, but it's still wrong.) If an overflow did occur it could lead to a poor choice to shove a very large relation into WAL instead of fsync'ing it. This wouldn't be fatal, but it could be inefficient. Change total_blocks to uint64 which should be plenty, and rearrange the comparison calculation to be overflow-safe. I noticed this while looking for ramifications of the proposed change in MAX_KILOBYTES. It's not entirely clear to me why wal_skip_threshold is limited to MAX_KILOBYTES in the first place, but in any case this code is unsafe regardless of the range of wal_skip_threshold. Oversight in c6b9204 which introduced wal_skip_threshold, so back-patch to v13. Discussion: https://postgr.es/m/1a01f0-66ec2d80-3b-68487680@27595217 Backpatch-through: 13
1 parent bb85d09 commit b296e55

File tree

1 file changed

+2
-2
lines changed

1 file changed

+2
-2
lines changed

src/backend/catalog/storage.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
780780
{
781781
ForkNumber fork;
782782
BlockNumber nblocks[MAX_FORKNUM + 1];
783-
BlockNumber total_blocks = 0;
783+
uint64 total_blocks = 0;
784784
SMgrRelation srel;
785785

786786
srel = smgropen(pendingsync->rnode, InvalidBackendId);
@@ -824,7 +824,7 @@ smgrDoPendingSyncs(bool isCommit, bool isParallelWorker)
824824
* main fork is longer than ever but FSM fork gets shorter.
825825
*/
826826
if (pendingsync->is_truncated ||
827-
total_blocks * BLCKSZ / 1024 >= wal_skip_threshold)
827+
total_blocks >= wal_skip_threshold * (uint64) 1024 / BLCKSZ)
828828
{
829829
/* allocate the initial array, or extend it, if needed */
830830
if (maxrels == 0)

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