From e58cc264e32bfcf968847e3eec68d07fcc170390 Mon Sep 17 00:00:00 2001 From: Xing Guo Date: Thu, 9 Apr 2026 11:00:54 +0800 Subject: [PATCH] Use mul_size for allocation products potentially to overflow Several call sites multiplied runtime factors before palloc; use mul_size() in the backend and pg_mul_size_overflow() in the frontend gzip allocator. --- src/backend/backup/basebackup_gzip.c | 3 ++- src/backend/catalog/namespace.c | 3 ++- src/backend/storage/buffer/bufmgr.c | 4 +++- src/backend/utils/adt/tsgistidx.c | 7 ++++--- src/fe_utils/astreamer_gzip.c | 8 +++++++- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/backend/backup/basebackup_gzip.c b/src/backend/backup/basebackup_gzip.c index c5e4c4143e8..1ec2c13ea7f 100644 --- a/src/backend/backup/basebackup_gzip.c +++ b/src/backend/backup/basebackup_gzip.c @@ -17,6 +17,7 @@ #endif #include "backup/basebackup_sink.h" +#include "storage/shmem.h" #ifdef HAVE_LIBZ typedef struct bbsink_gzip @@ -297,7 +298,7 @@ bbsink_gzip_manifest_contents(bbsink *sink, size_t len) static void * gzip_palloc(void *opaque, unsigned items, unsigned size) { - return palloc(items * size); + return palloc(mul_size(size, items)); } /* diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 56b87d878e8..d251cd302ff 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -48,6 +48,7 @@ #include "nodes/makefuncs.h" #include "storage/ipc.h" #include "storage/lmgr.h" +#include "storage/shmem.h" #include "storage/proc.h" #include "storage/procarray.h" #include "utils/acl.h" @@ -1994,7 +1995,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok, 2 * sizeof(Oid)) if (catlist->n_members > 0) - resultSpace = palloc(catlist->n_members * SPACE_PER_OP); + resultSpace = palloc(mul_size(SPACE_PER_OP, catlist->n_members)); for (i = 0; i < catlist->n_members; i++) { diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 3cc0b0bdd92..b738c053830 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -62,6 +62,7 @@ #include "storage/proclist.h" #include "storage/procsignal.h" #include "storage/read_stream.h" +#include "storage/shmem.h" #include "storage/smgr.h" #include "storage/standby.h" #include "utils/memdebug.h" @@ -4925,7 +4926,8 @@ DropRelationsAllBuffers(SMgrRelation *smgr_reln, int nlocators) * forks. */ block = (BlockNumber (*)[MAX_FORKNUM + 1]) - palloc(sizeof(BlockNumber) * n * (MAX_FORKNUM + 1)); + palloc(mul_size(mul_size(sizeof(BlockNumber), (MAX_FORKNUM + 1)), + n)); /* * We can avoid scanning the entire buffer pool if we know the exact size diff --git a/src/backend/utils/adt/tsgistidx.c b/src/backend/utils/adt/tsgistidx.c index e35a25797a0..38a80ad72d2 100644 --- a/src/backend/utils/adt/tsgistidx.c +++ b/src/backend/utils/adt/tsgistidx.c @@ -18,6 +18,7 @@ #include "access/heaptoast.h" #include "access/reloptions.h" #include "common/int.h" +#include "storage/shmem.h" #include "lib/qunique.h" #include "port/pg_bitutils.h" #include "tsearch/ts_utils.h" @@ -625,7 +626,7 @@ gtsvector_picksplit(PG_FUNCTION_ARGS) size_beta; int32 size_waste, waste = -1; - int32 nbytes; + Size nbytes; OffsetNumber seed_1 = 0, seed_2 = 0; OffsetNumber *left, @@ -638,12 +639,12 @@ gtsvector_picksplit(PG_FUNCTION_ARGS) SPLITCOST *costvector; maxoff = entryvec->n - 2; - nbytes = (maxoff + 2) * sizeof(OffsetNumber); + nbytes = mul_size(sizeof(OffsetNumber), (maxoff + 2)); v->spl_left = (OffsetNumber *) palloc(nbytes); v->spl_right = (OffsetNumber *) palloc(nbytes); cache = palloc_array(CACHESIGN, maxoff + 2); - cache_sign = palloc(siglen * (maxoff + 2)); + cache_sign = palloc(mul_size(siglen, (maxoff + 2))); for (j = 0; j < maxoff + 2; j++) cache[j].sign = &cache_sign[siglen * j]; diff --git a/src/fe_utils/astreamer_gzip.c b/src/fe_utils/astreamer_gzip.c index bc3d53076e1..ffc41a75219 100644 --- a/src/fe_utils/astreamer_gzip.c +++ b/src/fe_utils/astreamer_gzip.c @@ -32,6 +32,7 @@ #include #endif +#include "common/int.h" #include "common/logging.h" #include "fe_utils/astreamer.h" @@ -382,7 +383,12 @@ astreamer_gzip_decompressor_free(astreamer *streamer) static void * gzip_palloc(void *opaque, unsigned items, unsigned size) { - return palloc(items * size); + size_t nbytes; + + if (pg_mul_size_overflow((size_t) size, (size_t) items, &nbytes)) + pg_fatal("gzip library requested invalid allocation size"); + + return palloc(nbytes); } /* -- 2.50.1 (Apple Git-155)