public inbox for [email protected]
help / color / mirror / Atom feedFrom: Xing Guo <[email protected]>
To: [email protected]
Subject: [PATCH] Use mul_size for allocation products potentially to overflow
Date: Thu, 9 Apr 2026 13:13:59 +0800
Message-ID: <CACpMh+BxvqwPr6DqOGz_gLWWSPX+EgVLiOwMpqg5e71uvszdbA@mail.gmail.com> (raw)
Hi hackers,
I spotted several call sites multiplying runtime variables in palloc
and they can potentially lead
to overflow. I fixed them with mul_size() in backend codes and
pg_mul_size_overflow() in frontend codes.
Best Regards,
Xing
Attachments:
[application/octet-stream] 0001-Use-mul_size-for-allocation-products-potentially-to-.patch (4.6K, 2-0001-Use-mul_size-for-allocation-products-potentially-to-.patch)
download | inline diff:
From e58cc264e32bfcf968847e3eec68d07fcc170390 Mon Sep 17 00:00:00 2001
From: Xing Guo <[email protected]>
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 <zlib.h>
#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)
reply
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: [email protected]
Cc: [email protected], [email protected]
Subject: Re: [PATCH] Use mul_size for allocation products potentially to overflow
In-Reply-To: <CACpMh+BxvqwPr6DqOGz_gLWWSPX+EgVLiOwMpqg5e71uvszdbA@mail.gmail.com>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox