]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix bogus use of "long" in AllocSetCheck()
authorDavid Rowley <drowley@postgresql.org>
Thu, 30 Oct 2025 01:49:42 +0000 (14:49 +1300)
committerDavid Rowley <drowley@postgresql.org>
Thu, 30 Oct 2025 01:49:42 +0000 (14:49 +1300)
Because long is 32-bit on 64-bit Windows, it isn't a good datatype to
store the difference between 2 pointers.  The under-sized type could
overflow and lead to scary warnings in MEMORY_CONTEXT_CHECKING builds,
such as:

WARNING:  problem in alloc set ExecutorState: bad single-chunk %p in block %p

However, the problem lies only in the code running the check, not from
an actual memory accounting bug.

Fix by using "Size" instead of "long".  This means using an unsigned
type rather than the previous signed type.  If the block's freeptr was
corrupted, we'd still catch that if the unsigned type wrapped.  Unsigned
allows us to avoid further needless complexities around comparing signed
and unsigned types.

Author: David Rowley <dgrowleyml@gmail.com>
Reviewed-by: Michael Paquier <michael@paquier.xyz>
Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us>
Backpatch-through: 13
Discussion: https://postgr.es/m/CAApHDvo-RmiT4s33J=aC9C_-wPZjOXQ232V-EZFgKftSsNRi4w@mail.gmail.com

src/backend/utils/mmgr/aset.c

index dede30dd86a94739ea38446977c987e0cb3c7f37..c86f83e1dacc16a5f6bb7f3df9e6fd0c0bccc49d 100644 (file)
@@ -1609,9 +1609,9 @@ AllocSetCheck(MemoryContext context)
                 prevblock = block, block = block->next)
        {
                char       *bpoz = ((char *) block) + ALLOC_BLOCKHDRSZ;
-               long            blk_used = block->freeptr - bpoz;
-               long            blk_data = 0;
-               long            nchunks = 0;
+               Size            blk_used = block->freeptr - bpoz;
+               Size            blk_data = 0;
+               Size            nchunks = 0;
                bool            has_external_chunk = false;
 
                if (IsKeeperBlock(set, block))